@flamingo-stack/openframe-frontend-core 0.0.671 → 0.0.672-snapshot.20260928032919

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.
Files changed (178) hide show
  1. package/dist/chat-protocol/card-marker.d.ts +12 -0
  2. package/dist/chat-protocol/card-marker.d.ts.map +1 -1
  3. package/dist/chat-protocol/index.cjs +17 -0
  4. package/dist/chat-protocol/index.cjs.map +1 -1
  5. package/dist/chat-protocol/index.d.ts +1 -0
  6. package/dist/chat-protocol/index.d.ts.map +1 -1
  7. package/dist/chat-protocol/index.js +15 -1
  8. package/dist/chat-protocol/index.js.map +1 -1
  9. package/dist/{chunk-4PVY4JJN.js → chunk-2TQ64TG3.js} +3 -3
  10. package/dist/{chunk-FAJUQKWQ.cjs → chunk-3EIB5PNM.cjs} +76 -75
  11. package/dist/chunk-3EIB5PNM.cjs.map +1 -0
  12. package/dist/{chunk-FUXUJSPP.cjs → chunk-3UDBK2YG.cjs} +1 -1
  13. package/dist/chunk-3UDBK2YG.cjs.map +1 -0
  14. package/dist/{chunk-G64BNLDO.js → chunk-3X6WFYSV.js} +2 -2
  15. package/dist/{chunk-DUZEFACP.js → chunk-4UAIOXYC.js} +3 -3
  16. package/dist/{chunk-SNNE34OP.js → chunk-5KD5SSP6.js} +5 -5
  17. package/dist/{chunk-RKUCK6MN.js → chunk-6NGIPAQ6.js} +2 -2
  18. package/dist/{chunk-OG2BNJ2Q.cjs → chunk-6PPEG2N4.cjs} +389 -375
  19. package/dist/chunk-6PPEG2N4.cjs.map +1 -0
  20. package/dist/{chunk-NIYIK32F.js → chunk-6ZX6TFSS.js} +18 -4
  21. package/dist/{chunk-NIYIK32F.js.map → chunk-6ZX6TFSS.js.map} +1 -1
  22. package/dist/{chunk-6C6UUOH4.js → chunk-A77HP3N6.js} +8 -7
  23. package/dist/{chunk-6C6UUOH4.js.map → chunk-A77HP3N6.js.map} +1 -1
  24. package/dist/{chunk-YNGAJGYB.cjs → chunk-AXMNWMAU.cjs} +340 -6
  25. package/dist/chunk-AXMNWMAU.cjs.map +1 -0
  26. package/dist/{chunk-PLG6LP7E.cjs → chunk-BAEHCDPI.cjs} +49 -49
  27. package/dist/{chunk-PLG6LP7E.cjs.map → chunk-BAEHCDPI.cjs.map} +1 -1
  28. package/dist/{chunk-R22IA7MP.js → chunk-BBDEIE56.js} +4 -4
  29. package/dist/{chunk-PQ7YC5Y6.js → chunk-D5HO3RNF.js} +3 -3
  30. package/dist/{chunk-II66XWU5.cjs → chunk-D6IOMPAH.cjs} +3 -3
  31. package/dist/{chunk-II66XWU5.cjs.map → chunk-D6IOMPAH.cjs.map} +1 -1
  32. package/dist/{chunk-DAGKBFZN.cjs → chunk-EQIBWG5U.cjs} +33 -33
  33. package/dist/{chunk-DAGKBFZN.cjs.map → chunk-EQIBWG5U.cjs.map} +1 -1
  34. package/dist/{chunk-3PVOF3IB.js → chunk-EVB3EO5S.js} +337 -3
  35. package/dist/{chunk-3PVOF3IB.js.map → chunk-EVB3EO5S.js.map} +1 -1
  36. package/dist/{chunk-SJZPKIW6.cjs → chunk-G64BDYU5.cjs} +12 -12
  37. package/dist/{chunk-SJZPKIW6.cjs.map → chunk-G64BDYU5.cjs.map} +1 -1
  38. package/dist/{chunk-BP542DGQ.cjs → chunk-GLPGYU6H.cjs} +55 -28
  39. package/dist/chunk-GLPGYU6H.cjs.map +1 -0
  40. package/dist/{chunk-TLLTL6LB.js → chunk-JD4U7QMG.js} +1 -1
  41. package/dist/chunk-JD4U7QMG.js.map +1 -0
  42. package/dist/{chunk-ZRIVCLPR.js → chunk-JD5TKRCU.js} +1 -1
  43. package/dist/chunk-JD5TKRCU.js.map +1 -0
  44. package/dist/{chunk-YJWR7D6O.cjs → chunk-JKIM7U7N.cjs} +3 -3
  45. package/dist/{chunk-YJWR7D6O.cjs.map → chunk-JKIM7U7N.cjs.map} +1 -1
  46. package/dist/{chunk-K3O4D7LW.js → chunk-KUASHD7Z.js} +4 -4
  47. package/dist/{chunk-GF5TSQ6C.cjs → chunk-KXL534EV.cjs} +10 -10
  48. package/dist/{chunk-GF5TSQ6C.cjs.map → chunk-KXL534EV.cjs.map} +1 -1
  49. package/dist/{chunk-FHTNCWIP.js → chunk-KYVFU7VQ.js} +5 -5
  50. package/dist/{chunk-OYMOG544.js → chunk-KZAT6VWE.js} +5 -5
  51. package/dist/{chunk-D55IENZJ.cjs → chunk-LCMT2GZK.cjs} +1 -1
  52. package/dist/chunk-LCMT2GZK.cjs.map +1 -0
  53. package/dist/{chunk-IJIIL6WU.js → chunk-MVU7HF5A.js} +6 -6
  54. package/dist/{chunk-XGXHHSDU.cjs → chunk-NYDFVUMH.cjs} +22 -22
  55. package/dist/{chunk-XGXHHSDU.cjs.map → chunk-NYDFVUMH.cjs.map} +1 -1
  56. package/dist/{chunk-STLBB6PF.js → chunk-O75Y5O3U.js} +35 -8
  57. package/dist/chunk-O75Y5O3U.js.map +1 -0
  58. package/dist/{chunk-DAWYS25M.cjs → chunk-PDNGWDJF.cjs} +17 -17
  59. package/dist/{chunk-DAWYS25M.cjs.map → chunk-PDNGWDJF.cjs.map} +1 -1
  60. package/dist/{chunk-T3ACDOVD.cjs → chunk-VRZZCL4R.cjs} +7 -7
  61. package/dist/{chunk-T3ACDOVD.cjs.map → chunk-VRZZCL4R.cjs.map} +1 -1
  62. package/dist/{chunk-XH4MRTZM.cjs → chunk-WQFT7GOC.cjs} +5 -5
  63. package/dist/{chunk-XH4MRTZM.cjs.map → chunk-WQFT7GOC.cjs.map} +1 -1
  64. package/dist/{chunk-YIDNSRPL.cjs → chunk-XGBFQ3YV.cjs} +31 -31
  65. package/dist/{chunk-YIDNSRPL.cjs.map → chunk-XGBFQ3YV.cjs.map} +1 -1
  66. package/dist/{chunk-UH3BL2OT.js → chunk-Y7TZHPS2.js} +2 -2
  67. package/dist/{chunk-EIAVE6SE.cjs → chunk-YKKW67A3.cjs} +10 -10
  68. package/dist/{chunk-EIAVE6SE.cjs.map → chunk-YKKW67A3.cjs.map} +1 -1
  69. package/dist/components/case-studies/index.cjs +18 -17
  70. package/dist/components/case-studies/index.cjs.map +1 -1
  71. package/dist/components/case-studies/index.js +7 -6
  72. package/dist/components/case-studies/index.js.map +1 -1
  73. package/dist/components/case-studies/share-experience-section.d.ts.map +1 -1
  74. package/dist/components/chat/index.cjs +2 -2
  75. package/dist/components/chat/index.js +1 -1
  76. package/dist/components/contact/contact-form.d.ts +6 -1
  77. package/dist/components/contact/contact-form.d.ts.map +1 -1
  78. package/dist/components/contact/index.cjs +6 -6
  79. package/dist/components/contact/index.js +5 -5
  80. package/dist/components/docs/index.cjs +9 -9
  81. package/dist/components/docs/index.js +8 -8
  82. package/dist/components/embeds/index.cjs +6 -6
  83. package/dist/components/embeds/index.js +5 -5
  84. package/dist/components/faq/index.cjs +6 -6
  85. package/dist/components/faq/index.js +5 -5
  86. package/dist/components/features/index.cjs +5 -5
  87. package/dist/components/features/index.js +4 -4
  88. package/dist/components/features/waitlist-form.d.ts +3 -1
  89. package/dist/components/features/waitlist-form.d.ts.map +1 -1
  90. package/dist/components/help-center-pages/index.cjs +77 -76
  91. package/dist/components/help-center-pages/index.cjs.map +1 -1
  92. package/dist/components/help-center-pages/index.js +17 -16
  93. package/dist/components/help-center-pages/index.js.map +1 -1
  94. package/dist/components/help-center-pages/trust-center-sections.d.ts.map +1 -1
  95. package/dist/components/index.cjs +43 -43
  96. package/dist/components/index.js +15 -15
  97. package/dist/components/meeting-scheduler/booking-form.d.ts +4 -1
  98. package/dist/components/meeting-scheduler/booking-form.d.ts.map +1 -1
  99. package/dist/components/meeting-scheduler/index.cjs +73 -39
  100. package/dist/components/meeting-scheduler/index.cjs.map +1 -1
  101. package/dist/components/meeting-scheduler/index.d.ts.map +1 -1
  102. package/dist/components/meeting-scheduler/index.js +44 -10
  103. package/dist/components/meeting-scheduler/index.js.map +1 -1
  104. package/dist/components/navigation/index.cjs +8 -8
  105. package/dist/components/navigation/index.js +7 -7
  106. package/dist/components/onboarding-guides/index.cjs +8 -8
  107. package/dist/components/onboarding-guides/index.js +7 -7
  108. package/dist/components/tickets/help-center-create-form.d.ts.map +1 -1
  109. package/dist/components/tickets/index.cjs +9 -9
  110. package/dist/components/tickets/index.js +8 -8
  111. package/dist/components/ui/index.cjs +5 -5
  112. package/dist/components/ui/index.js +4 -4
  113. package/dist/contexts/endpoints-runtime-context.d.ts +5 -0
  114. package/dist/contexts/endpoints-runtime-context.d.ts.map +1 -1
  115. package/dist/contexts/index.cjs +2 -2
  116. package/dist/contexts/index.js +1 -1
  117. package/dist/hooks/index.cjs +5 -3
  118. package/dist/hooks/index.cjs.map +1 -1
  119. package/dist/hooks/index.d.ts +1 -0
  120. package/dist/hooks/index.d.ts.map +1 -1
  121. package/dist/hooks/index.js +4 -2
  122. package/dist/hooks/use-form-rescue.d.ts +37 -0
  123. package/dist/hooks/use-form-rescue.d.ts.map +1 -0
  124. package/dist/index.cjs +51 -9
  125. package/dist/index.cjs.map +1 -1
  126. package/dist/index.js +50 -8
  127. package/dist/index.js.map +1 -1
  128. package/dist/utils/form-rescue.cjs +117 -0
  129. package/dist/utils/form-rescue.cjs.map +1 -0
  130. package/dist/utils/form-rescue.d.ts +98 -0
  131. package/dist/utils/form-rescue.d.ts.map +1 -0
  132. package/dist/utils/form-rescue.js +96 -0
  133. package/dist/utils/form-rescue.js.map +1 -0
  134. package/dist/utils/index.cjs +113 -0
  135. package/dist/utils/index.cjs.map +1 -1
  136. package/dist/utils/index.d.ts +1 -0
  137. package/dist/utils/index.d.ts.map +1 -1
  138. package/dist/utils/index.js +94 -1
  139. package/dist/utils/index.js.map +1 -1
  140. package/package.json +7 -1
  141. package/src/chat-protocol/__tests__/card-marker.test.ts +27 -1
  142. package/src/chat-protocol/card-marker.ts +24 -0
  143. package/src/chat-protocol/index.ts +3 -0
  144. package/src/components/case-studies/share-experience-section.tsx +1 -0
  145. package/src/components/contact/contact-form.tsx +38 -2
  146. package/src/components/features/waitlist-form.tsx +23 -2
  147. package/src/components/help-center-pages/trust-center-sections.tsx +1 -0
  148. package/src/components/meeting-scheduler/booking-form.tsx +14 -0
  149. package/src/components/meeting-scheduler/index.tsx +33 -3
  150. package/src/components/tickets/help-center-create-form.tsx +2 -0
  151. package/src/contexts/endpoints-runtime-context.tsx +5 -0
  152. package/src/hooks/__tests__/use-form-rescue.test.tsx +182 -0
  153. package/src/hooks/index.ts +3 -0
  154. package/src/hooks/use-form-rescue.ts +315 -0
  155. package/src/utils/__tests__/form-rescue.test.ts +106 -0
  156. package/src/utils/form-rescue.ts +190 -0
  157. package/src/utils/index.ts +5 -0
  158. package/dist/chunk-BP542DGQ.cjs.map +0 -1
  159. package/dist/chunk-D55IENZJ.cjs.map +0 -1
  160. package/dist/chunk-FAJUQKWQ.cjs.map +0 -1
  161. package/dist/chunk-FUXUJSPP.cjs.map +0 -1
  162. package/dist/chunk-OG2BNJ2Q.cjs.map +0 -1
  163. package/dist/chunk-STLBB6PF.js.map +0 -1
  164. package/dist/chunk-TLLTL6LB.js.map +0 -1
  165. package/dist/chunk-YNGAJGYB.cjs.map +0 -1
  166. package/dist/chunk-ZRIVCLPR.js.map +0 -1
  167. /package/dist/{chunk-4PVY4JJN.js.map → chunk-2TQ64TG3.js.map} +0 -0
  168. /package/dist/{chunk-G64BNLDO.js.map → chunk-3X6WFYSV.js.map} +0 -0
  169. /package/dist/{chunk-DUZEFACP.js.map → chunk-4UAIOXYC.js.map} +0 -0
  170. /package/dist/{chunk-SNNE34OP.js.map → chunk-5KD5SSP6.js.map} +0 -0
  171. /package/dist/{chunk-RKUCK6MN.js.map → chunk-6NGIPAQ6.js.map} +0 -0
  172. /package/dist/{chunk-R22IA7MP.js.map → chunk-BBDEIE56.js.map} +0 -0
  173. /package/dist/{chunk-PQ7YC5Y6.js.map → chunk-D5HO3RNF.js.map} +0 -0
  174. /package/dist/{chunk-K3O4D7LW.js.map → chunk-KUASHD7Z.js.map} +0 -0
  175. /package/dist/{chunk-FHTNCWIP.js.map → chunk-KYVFU7VQ.js.map} +0 -0
  176. /package/dist/{chunk-OYMOG544.js.map → chunk-KZAT6VWE.js.map} +0 -0
  177. /package/dist/{chunk-IJIIL6WU.js.map → chunk-MVU7HF5A.js.map} +0 -0
  178. /package/dist/{chunk-UH3BL2OT.js.map → chunk-Y7TZHPS2.js.map} +0 -0
@@ -4,16 +4,16 @@ import {
4
4
  getOSLabel,
5
5
  getShellLabel,
6
6
  getToolLabel
7
- } from "./chunk-NIYIK32F.js";
7
+ } from "./chunk-6ZX6TFSS.js";
8
8
  import {
9
9
  useOnboardingState
10
- } from "./chunk-3PVOF3IB.js";
10
+ } from "./chunk-EVB3EO5S.js";
11
11
  import {
12
12
  Input
13
13
  } from "./chunk-BXWXBBAC.js";
14
14
  import {
15
15
  SECTION_HEADING_CLASS
16
- } from "./chunk-TLLTL6LB.js";
16
+ } from "./chunk-JD4U7QMG.js";
17
17
  import {
18
18
  ToolIcon,
19
19
  cn as cn2
@@ -558,4 +558,4 @@ export {
558
558
  OnboardingStepCard,
559
559
  OnboardingWalkthrough
560
560
  };
561
- //# sourceMappingURL=chunk-R22IA7MP.js.map
561
+ //# sourceMappingURL=chunk-BBDEIE56.js.map
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  SearchInput
4
- } from "./chunk-NIYIK32F.js";
4
+ } from "./chunk-6ZX6TFSS.js";
5
5
  import {
6
6
  contentFetch
7
7
  } from "./chunk-MT5A25AX.js";
@@ -12,7 +12,7 @@ import {
12
12
  resolveExternalNavigation,
13
13
  resolveSourceIcon,
14
14
  stripSameOriginToPath
15
- } from "./chunk-TLLTL6LB.js";
15
+ } from "./chunk-JD4U7QMG.js";
16
16
  import {
17
17
  useDebounce
18
18
  } from "./chunk-3T4GPKSB.js";
@@ -370,4 +370,4 @@ export {
370
370
  resolveSearchResultAction,
371
371
  useDocSearch
372
372
  };
373
- //# sourceMappingURL=chunk-PQ7YC5Y6.js.map
373
+ //# sourceMappingURL=chunk-D5HO3RNF.js.map
@@ -1,7 +1,7 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
2
2
 
3
3
 
4
- var _chunkOG2BNJ2Qcjs = require('./chunk-OG2BNJ2Q.cjs');
4
+ var _chunk6PPEG2N4cjs = require('./chunk-6PPEG2N4.cjs');
5
5
 
6
6
 
7
7
  var _chunkV2A4MAALcjs = require('./chunk-V2A4MAAL.cjs');
@@ -129,7 +129,7 @@ function useSectionNavigation(sections, options) {
129
129
  // src/components/navigation/multi-level-navigation.tsx
130
130
  var _lucidereact = require('lucide-react');
131
131
 
132
- var DEFAULT_FOLDER_INDEX_FILE2 = _chunkOG2BNJ2Qcjs.DEFAULT_FOLDER_INDEX_FILE;
132
+ var DEFAULT_FOLDER_INDEX_FILE2 = _chunk6PPEG2N4cjs.DEFAULT_FOLDER_INDEX_FILE;
133
133
  function isNodeVisuallySelected(node, selectedPath, folderIndexFile = DEFAULT_FOLDER_INDEX_FILE2) {
134
134
  const FOLDER_INDEX_FILE = folderIndexFile.toLowerCase();
135
135
  if (selectedPath === node.path) {
@@ -357,4 +357,4 @@ function MobileNavigationItem({
357
357
 
358
358
 
359
359
  exports.StickySectionNav = StickySectionNav; exports.useSectionNavigation = useSectionNavigation; exports.MultiLevelNavigation = MultiLevelNavigation; exports.MobileNavigationDropdown = MobileNavigationDropdown;
360
- //# sourceMappingURL=chunk-II66XWU5.cjs.map
360
+ //# sourceMappingURL=chunk-D6IOMPAH.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-II66XWU5.cjs","../src/components/navigation/sticky-section-nav.tsx","../src/components/navigation/multi-level-navigation.tsx"],"names":["jsx","DEFAULT_FOLDER_INDEX_FILE"],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-II66XWU5.cjs","sourcesContent":[null,"'use client';\n\nimport type React from 'react';\nimport { useEffect, useState, useCallback, useRef } from 'react';\nimport { cn } from '../../utils';\nimport { scrollElementIntoView } from '../../utils/scroll-into-view';\n\nexport interface StickyNavSection {\n id: string;\n label: string;\n}\n\ninterface StickySectionNavProps {\n sections: StickyNavSection[];\n activeSection: string;\n onSectionClick: (sectionId: string) => void;\n className?: string;\n ribbonPosition?: 'left' | 'right';\n ribbonColor?: string;\n}\n\n/**\n * Reusable sticky navigation component for section-based navigation\n * Used in vendor detail pages, knowledge base, documentation, etc.\n */\nexport function StickySectionNav({\n sections,\n activeSection,\n onSectionClick,\n className,\n ribbonPosition = 'left',\n ribbonColor = 'var(--color-accent-primary)',\n}: StickySectionNavProps) {\n const navHeight = sections.length * 40; // 40px per item (h-10)\n\n return (\n <nav className={cn('relative bg-ods-bg', className)}>\n {/* Background gray vertical line for all nav items */}\n <div\n className=\"absolute bg-ods-border\"\n style={{\n width: '1px',\n height: `${navHeight}px`,\n [ribbonPosition === 'left' ? 'left' : 'right']: '-2px',\n top: '0px',\n }}\n />\n\n {sections.map(section => (\n <div key={section.id} className=\"relative flex h-10 w-full items-stretch transition-all duration-200\">\n {/* Yellow ribbon for active state */}\n {activeSection === section.id && (\n <div\n className=\"absolute z-10 transition-all duration-200\"\n style={{\n backgroundColor: ribbonColor,\n width: '4px',\n height: '24px',\n [ribbonPosition === 'left' ? 'left' : 'right']: '-2px',\n top: '8px',\n borderRadius: '2px',\n }}\n />\n )}\n\n {/* Navigation button */}\n <button\n onClick={() => onSectionClick(section.id)}\n className=\"relative flex flex-1 cursor-pointer items-center gap-2 px-3 py-2\"\n >\n <span\n className={cn(\n 'text-left transition-all duration-200 text-h6',\n activeSection === section.id\n ? 'text-ods-text-primary'\n : 'text-ods-text-secondary hover:text-ods-text-primary',\n )}\n >\n {section.label}\n </span>\n </button>\n </div>\n ))}\n </nav>\n );\n}\n\n/**\n * SIMPLEST POSSIBLE IMPLEMENTATION - Just make it work\n */\nexport function useSectionNavigation(\n sections: { id: string; ref: React.RefObject<HTMLElement> }[],\n options?: {\n offset?: number;\n },\n) {\n const [activeSection, setActiveSection] = useState(sections[0]?.id || '');\n const isScrollingFromClick = useRef(false);\n const { offset = 100 } = options || {};\n\n // Handle click - scroll to the element via the canonical helper.\n // The `offset` prop maps to `headerOffset` (sticky chrome above the\n // section nav); same smooth-scroll mechanics every other anchor\n // surface in the app uses.\n const handleSectionClick = useCallback(\n (sectionId: string) => {\n const targetElement = document.getElementById(sectionId);\n if (!targetElement) return;\n\n // Prevent scroll spy while we're scrolling\n isScrollingFromClick.current = true;\n setActiveSection(sectionId);\n\n scrollElementIntoView(targetElement, { headerOffset: offset });\n\n // Allow scroll spy again after scroll completes\n setTimeout(() => {\n isScrollingFromClick.current = false;\n }, 500);\n },\n [offset],\n );\n\n // Make sure elements have IDs\n useEffect(() => {\n sections.forEach(section => {\n const el = section.ref.current;\n if (el && !el.id) {\n el.id = section.id;\n }\n });\n }, [sections]);\n\n // Simple scroll spy\n useEffect(() => {\n const handleScroll = () => {\n if (isScrollingFromClick.current) return;\n\n const scrollPosition = window.scrollY + offset + 50;\n\n // Find which section we're in\n let currentSection = sections[0]?.id || '';\n\n for (let i = sections.length - 1; i >= 0; i--) {\n const element = document.getElementById(sections[i].id);\n if (element && scrollPosition >= element.offsetTop) {\n currentSection = sections[i].id;\n break;\n }\n }\n\n setActiveSection(currentSection);\n };\n\n // Throttle the scroll handler\n let scrollTimer: NodeJS.Timeout;\n const throttledScroll = () => {\n clearTimeout(scrollTimer);\n scrollTimer = setTimeout(handleScroll, 100);\n };\n\n window.addEventListener('scroll', throttledScroll);\n handleScroll(); // Check initial position\n\n return () => {\n window.removeEventListener('scroll', throttledScroll);\n clearTimeout(scrollTimer);\n };\n }, [sections, offset]);\n\n return {\n activeSection,\n handleSectionClick,\n };\n}\n","'use client';\n\nimport { ChevronDown, ChevronUp, FileText, Folder, FolderOpen } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { DEFAULT_FOLDER_INDEX_FILE as CANONICAL_FOLDER_INDEX_FILE } from '../../utils/doc-tree-nav';\n\nexport interface NavigationNode {\n id: string;\n name: string;\n path: string;\n type: 'file' | 'folder';\n hasReadme?: boolean;\n children?: NavigationNode[];\n slug?: string;\n // Mirror DocNode's extra optional fields so a DocNode tree is structurally\n // assignable to NavigationNode[] without an `as` cast. NavigationNode\n // intentionally never reads these — they're carried for type-compat only.\n documentType?: 'markdown' | 'pdf' | 'google_sheet' | 'figma' | 'file';\n sortOrder?: number;\n}\n\ninterface MultiLevelNavigationProps {\n nodes: NavigationNode[];\n selectedPath: string;\n expandedNodes: Set<string>;\n onNodeClick: (node: NavigationNode) => void;\n onToggleExpand?: (nodeId: string) => void;\n isLoading?: boolean;\n className?: string;\n /** Folder-index filename (default `'README.md'`, case-insensitive). When the\n * selectedPath is a folder with this file, the visual ribbon moves to the\n * child file. */\n folderIndexFile?: string;\n}\n\n// SSOT lives in `doc-tree-nav` (canonical case `'README.md'`). The visual\n// comparator below lowercases both sides, so re-exporting the canonical\n// constant under the same local name preserves call-site syntax without\n// drifting from the SSOT.\nconst DEFAULT_FOLDER_INDEX_FILE = CANONICAL_FOLDER_INDEX_FILE;\n\n/**\n * Compute the visual \"selected\" state for a navigation node.\n *\n * Folder-with-README convention: when `selectedPath` is a folder that has a\n * README, the FOLDER doesn't get the ribbon — its README child does. The folder\n * is just a container; the README is the actual document being viewed.\n *\n * Mirror case: a README file whose parent folder is the `selectedPath` gets the\n * visual selection ribbon (implicit). This handles both the auto-select-first-\n * folder landing path AND the user-clicks-folder case.\n */\nfunction isNodeVisuallySelected(\n node: NavigationNode,\n selectedPath: string,\n folderIndexFile: string = DEFAULT_FOLDER_INDEX_FILE,\n): boolean {\n const FOLDER_INDEX_FILE = folderIndexFile.toLowerCase();\n // Path comparisons keyed on `node.path` (raw, includes `.md`). Do NOT use\n // `node.name` — the tree-builder runs it through `formatDocName` which strips\n // the `.md` extension, so `node.name.toLowerCase() === 'readme.md'` is always\n // false.\n if (selectedPath === node.path) {\n // Explicit match — but folder-with-README defers to its README child.\n return !(node.type === 'folder' && node.hasReadme);\n }\n if (node.type !== 'file') return false;\n const pathLower = node.path.toLowerCase();\n // Implicit: README child whose parent folder is the selectedPath.\n if (selectedPath !== '' && pathLower === `${selectedPath.toLowerCase()}/${FOLDER_INDEX_FILE}`) {\n return true;\n }\n // Implicit: ROOT README on the landing page (selectedPath === '' means\n // \"no explicit doc selected\" — the viewer falls back to the root folder-\n // index file, so that file IS the active document).\n if (selectedPath === '' && pathLower === FOLDER_INDEX_FILE) {\n return true;\n }\n return false;\n}\n\nexport function MultiLevelNavigation({\n nodes,\n selectedPath,\n expandedNodes,\n onNodeClick,\n onToggleExpand,\n isLoading,\n className,\n folderIndexFile = DEFAULT_FOLDER_INDEX_FILE,\n}: MultiLevelNavigationProps) {\n if (isLoading) {\n return (\n <div className={cn('space-y-2', className)}>\n {[1, 2, 3, 4].map(i => (\n <div key={i} className=\"h-12 animate-pulse rounded-lg bg-ods-skeleton p-3\" />\n ))}\n </div>\n );\n }\n\n return (\n <div className={cn('space-y-2', className)} role=\"list\" aria-label=\"Navigation list\">\n {nodes.map(node => (\n <NavigationItem\n key={node.id}\n node={node}\n selectedPath={selectedPath}\n expandedNodes={expandedNodes}\n onNodeClick={onNodeClick}\n onToggleExpand={onToggleExpand}\n level={0}\n folderIndexFile={folderIndexFile}\n />\n ))}\n </div>\n );\n}\n\ninterface NavigationItemProps {\n node: NavigationNode;\n selectedPath: string;\n expandedNodes: Set<string>;\n onNodeClick: (node: NavigationNode) => void;\n onToggleExpand?: (nodeId: string) => void;\n level: number;\n folderIndexFile: string;\n}\n\nfunction NavigationItem({\n node,\n selectedPath,\n expandedNodes,\n onNodeClick,\n onToggleExpand,\n level,\n folderIndexFile,\n}: NavigationItemProps) {\n const isExpanded = expandedNodes.has(node.id);\n const isSelected = isNodeVisuallySelected(node, selectedPath, folderIndexFile);\n // Bind the (optional) child list once so the render below maps a real array\n // rather than re-deriving `hasChildren` and asserting it away.\n const children = node.children ?? [];\n const hasChildren = children.length > 0;\n\n return (\n <div className=\"space-y-1\" role=\"listitem\">\n <div className={cn('px-2', level > 0 && 'ml-4')}>\n <div\n className={cn(\n 'relative w-full rounded-lg border transition-all duration-150',\n isSelected ? 'border-ods-border bg-ods-border' : 'border-ods-border bg-ods-card',\n )}\n >\n <div className=\"relative flex items-center\">\n <button\n className={cn(\n 'flex h-12 w-full items-center rounded-lg px-2 text-ods-text-primary transition-all duration-150 text-h6',\n !isSelected && 'hover:bg-ods-bg-hover',\n hasChildren && 'pr-12',\n )}\n onClick={() => onNodeClick(node)}\n aria-label={`${isSelected ? 'Selected' : 'Select'} ${node.name}`}\n >\n <span className=\"mr-2 flex-shrink-0\">\n {node.type === 'folder' ? (\n isExpanded ? (\n <FolderOpen className=\"h-4 w-4\" />\n ) : (\n <Folder className=\"h-4 w-4\" />\n )\n ) : (\n <FileText className=\"h-4 w-4\" />\n )}\n </span>\n <span className=\"min-w-0 flex-1 truncate text-left\">\n {node.name.endsWith('.md') ? node.name.replace('.md', '') : node.name}\n </span>\n {node.type === 'folder' && node.hasReadme && (\n <span className=\"mr-2 rounded bg-ods-bg-surface px-1.5 py-0.5 text-ods-text-secondary text-h6\">\n README\n </span>\n )}\n </button>\n\n {hasChildren && (\n <button\n className=\"absolute right-0 top-0 flex h-12 w-12 items-center justify-center text-ods-text-secondary transition-colors duration-150 hover:text-ods-text-primary\"\n onClick={e => {\n e.stopPropagation();\n if (onToggleExpand) {\n onToggleExpand(node.id);\n } else {\n onNodeClick(node);\n }\n }}\n aria-label={`${isExpanded ? 'Collapse' : 'Expand'} ${node.name}`}\n >\n {isExpanded ? <ChevronUp className=\"h-4 w-4\" /> : <ChevronDown className=\"h-4 w-4\" />}\n </button>\n )}\n </div>\n\n {isSelected && (\n <div className=\"absolute right-0 top-1/2 h-[calc(100%-8px)] w-1 -translate-y-1/2 rounded-l bg-ods-accent\" />\n )}\n </div>\n </div>\n\n {hasChildren && isExpanded && (\n <div className=\"space-y-1\">\n {children.map(child => (\n <NavigationItem\n key={child.id}\n node={child}\n selectedPath={selectedPath}\n expandedNodes={expandedNodes}\n onNodeClick={onNodeClick}\n onToggleExpand={onToggleExpand}\n level={level + 1}\n folderIndexFile={folderIndexFile}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nexport function MobileNavigationDropdown({\n nodes,\n selectedPath,\n expandedNodes,\n onNodeClick,\n onToggleExpand,\n isLoading,\n className,\n folderIndexFile = DEFAULT_FOLDER_INDEX_FILE,\n}: MultiLevelNavigationProps) {\n if (isLoading) {\n return (\n <div className={cn('space-y-2', className)}>\n {[1, 2, 3].map(i => (\n <div key={i} className=\"h-10 animate-pulse rounded-lg bg-ods-skeleton p-3\" />\n ))}\n </div>\n );\n }\n\n return (\n <div className={cn('space-y-2', className)}>\n {nodes.map(node => (\n <MobileNavigationItem\n key={node.id}\n node={node}\n selectedPath={selectedPath}\n expandedNodes={expandedNodes}\n onNodeClick={onNodeClick}\n onToggleExpand={onToggleExpand}\n level={0}\n folderIndexFile={folderIndexFile}\n />\n ))}\n </div>\n );\n}\n\nfunction MobileNavigationItem({\n node,\n selectedPath,\n expandedNodes,\n onNodeClick,\n onToggleExpand,\n level,\n folderIndexFile,\n}: NavigationItemProps) {\n const isExpanded = expandedNodes.has(node.id);\n const isSelected = isNodeVisuallySelected(node, selectedPath, folderIndexFile);\n // Same binding as the desktop item above — a real array to map, no assertion.\n const children = node.children ?? [];\n const hasChildren = children.length > 0;\n\n return (\n <div className=\"space-y-1\">\n <div className={cn('px-2', level > 0 && 'ml-3')}>\n <div\n className={cn(\n 'relative w-full rounded-lg border transition-all duration-150',\n isSelected ? 'border-ods-border bg-ods-border' : 'border-ods-border bg-ods-card',\n )}\n >\n <div className=\"relative flex items-center\">\n <button\n className={cn(\n 'flex h-11 w-full items-center rounded-lg px-2 text-ods-text-primary transition-all duration-150 text-h6',\n !isSelected && 'hover:bg-ods-bg-hover',\n hasChildren && 'pr-11',\n )}\n onClick={() => onNodeClick(node)}\n >\n <span className=\"mr-2 flex-shrink-0\">\n {node.type === 'folder' ? (\n isExpanded ? (\n <FolderOpen className=\"h-4 w-4\" />\n ) : (\n <Folder className=\"h-4 w-4\" />\n )\n ) : (\n <FileText className=\"h-4 w-4\" />\n )}\n </span>\n <span className=\"min-w-0 flex-1 truncate text-left\">\n {node.name.endsWith('.md') ? node.name.replace('.md', '') : node.name}\n </span>\n {node.type === 'folder' && node.hasReadme && (\n <span className=\"mr-2 rounded bg-ods-bg-surface px-1.5 py-0.5 text-ods-text-secondary text-h6\">\n README\n </span>\n )}\n </button>\n\n {hasChildren && (\n <button\n className=\"absolute right-0 top-0 flex h-11 w-11 items-center justify-center text-ods-text-secondary transition-colors duration-150 hover:text-ods-text-primary\"\n onClick={e => {\n e.stopPropagation();\n if (onToggleExpand) {\n onToggleExpand(node.id);\n } else {\n onNodeClick(node);\n }\n }}\n aria-label={`${isExpanded ? 'Collapse' : 'Expand'} ${node.name}`}\n >\n {isExpanded ? <ChevronUp className=\"h-3.5 w-3.5\" /> : <ChevronDown className=\"h-3.5 w-3.5\" />}\n </button>\n )}\n </div>\n\n {isSelected && (\n <div className=\"absolute right-0 top-1/2 h-[calc(100%-8px)] w-1 -translate-y-1/2 rounded-l bg-ods-accent\" />\n )}\n </div>\n </div>\n\n {hasChildren && isExpanded && (\n <div className=\"space-y-1\">\n {children.map(child => (\n <MobileNavigationItem\n key={child.id}\n node={child}\n selectedPath={selectedPath}\n expandedNodes={expandedNodes}\n onNodeClick={onNodeClick}\n onToggleExpand={onToggleExpand}\n level={level + 1}\n folderIndexFile={folderIndexFile}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-D6IOMPAH.cjs","../src/components/navigation/sticky-section-nav.tsx","../src/components/navigation/multi-level-navigation.tsx"],"names":["jsx","DEFAULT_FOLDER_INDEX_FILE"],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-D6IOMPAH.cjs","sourcesContent":[null,"'use client';\n\nimport type React from 'react';\nimport { useEffect, useState, useCallback, useRef } from 'react';\nimport { cn } from '../../utils';\nimport { scrollElementIntoView } from '../../utils/scroll-into-view';\n\nexport interface StickyNavSection {\n id: string;\n label: string;\n}\n\ninterface StickySectionNavProps {\n sections: StickyNavSection[];\n activeSection: string;\n onSectionClick: (sectionId: string) => void;\n className?: string;\n ribbonPosition?: 'left' | 'right';\n ribbonColor?: string;\n}\n\n/**\n * Reusable sticky navigation component for section-based navigation\n * Used in vendor detail pages, knowledge base, documentation, etc.\n */\nexport function StickySectionNav({\n sections,\n activeSection,\n onSectionClick,\n className,\n ribbonPosition = 'left',\n ribbonColor = 'var(--color-accent-primary)',\n}: StickySectionNavProps) {\n const navHeight = sections.length * 40; // 40px per item (h-10)\n\n return (\n <nav className={cn('relative bg-ods-bg', className)}>\n {/* Background gray vertical line for all nav items */}\n <div\n className=\"absolute bg-ods-border\"\n style={{\n width: '1px',\n height: `${navHeight}px`,\n [ribbonPosition === 'left' ? 'left' : 'right']: '-2px',\n top: '0px',\n }}\n />\n\n {sections.map(section => (\n <div key={section.id} className=\"relative flex h-10 w-full items-stretch transition-all duration-200\">\n {/* Yellow ribbon for active state */}\n {activeSection === section.id && (\n <div\n className=\"absolute z-10 transition-all duration-200\"\n style={{\n backgroundColor: ribbonColor,\n width: '4px',\n height: '24px',\n [ribbonPosition === 'left' ? 'left' : 'right']: '-2px',\n top: '8px',\n borderRadius: '2px',\n }}\n />\n )}\n\n {/* Navigation button */}\n <button\n onClick={() => onSectionClick(section.id)}\n className=\"relative flex flex-1 cursor-pointer items-center gap-2 px-3 py-2\"\n >\n <span\n className={cn(\n 'text-left transition-all duration-200 text-h6',\n activeSection === section.id\n ? 'text-ods-text-primary'\n : 'text-ods-text-secondary hover:text-ods-text-primary',\n )}\n >\n {section.label}\n </span>\n </button>\n </div>\n ))}\n </nav>\n );\n}\n\n/**\n * SIMPLEST POSSIBLE IMPLEMENTATION - Just make it work\n */\nexport function useSectionNavigation(\n sections: { id: string; ref: React.RefObject<HTMLElement> }[],\n options?: {\n offset?: number;\n },\n) {\n const [activeSection, setActiveSection] = useState(sections[0]?.id || '');\n const isScrollingFromClick = useRef(false);\n const { offset = 100 } = options || {};\n\n // Handle click - scroll to the element via the canonical helper.\n // The `offset` prop maps to `headerOffset` (sticky chrome above the\n // section nav); same smooth-scroll mechanics every other anchor\n // surface in the app uses.\n const handleSectionClick = useCallback(\n (sectionId: string) => {\n const targetElement = document.getElementById(sectionId);\n if (!targetElement) return;\n\n // Prevent scroll spy while we're scrolling\n isScrollingFromClick.current = true;\n setActiveSection(sectionId);\n\n scrollElementIntoView(targetElement, { headerOffset: offset });\n\n // Allow scroll spy again after scroll completes\n setTimeout(() => {\n isScrollingFromClick.current = false;\n }, 500);\n },\n [offset],\n );\n\n // Make sure elements have IDs\n useEffect(() => {\n sections.forEach(section => {\n const el = section.ref.current;\n if (el && !el.id) {\n el.id = section.id;\n }\n });\n }, [sections]);\n\n // Simple scroll spy\n useEffect(() => {\n const handleScroll = () => {\n if (isScrollingFromClick.current) return;\n\n const scrollPosition = window.scrollY + offset + 50;\n\n // Find which section we're in\n let currentSection = sections[0]?.id || '';\n\n for (let i = sections.length - 1; i >= 0; i--) {\n const element = document.getElementById(sections[i].id);\n if (element && scrollPosition >= element.offsetTop) {\n currentSection = sections[i].id;\n break;\n }\n }\n\n setActiveSection(currentSection);\n };\n\n // Throttle the scroll handler\n let scrollTimer: NodeJS.Timeout;\n const throttledScroll = () => {\n clearTimeout(scrollTimer);\n scrollTimer = setTimeout(handleScroll, 100);\n };\n\n window.addEventListener('scroll', throttledScroll);\n handleScroll(); // Check initial position\n\n return () => {\n window.removeEventListener('scroll', throttledScroll);\n clearTimeout(scrollTimer);\n };\n }, [sections, offset]);\n\n return {\n activeSection,\n handleSectionClick,\n };\n}\n","'use client';\n\nimport { ChevronDown, ChevronUp, FileText, Folder, FolderOpen } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { DEFAULT_FOLDER_INDEX_FILE as CANONICAL_FOLDER_INDEX_FILE } from '../../utils/doc-tree-nav';\n\nexport interface NavigationNode {\n id: string;\n name: string;\n path: string;\n type: 'file' | 'folder';\n hasReadme?: boolean;\n children?: NavigationNode[];\n slug?: string;\n // Mirror DocNode's extra optional fields so a DocNode tree is structurally\n // assignable to NavigationNode[] without an `as` cast. NavigationNode\n // intentionally never reads these — they're carried for type-compat only.\n documentType?: 'markdown' | 'pdf' | 'google_sheet' | 'figma' | 'file';\n sortOrder?: number;\n}\n\ninterface MultiLevelNavigationProps {\n nodes: NavigationNode[];\n selectedPath: string;\n expandedNodes: Set<string>;\n onNodeClick: (node: NavigationNode) => void;\n onToggleExpand?: (nodeId: string) => void;\n isLoading?: boolean;\n className?: string;\n /** Folder-index filename (default `'README.md'`, case-insensitive). When the\n * selectedPath is a folder with this file, the visual ribbon moves to the\n * child file. */\n folderIndexFile?: string;\n}\n\n// SSOT lives in `doc-tree-nav` (canonical case `'README.md'`). The visual\n// comparator below lowercases both sides, so re-exporting the canonical\n// constant under the same local name preserves call-site syntax without\n// drifting from the SSOT.\nconst DEFAULT_FOLDER_INDEX_FILE = CANONICAL_FOLDER_INDEX_FILE;\n\n/**\n * Compute the visual \"selected\" state for a navigation node.\n *\n * Folder-with-README convention: when `selectedPath` is a folder that has a\n * README, the FOLDER doesn't get the ribbon — its README child does. The folder\n * is just a container; the README is the actual document being viewed.\n *\n * Mirror case: a README file whose parent folder is the `selectedPath` gets the\n * visual selection ribbon (implicit). This handles both the auto-select-first-\n * folder landing path AND the user-clicks-folder case.\n */\nfunction isNodeVisuallySelected(\n node: NavigationNode,\n selectedPath: string,\n folderIndexFile: string = DEFAULT_FOLDER_INDEX_FILE,\n): boolean {\n const FOLDER_INDEX_FILE = folderIndexFile.toLowerCase();\n // Path comparisons keyed on `node.path` (raw, includes `.md`). Do NOT use\n // `node.name` — the tree-builder runs it through `formatDocName` which strips\n // the `.md` extension, so `node.name.toLowerCase() === 'readme.md'` is always\n // false.\n if (selectedPath === node.path) {\n // Explicit match — but folder-with-README defers to its README child.\n return !(node.type === 'folder' && node.hasReadme);\n }\n if (node.type !== 'file') return false;\n const pathLower = node.path.toLowerCase();\n // Implicit: README child whose parent folder is the selectedPath.\n if (selectedPath !== '' && pathLower === `${selectedPath.toLowerCase()}/${FOLDER_INDEX_FILE}`) {\n return true;\n }\n // Implicit: ROOT README on the landing page (selectedPath === '' means\n // \"no explicit doc selected\" — the viewer falls back to the root folder-\n // index file, so that file IS the active document).\n if (selectedPath === '' && pathLower === FOLDER_INDEX_FILE) {\n return true;\n }\n return false;\n}\n\nexport function MultiLevelNavigation({\n nodes,\n selectedPath,\n expandedNodes,\n onNodeClick,\n onToggleExpand,\n isLoading,\n className,\n folderIndexFile = DEFAULT_FOLDER_INDEX_FILE,\n}: MultiLevelNavigationProps) {\n if (isLoading) {\n return (\n <div className={cn('space-y-2', className)}>\n {[1, 2, 3, 4].map(i => (\n <div key={i} className=\"h-12 animate-pulse rounded-lg bg-ods-skeleton p-3\" />\n ))}\n </div>\n );\n }\n\n return (\n <div className={cn('space-y-2', className)} role=\"list\" aria-label=\"Navigation list\">\n {nodes.map(node => (\n <NavigationItem\n key={node.id}\n node={node}\n selectedPath={selectedPath}\n expandedNodes={expandedNodes}\n onNodeClick={onNodeClick}\n onToggleExpand={onToggleExpand}\n level={0}\n folderIndexFile={folderIndexFile}\n />\n ))}\n </div>\n );\n}\n\ninterface NavigationItemProps {\n node: NavigationNode;\n selectedPath: string;\n expandedNodes: Set<string>;\n onNodeClick: (node: NavigationNode) => void;\n onToggleExpand?: (nodeId: string) => void;\n level: number;\n folderIndexFile: string;\n}\n\nfunction NavigationItem({\n node,\n selectedPath,\n expandedNodes,\n onNodeClick,\n onToggleExpand,\n level,\n folderIndexFile,\n}: NavigationItemProps) {\n const isExpanded = expandedNodes.has(node.id);\n const isSelected = isNodeVisuallySelected(node, selectedPath, folderIndexFile);\n // Bind the (optional) child list once so the render below maps a real array\n // rather than re-deriving `hasChildren` and asserting it away.\n const children = node.children ?? [];\n const hasChildren = children.length > 0;\n\n return (\n <div className=\"space-y-1\" role=\"listitem\">\n <div className={cn('px-2', level > 0 && 'ml-4')}>\n <div\n className={cn(\n 'relative w-full rounded-lg border transition-all duration-150',\n isSelected ? 'border-ods-border bg-ods-border' : 'border-ods-border bg-ods-card',\n )}\n >\n <div className=\"relative flex items-center\">\n <button\n className={cn(\n 'flex h-12 w-full items-center rounded-lg px-2 text-ods-text-primary transition-all duration-150 text-h6',\n !isSelected && 'hover:bg-ods-bg-hover',\n hasChildren && 'pr-12',\n )}\n onClick={() => onNodeClick(node)}\n aria-label={`${isSelected ? 'Selected' : 'Select'} ${node.name}`}\n >\n <span className=\"mr-2 flex-shrink-0\">\n {node.type === 'folder' ? (\n isExpanded ? (\n <FolderOpen className=\"h-4 w-4\" />\n ) : (\n <Folder className=\"h-4 w-4\" />\n )\n ) : (\n <FileText className=\"h-4 w-4\" />\n )}\n </span>\n <span className=\"min-w-0 flex-1 truncate text-left\">\n {node.name.endsWith('.md') ? node.name.replace('.md', '') : node.name}\n </span>\n {node.type === 'folder' && node.hasReadme && (\n <span className=\"mr-2 rounded bg-ods-bg-surface px-1.5 py-0.5 text-ods-text-secondary text-h6\">\n README\n </span>\n )}\n </button>\n\n {hasChildren && (\n <button\n className=\"absolute right-0 top-0 flex h-12 w-12 items-center justify-center text-ods-text-secondary transition-colors duration-150 hover:text-ods-text-primary\"\n onClick={e => {\n e.stopPropagation();\n if (onToggleExpand) {\n onToggleExpand(node.id);\n } else {\n onNodeClick(node);\n }\n }}\n aria-label={`${isExpanded ? 'Collapse' : 'Expand'} ${node.name}`}\n >\n {isExpanded ? <ChevronUp className=\"h-4 w-4\" /> : <ChevronDown className=\"h-4 w-4\" />}\n </button>\n )}\n </div>\n\n {isSelected && (\n <div className=\"absolute right-0 top-1/2 h-[calc(100%-8px)] w-1 -translate-y-1/2 rounded-l bg-ods-accent\" />\n )}\n </div>\n </div>\n\n {hasChildren && isExpanded && (\n <div className=\"space-y-1\">\n {children.map(child => (\n <NavigationItem\n key={child.id}\n node={child}\n selectedPath={selectedPath}\n expandedNodes={expandedNodes}\n onNodeClick={onNodeClick}\n onToggleExpand={onToggleExpand}\n level={level + 1}\n folderIndexFile={folderIndexFile}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nexport function MobileNavigationDropdown({\n nodes,\n selectedPath,\n expandedNodes,\n onNodeClick,\n onToggleExpand,\n isLoading,\n className,\n folderIndexFile = DEFAULT_FOLDER_INDEX_FILE,\n}: MultiLevelNavigationProps) {\n if (isLoading) {\n return (\n <div className={cn('space-y-2', className)}>\n {[1, 2, 3].map(i => (\n <div key={i} className=\"h-10 animate-pulse rounded-lg bg-ods-skeleton p-3\" />\n ))}\n </div>\n );\n }\n\n return (\n <div className={cn('space-y-2', className)}>\n {nodes.map(node => (\n <MobileNavigationItem\n key={node.id}\n node={node}\n selectedPath={selectedPath}\n expandedNodes={expandedNodes}\n onNodeClick={onNodeClick}\n onToggleExpand={onToggleExpand}\n level={0}\n folderIndexFile={folderIndexFile}\n />\n ))}\n </div>\n );\n}\n\nfunction MobileNavigationItem({\n node,\n selectedPath,\n expandedNodes,\n onNodeClick,\n onToggleExpand,\n level,\n folderIndexFile,\n}: NavigationItemProps) {\n const isExpanded = expandedNodes.has(node.id);\n const isSelected = isNodeVisuallySelected(node, selectedPath, folderIndexFile);\n // Same binding as the desktop item above — a real array to map, no assertion.\n const children = node.children ?? [];\n const hasChildren = children.length > 0;\n\n return (\n <div className=\"space-y-1\">\n <div className={cn('px-2', level > 0 && 'ml-3')}>\n <div\n className={cn(\n 'relative w-full rounded-lg border transition-all duration-150',\n isSelected ? 'border-ods-border bg-ods-border' : 'border-ods-border bg-ods-card',\n )}\n >\n <div className=\"relative flex items-center\">\n <button\n className={cn(\n 'flex h-11 w-full items-center rounded-lg px-2 text-ods-text-primary transition-all duration-150 text-h6',\n !isSelected && 'hover:bg-ods-bg-hover',\n hasChildren && 'pr-11',\n )}\n onClick={() => onNodeClick(node)}\n >\n <span className=\"mr-2 flex-shrink-0\">\n {node.type === 'folder' ? (\n isExpanded ? (\n <FolderOpen className=\"h-4 w-4\" />\n ) : (\n <Folder className=\"h-4 w-4\" />\n )\n ) : (\n <FileText className=\"h-4 w-4\" />\n )}\n </span>\n <span className=\"min-w-0 flex-1 truncate text-left\">\n {node.name.endsWith('.md') ? node.name.replace('.md', '') : node.name}\n </span>\n {node.type === 'folder' && node.hasReadme && (\n <span className=\"mr-2 rounded bg-ods-bg-surface px-1.5 py-0.5 text-ods-text-secondary text-h6\">\n README\n </span>\n )}\n </button>\n\n {hasChildren && (\n <button\n className=\"absolute right-0 top-0 flex h-11 w-11 items-center justify-center text-ods-text-secondary transition-colors duration-150 hover:text-ods-text-primary\"\n onClick={e => {\n e.stopPropagation();\n if (onToggleExpand) {\n onToggleExpand(node.id);\n } else {\n onNodeClick(node);\n }\n }}\n aria-label={`${isExpanded ? 'Collapse' : 'Expand'} ${node.name}`}\n >\n {isExpanded ? <ChevronUp className=\"h-3.5 w-3.5\" /> : <ChevronDown className=\"h-3.5 w-3.5\" />}\n </button>\n )}\n </div>\n\n {isSelected && (\n <div className=\"absolute right-0 top-1/2 h-[calc(100%-8px)] w-1 -translate-y-1/2 rounded-l bg-ods-accent\" />\n )}\n </div>\n </div>\n\n {hasChildren && isExpanded && (\n <div className=\"space-y-1\">\n {children.map(child => (\n <MobileNavigationItem\n key={child.id}\n node={child}\n selectedPath={selectedPath}\n expandedNodes={expandedNodes}\n onNodeClick={onNodeClick}\n onToggleExpand={onToggleExpand}\n level={level + 1}\n folderIndexFile={folderIndexFile}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n"]}
@@ -3,16 +3,16 @@
3
3
 
4
4
 
5
5
 
6
- var _chunkT3ACDOVDcjs = require('./chunk-T3ACDOVD.cjs');
6
+ var _chunkVRZZCL4Rcjs = require('./chunk-VRZZCL4R.cjs');
7
7
 
8
8
 
9
9
 
10
10
 
11
- var _chunkII66XWU5cjs = require('./chunk-II66XWU5.cjs');
11
+ var _chunkD6IOMPAHcjs = require('./chunk-D6IOMPAH.cjs');
12
12
 
13
13
 
14
14
 
15
- var _chunkGF5TSQ6Ccjs = require('./chunk-GF5TSQ6C.cjs');
15
+ var _chunkKXL534EVcjs = require('./chunk-KXL534EV.cjs');
16
16
 
17
17
 
18
18
 
@@ -22,7 +22,7 @@ var _chunkGF5TSQ6Ccjs = require('./chunk-GF5TSQ6C.cjs');
22
22
 
23
23
 
24
24
 
25
- var _chunkOG2BNJ2Qcjs = require('./chunk-OG2BNJ2Q.cjs');
25
+ var _chunk6PPEG2N4cjs = require('./chunk-6PPEG2N4.cjs');
26
26
 
27
27
 
28
28
  var _chunkVTYP25OWcjs = require('./chunk-VTYP25OW.cjs');
@@ -324,8 +324,8 @@ function toDocContent(value, requestedPath) {
324
324
  }
325
325
  function useDocumentTree(config, initialPath) {
326
326
  const { structureEndpoint, contentEndpoint, baseRoute } = config;
327
- const folderIndexFile = _nullishCoalesce(config.folderIndexFile, () => ( _chunkOG2BNJ2Qcjs.DEFAULT_FOLDER_INDEX_FILE));
328
- const cleanInitialPath = _chunkOG2BNJ2Qcjs.stripFolderIndexFromPath.call(void 0, _optionalChain([initialPath, 'optionalAccess', _4 => _4.replace, 'call', _5 => _5(/\/$/, "")]) || "", folderIndexFile);
327
+ const folderIndexFile = _nullishCoalesce(config.folderIndexFile, () => ( _chunk6PPEG2N4cjs.DEFAULT_FOLDER_INDEX_FILE));
328
+ const cleanInitialPath = _chunk6PPEG2N4cjs.stripFolderIndexFromPath.call(void 0, _optionalChain([initialPath, 'optionalAccess', _4 => _4.replace, 'call', _5 => _5(/\/$/, "")]) || "", folderIndexFile);
329
329
  const [structure, setStructure] = _react.useState.call(void 0, []);
330
330
  const [selectedPath, setSelectedPath] = _react.useState.call(void 0, cleanInitialPath);
331
331
  const [content, setContent] = _react.useState.call(void 0, null);
@@ -349,12 +349,12 @@ function useDocumentTree(config, initialPath) {
349
349
  } else if (pathname.startsWith(`${normalizedBaseRoute}/`)) {
350
350
  pathFromUrl = pathname.substring(`${normalizedBaseRoute}/`.length);
351
351
  }
352
- pathFromUrl = _chunkOG2BNJ2Qcjs.stripFolderIndexFromPath.call(void 0, pathFromUrl, folderIndexFile);
352
+ pathFromUrl = _chunk6PPEG2N4cjs.stripFolderIndexFromPath.call(void 0, pathFromUrl, folderIndexFile);
353
353
  if (pathFromUrl !== selectedPathRef.current) {
354
354
  setSelectedPath(pathFromUrl);
355
355
  if (pathFromUrl) {
356
356
  const parentPath = pathFromUrl.includes("/") ? pathFromUrl.substring(0, pathFromUrl.lastIndexOf("/")) : pathFromUrl;
357
- setExpandedNodes(new Set(_chunkOG2BNJ2Qcjs.getDocAncestorNodeIds.call(void 0, parentPath)));
357
+ setExpandedNodes(new Set(_chunk6PPEG2N4cjs.getDocAncestorNodeIds.call(void 0, parentPath)));
358
358
  }
359
359
  setTimeout(() => {
360
360
  scrollToContent();
@@ -372,7 +372,7 @@ function useDocumentTree(config, initialPath) {
372
372
  setSelectedPath(cleanInitialPath);
373
373
  if (cleanInitialPath) {
374
374
  const parentPath = cleanInitialPath.includes("/") ? cleanInitialPath.substring(0, cleanInitialPath.lastIndexOf("/")) : cleanInitialPath;
375
- setExpandedNodes(new Set(_chunkOG2BNJ2Qcjs.getDocAncestorNodeIds.call(void 0, parentPath)));
375
+ setExpandedNodes(new Set(_chunk6PPEG2N4cjs.getDocAncestorNodeIds.call(void 0, parentPath)));
376
376
  }
377
377
  setExternalNavCount((n) => n + 1);
378
378
  }
@@ -397,7 +397,7 @@ function useDocumentTree(config, initialPath) {
397
397
  if (cleanInitialPath) {
398
398
  const pathForExpansion = cleanInitialPath.includes(".") ? cleanInitialPath.substring(0, cleanInitialPath.lastIndexOf("/")) : cleanInitialPath;
399
399
  if (pathForExpansion) {
400
- setExpandedNodes(new Set(_chunkOG2BNJ2Qcjs.getDocAncestorNodeIds.call(void 0, pathForExpansion)));
400
+ setExpandedNodes(new Set(_chunk6PPEG2N4cjs.getDocAncestorNodeIds.call(void 0, pathForExpansion)));
401
401
  }
402
402
  } else if (nodes.length > 0) {
403
403
  const hasRootReadme = nodes.some((node) => node.type === "file" && node.path === folderIndexFile);
@@ -437,7 +437,7 @@ function useDocumentTree(config, initialPath) {
437
437
  setContent(null);
438
438
  return;
439
439
  }
440
- const probe = _chunkOG2BNJ2Qcjs.findDocNodeByPath.call(void 0, _chunkOG2BNJ2Qcjs.stripFolderIndexFromPath.call(void 0, path, folderIndexFile), structure);
440
+ const probe = _chunk6PPEG2N4cjs.findDocNodeByPath.call(void 0, _chunk6PPEG2N4cjs.stripFolderIndexFromPath.call(void 0, path, folderIndexFile), structure);
441
441
  const probeIsNoReadmeFolder = !!probe && probe.type === "folder" && !probe.hasReadme;
442
442
  const preStructureFolderLike = structure.length === 0 && !path.endsWith(".md");
443
443
  if (probeIsNoReadmeFolder || preStructureFolderLike) {
@@ -494,7 +494,7 @@ function useDocumentTree(config, initialPath) {
494
494
  if (selectedPath === "") {
495
495
  pathToFetch = folderIndexFile;
496
496
  } else {
497
- const node = _chunkOG2BNJ2Qcjs.findDocNodeByPath.call(void 0, selectedPath, structure);
497
+ const node = _chunk6PPEG2N4cjs.findDocNodeByPath.call(void 0, selectedPath, structure);
498
498
  if (node && node.type === "folder" && !node.hasReadme) {
499
499
  const firstDocPath = findFirstDocPath(node);
500
500
  if (!firstDocPath) {
@@ -535,16 +535,16 @@ function useDocumentTree(config, initialPath) {
535
535
  if (node.type === "folder") {
536
536
  setExpandedNodes((prev) => {
537
537
  if (prev.has(node.id)) {
538
- const ancestorIds = _chunkOG2BNJ2Qcjs.getDocAncestorNodeIds.call(void 0, node.path);
538
+ const ancestorIds = _chunk6PPEG2N4cjs.getDocAncestorNodeIds.call(void 0, node.path);
539
539
  ancestorIds.pop();
540
540
  return new Set(ancestorIds);
541
541
  }
542
- return new Set(_chunkOG2BNJ2Qcjs.getDocAncestorNodeIds.call(void 0, node.path));
542
+ return new Set(_chunk6PPEG2N4cjs.getDocAncestorNodeIds.call(void 0, node.path));
543
543
  });
544
544
  } else {
545
545
  const lastSlash = node.path.lastIndexOf("/");
546
546
  if (lastSlash > 0) {
547
- setExpandedNodes(new Set(_chunkOG2BNJ2Qcjs.getDocAncestorNodeIds.call(void 0, node.path.substring(0, lastSlash))));
547
+ setExpandedNodes(new Set(_chunk6PPEG2N4cjs.getDocAncestorNodeIds.call(void 0, node.path.substring(0, lastSlash))));
548
548
  }
549
549
  }
550
550
  lastFetchedPath.current = null;
@@ -559,7 +559,7 @@ function useDocumentTree(config, initialPath) {
559
559
  const hashIndex = path.indexOf("#");
560
560
  const anchor = hashIndex !== -1 ? path.substring(hashIndex) : "";
561
561
  const cleanPath = path.replace(/\/$/, "").split("#")[0];
562
- const pathForSelection = anchor && _optionalChain([options, 'optionalAccess', _6 => _6.fromInternalLink]) && cleanPath === "" ? selectedPathRef.current : _chunkOG2BNJ2Qcjs.stripFolderIndexFromPath.call(void 0, cleanPath, folderIndexFile);
562
+ const pathForSelection = anchor && _optionalChain([options, 'optionalAccess', _6 => _6.fromInternalLink]) && cleanPath === "" ? selectedPathRef.current : _chunk6PPEG2N4cjs.stripFolderIndexFromPath.call(void 0, cleanPath, folderIndexFile);
563
563
  if (anchor && _optionalChain([options, 'optionalAccess', _7 => _7.fromInternalLink]) && pathForSelection === selectedPathRef.current) {
564
564
  _chunkV2A4MAALcjs.navigateSamePageHash.call(void 0, anchor, { headerOffset: _chunkV2A4MAALcjs.HUB_HEADER_OFFSET_PX });
565
565
  return;
@@ -623,15 +623,15 @@ function useDocumentTree(config, initialPath) {
623
623
  return docNavigation.register({
624
624
  baseRoute: normalizedBaseRoute,
625
625
  findNodeByPath: (path) => {
626
- const clean = _chunkOG2BNJ2Qcjs.stripFolderIndexFromPath.call(void 0, path.replace(/\/$/, "").split("#")[0], folderIndexFile);
627
- return _nullishCoalesce(_chunkOG2BNJ2Qcjs.findDocNodeByPath.call(void 0, clean, structure), () => ( null));
626
+ const clean = _chunk6PPEG2N4cjs.stripFolderIndexFromPath.call(void 0, path.replace(/\/$/, "").split("#")[0], folderIndexFile);
627
+ return _nullishCoalesce(_chunk6PPEG2N4cjs.findDocNodeByPath.call(void 0, clean, structure), () => ( null));
628
628
  },
629
629
  selectNode
630
630
  });
631
631
  }, [docNavigation, normalizedBaseRoute, structure, selectNode, folderIndexFile]);
632
632
  const isEmptyFolder = _react.useMemo.call(void 0, () => {
633
633
  if (!selectedPath || structure.length === 0) return false;
634
- const node = _chunkOG2BNJ2Qcjs.findDocNodeByPath.call(void 0, selectedPath, structure);
634
+ const node = _chunk6PPEG2N4cjs.findDocNodeByPath.call(void 0, selectedPath, structure);
635
635
  return !!node && node.type === "folder" && !node.hasReadme && !findFirstDocPath(node);
636
636
  }, [selectedPath, structure]);
637
637
  return {
@@ -786,7 +786,7 @@ function DocViewerContent({
786
786
  label: _nullishCoalesce(_optionalChain([backButton, 'optionalAccess', _16 => _16.label]), () => ( "Back to home")),
787
787
  onClick: () => router.push(_nullishCoalesce(_optionalChain([backButton, 'optionalAccess', _17 => _17.href]), () => ( "/")))
788
788
  };
789
- const docSearch = _chunkGF5TSQ6Ccjs.useDocSearch.call(void 0, {
789
+ const docSearch = _chunkKXL534EVcjs.useDocSearch.call(void 0, {
790
790
  source: chatSource,
791
791
  baseRoute,
792
792
  searchEndpoint,
@@ -810,7 +810,7 @@ function DocViewerContent({
810
810
  onResolveLink: resolveLink
811
811
  });
812
812
  }, [content, renderContent, navigateToDoc, sourceId, resolveLink]);
813
- const selectedNodeDocType = selectedPath && structure.length > 0 ? _optionalChain([_chunkOG2BNJ2Qcjs.findDocNodeByPath.call(void 0, selectedPath, structure), 'optionalAccess', _18 => _18.documentType]) : void 0;
813
+ const selectedNodeDocType = selectedPath && structure.length > 0 ? _optionalChain([_chunk6PPEG2N4cjs.findDocNodeByPath.call(void 0, selectedPath, structure), 'optionalAccess', _18 => _18.documentType]) : void 0;
814
814
  const activeDocType = _nullishCoalesce(_optionalChain([content, 'optionalAccess', _19 => _19.documentType]), () => ( selectedNodeDocType));
815
815
  const isMarkdownContent = !activeDocType || activeDocType === "markdown";
816
816
  const showStickyNav = isMarkdownContent;
@@ -821,9 +821,9 @@ function DocViewerContent({
821
821
  const containerBgStyle = colorPalette.containerBackground !== "transparent" ? { backgroundColor: colorPalette.containerBackground } : {};
822
822
  const defaultEmptyText = structure.length > 0 ? "Select a document from the sidebar to view" : "No documents yet. Add content from the admin panel.";
823
823
  const resolvedEmptyText = emptyStateText || defaultEmptyText;
824
- const inner = /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { ...bgStyle, ...containerBgStyle }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkOG2BNJ2Qcjs.PageLayout, { title, subtitle, titleSize: "h1", titleWrap: true, backButton: _nullishCoalesce(backCfg, () => ( void 0)), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-col gap-10", children: [
824
+ const inner = /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { ...bgStyle, ...containerBgStyle }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6PPEG2N4cjs.PageLayout, { title, subtitle, titleSize: "h1", titleWrap: true, backButton: _nullishCoalesce(backCfg, () => ( void 0)), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-col gap-10", children: [
825
825
  showAIChat && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
826
- _chunkGF5TSQ6Ccjs.DocSearchBar,
826
+ _chunkKXL534EVcjs.DocSearchBar,
827
827
  {
828
828
  placeholder: `Search ${_optionalChain([sidebarLabel, 'optionalAccess', _23 => _23.toLowerCase, 'call', _24 => _24()]) || "documents"}...`,
829
829
  query: docSearch.query,
@@ -842,9 +842,9 @@ function DocViewerContent({
842
842
  ] })
843
843
  ] }) }),
844
844
  !error && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-1 flex-col items-start gap-6 lg:flex-row lg:gap-10", children: [
845
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full lg:w-[320px] lg:shrink-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "lg:sticky lg:top-20", children: isLoadingStructure ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkOG2BNJ2Qcjs.CategorySidebarSkeleton, {}) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
845
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full lg:w-[320px] lg:shrink-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "lg:sticky lg:top-20", children: isLoadingStructure ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6PPEG2N4cjs.CategorySidebarSkeleton, {}) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
846
846
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PersistentMobileDropdown, { isLoading: false, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
847
- _chunkII66XWU5cjs.MobileNavigationDropdown,
847
+ _chunkD6IOMPAHcjs.MobileNavigationDropdown,
848
848
  {
849
849
  nodes: structure,
850
850
  selectedPath,
@@ -858,7 +858,7 @@ function DocViewerContent({
858
858
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PersistentSidebar, { isLoading: false, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "hidden lg:block", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-4", children: [
859
859
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-semibold text-ods-text-secondary text-h5", children: sidebarLabel }),
860
860
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
861
- _chunkII66XWU5cjs.MultiLevelNavigation,
861
+ _chunkD6IOMPAHcjs.MultiLevelNavigation,
862
862
  {
863
863
  nodes: structure,
864
864
  selectedPath,
@@ -897,7 +897,7 @@ function DocViewerContent({
897
897
  showStickyNav && content && stickyNavSections.length > 0 && !isLoadingContent && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "hidden lg:block", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "sticky top-24", children: [
898
898
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "mb-4 font-semibold text-ods-text-secondary text-h5", children: "ON THIS PAGE" }),
899
899
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
900
- _chunkII66XWU5cjs.StickySectionNav,
900
+ _chunkD6IOMPAHcjs.StickySectionNav,
901
901
  {
902
902
  sections: stickyNavSections,
903
903
  activeSection,
@@ -912,7 +912,7 @@ function DocViewerContent({
912
912
  ) })
913
913
  ] })
914
914
  ] }) }) });
915
- return shell ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkOG2BNJ2Qcjs.PageShell, { contentClassName: `${bgClass} ${className}`, children: inner }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: `page-shell-content ${bgClass} ${className}`.trim(), children: inner });
915
+ return shell ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6PPEG2N4cjs.PageShell, { contentClassName: `${bgClass} ${className}`, children: inner }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: `page-shell-content ${bgClass} ${className}`.trim(), children: inner });
916
916
  }
917
917
 
918
918
  // src/components/docs/skeletons.tsx
@@ -1002,11 +1002,11 @@ function EmbedSkeleton({ documentType } = {}) {
1002
1002
 
1003
1003
  var DEFAULT_TITLE = "Documents";
1004
1004
  var defaultFallbackRenderer = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "py-16 text-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-ods-text-secondary", children: "Unsupported document type" }) });
1005
- var defaultPdfRenderer = (content, handlers) => content.fileUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT3ACDOVDcjs.PdfViewer, { src: content.fileUrl, fileName: content.fileName }) : defaultFallbackRenderer(content, handlers);
1006
- var defaultGoogleSheetRenderer = (content, handlers) => content.externalUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT3ACDOVDcjs.GoogleSheetsViewer, { externalUrl: content.externalUrl, fileName: content.fileName }) : defaultFallbackRenderer(content, handlers);
1007
- var defaultFigmaRenderer = (content, handlers) => content.externalUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkOG2BNJ2Qcjs.FigmaEmbed, { url: content.externalUrl, title: content.fileName, loading: "eager" }) : defaultFallbackRenderer(content, handlers);
1005
+ var defaultPdfRenderer = (content, handlers) => content.fileUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkVRZZCL4Rcjs.PdfViewer, { src: content.fileUrl, fileName: content.fileName }) : defaultFallbackRenderer(content, handlers);
1006
+ var defaultGoogleSheetRenderer = (content, handlers) => content.externalUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkVRZZCL4Rcjs.GoogleSheetsViewer, { externalUrl: content.externalUrl, fileName: content.fileName }) : defaultFallbackRenderer(content, handlers);
1007
+ var defaultFigmaRenderer = (content, handlers) => content.externalUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6PPEG2N4cjs.FigmaEmbed, { url: content.externalUrl, title: content.fileName, loading: "eager" }) : defaultFallbackRenderer(content, handlers);
1008
1008
  var defaultFileRenderer = (content) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1009
- _chunkT3ACDOVDcjs.FileDownloadCard,
1009
+ _chunkVRZZCL4Rcjs.FileDownloadCard,
1010
1010
  {
1011
1011
  fileName: content.fileName,
1012
1012
  mimeType: content.mimeType,
@@ -1069,4 +1069,4 @@ function DocsHubPage({
1069
1069
 
1070
1070
 
1071
1071
  exports.PersistentFilterControls = PersistentFilterControls; exports.PersistentSearchContainer = PersistentSearchContainer; exports.PersistentSidebar = PersistentSidebar; exports.PersistentMobileDropdown = PersistentMobileDropdown; exports.DocNavigationProvider = DocNavigationProvider; exports.useDocNavigation = useDocNavigation; exports.useDocumentTree = useDocumentTree; exports.useScrollSpy = useScrollSpy; exports.DocViewer = DocViewer; exports.MarkdownSkeleton = MarkdownSkeleton; exports.EmbedSkeleton = EmbedSkeleton; exports.DocsHubPage = DocsHubPage;
1072
- //# sourceMappingURL=chunk-DAGKBFZN.cjs.map
1072
+ //# sourceMappingURL=chunk-EQIBWG5U.cjs.map