@flamingo-stack/openframe-frontend-core 0.0.580-1961.5367.1 → 0.0.580
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/dist/{chunk-KOXEFRIS.cjs → chunk-2H5THD2V.cjs} +69 -69
- package/dist/{chunk-KOXEFRIS.cjs.map → chunk-2H5THD2V.cjs.map} +1 -1
- package/dist/{chunk-KTVCPFRY.js → chunk-4VXJLVEF.js} +3 -3
- package/dist/{chunk-D5H4PRT6.cjs → chunk-7QBSMF3A.cjs} +4 -4
- package/dist/{chunk-D5H4PRT6.cjs.map → chunk-7QBSMF3A.cjs.map} +1 -1
- package/dist/{chunk-NHUVHW6N.js → chunk-AHPTMNF2.js} +2 -2
- package/dist/{chunk-CNHSVN5U.cjs → chunk-BVQYK3TO.cjs} +159 -159
- package/dist/{chunk-CNHSVN5U.cjs.map → chunk-BVQYK3TO.cjs.map} +1 -1
- package/dist/{chunk-4LPRIBW6.js → chunk-CCQDL6HM.js} +3 -3
- package/dist/{chunk-MDOLH3P3.cjs → chunk-DLLMAPL5.cjs} +5 -5
- package/dist/{chunk-MDOLH3P3.cjs.map → chunk-DLLMAPL5.cjs.map} +1 -1
- package/dist/{chunk-GBQLFG3C.js → chunk-FEPUMLJL.js} +4 -4
- package/dist/{chunk-F5FAVDVN.js → chunk-FF27HBZ7.js} +2 -2
- package/dist/{chunk-YSZFIV7M.cjs → chunk-FHICKOW7.cjs} +22 -22
- package/dist/{chunk-YSZFIV7M.cjs.map → chunk-FHICKOW7.cjs.map} +1 -1
- package/dist/{chunk-KDBRR4NA.cjs → chunk-FLUR7CUB.cjs} +3 -3
- package/dist/{chunk-KDBRR4NA.cjs.map → chunk-FLUR7CUB.cjs.map} +1 -1
- package/dist/{chunk-E6W6XU5Q.cjs → chunk-FWY4U5CB.cjs} +10 -10
- package/dist/{chunk-E6W6XU5Q.cjs.map → chunk-FWY4U5CB.cjs.map} +1 -1
- package/dist/{chunk-XDYPYW3K.js → chunk-HJVKPG55.js} +4 -10
- package/dist/chunk-HJVKPG55.js.map +1 -0
- package/dist/{chunk-XQ5RB7JR.cjs → chunk-IB7PMKJX.cjs} +9 -9
- package/dist/{chunk-XQ5RB7JR.cjs.map → chunk-IB7PMKJX.cjs.map} +1 -1
- package/dist/{chunk-6EFHTJAS.js → chunk-KMC44UBW.js} +3 -3
- package/dist/{chunk-Q6TEYGFN.js → chunk-LCR3J5Z4.js} +3 -3
- package/dist/{chunk-OU4FQZWH.js → chunk-MHA4KNWD.js} +2 -2
- package/dist/{chunk-Y6PZVGSN.cjs → chunk-MPHTQLXW.cjs} +24 -24
- package/dist/{chunk-Y6PZVGSN.cjs.map → chunk-MPHTQLXW.cjs.map} +1 -1
- package/dist/{chunk-7LF4L4PN.js → chunk-OABA7YGU.js} +6 -6
- package/dist/{chunk-AH7OTMJR.js → chunk-P2XZEUDA.js} +5 -5
- package/dist/{chunk-UXE4DR4N.js → chunk-PPWFQVWK.js} +3 -3
- package/dist/{chunk-DPVNUSNO.cjs → chunk-Q3MR6FFT.cjs} +21 -21
- package/dist/{chunk-DPVNUSNO.cjs.map → chunk-Q3MR6FFT.cjs.map} +1 -1
- package/dist/{chunk-LZ46JHWB.js → chunk-ROUP3WGG.js} +5 -5
- package/dist/{chunk-WSBVOHYG.js → chunk-SE2AQAOH.js} +5 -5
- package/dist/{chunk-GA4SY5N3.cjs → chunk-TDTACWIE.cjs} +15 -15
- package/dist/{chunk-GA4SY5N3.cjs.map → chunk-TDTACWIE.cjs.map} +1 -1
- package/dist/{chunk-QS47HKYQ.cjs → chunk-ULMO6SIY.cjs} +43 -43
- package/dist/{chunk-QS47HKYQ.cjs.map → chunk-ULMO6SIY.cjs.map} +1 -1
- package/dist/{chunk-EUIYALFP.cjs → chunk-ULZHN4XS.cjs} +3 -3
- package/dist/{chunk-EUIYALFP.cjs.map → chunk-ULZHN4XS.cjs.map} +1 -1
- package/dist/{chunk-OEFQPESB.js → chunk-UWVKWRM3.js} +2 -2
- package/dist/{chunk-GTYXMVOG.cjs → chunk-V3XCLT5V.cjs} +32 -32
- package/dist/{chunk-GTYXMVOG.cjs.map → chunk-V3XCLT5V.cjs.map} +1 -1
- package/dist/{chunk-MNCI3CXL.cjs → chunk-VQTE5WAE.cjs} +10 -10
- package/dist/{chunk-MNCI3CXL.cjs.map → chunk-VQTE5WAE.cjs.map} +1 -1
- package/dist/{chunk-DJJAEVB2.js → chunk-YLLX27VK.js} +2 -2
- package/dist/{chunk-A4F7VLCJ.cjs → chunk-YU2UJPAT.cjs} +4 -10
- package/dist/chunk-YU2UJPAT.cjs.map +1 -0
- package/dist/components/case-studies/index.cjs +9 -9
- package/dist/components/case-studies/index.js +3 -3
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/contact/index.cjs +4 -4
- package/dist/components/contact/index.js +3 -3
- package/dist/components/docs/index.cjs +7 -7
- package/dist/components/docs/index.js +6 -6
- package/dist/components/embeds/index.cjs +4 -4
- package/dist/components/embeds/index.js +3 -3
- package/dist/components/faq/index.cjs +4 -4
- package/dist/components/faq/index.js +3 -3
- package/dist/components/features/index.cjs +3 -3
- package/dist/components/features/index.js +2 -2
- package/dist/components/help-center-pages/index.cjs +23 -23
- package/dist/components/help-center-pages/index.js +14 -14
- package/dist/components/index.cjs +121 -121
- package/dist/components/index.js +13 -13
- package/dist/components/meeting-scheduler/index.cjs +21 -21
- package/dist/components/meeting-scheduler/index.js +2 -2
- package/dist/components/navigation/index.cjs +6 -6
- package/dist/components/navigation/index.js +5 -5
- package/dist/components/onboarding-guides/index.cjs +6 -6
- package/dist/components/onboarding-guides/index.js +5 -5
- package/dist/components/tickets/index.cjs +7 -7
- package/dist/components/tickets/index.js +6 -6
- package/dist/components/ui/actions-menu-header-context.d.ts +3 -2
- package/dist/components/ui/actions-menu-header-context.d.ts.map +1 -1
- package/dist/components/ui/index.cjs +3 -3
- package/dist/components/ui/index.js +2 -2
- package/dist/components/ui/tab-selector.d.ts.map +1 -1
- package/dist/index.cjs +7 -7
- package/dist/index.js +6 -6
- package/package.json +1 -1
- package/src/components/ui/.actions-menu.md +1 -1
- package/src/components/ui/.tab-selector.md +1 -1
- package/src/components/ui/actions-menu-header-context.ts +3 -2
- package/src/components/ui/tab-selector.tsx +9 -13
- package/dist/chunk-A4F7VLCJ.cjs.map +0 -1
- package/dist/chunk-XDYPYW3K.js.map +0 -1
- /package/dist/{chunk-KTVCPFRY.js.map → chunk-4VXJLVEF.js.map} +0 -0
- /package/dist/{chunk-NHUVHW6N.js.map → chunk-AHPTMNF2.js.map} +0 -0
- /package/dist/{chunk-4LPRIBW6.js.map → chunk-CCQDL6HM.js.map} +0 -0
- /package/dist/{chunk-GBQLFG3C.js.map → chunk-FEPUMLJL.js.map} +0 -0
- /package/dist/{chunk-F5FAVDVN.js.map → chunk-FF27HBZ7.js.map} +0 -0
- /package/dist/{chunk-6EFHTJAS.js.map → chunk-KMC44UBW.js.map} +0 -0
- /package/dist/{chunk-Q6TEYGFN.js.map → chunk-LCR3J5Z4.js.map} +0 -0
- /package/dist/{chunk-OU4FQZWH.js.map → chunk-MHA4KNWD.js.map} +0 -0
- /package/dist/{chunk-7LF4L4PN.js.map → chunk-OABA7YGU.js.map} +0 -0
- /package/dist/{chunk-AH7OTMJR.js.map → chunk-P2XZEUDA.js.map} +0 -0
- /package/dist/{chunk-UXE4DR4N.js.map → chunk-PPWFQVWK.js.map} +0 -0
- /package/dist/{chunk-LZ46JHWB.js.map → chunk-ROUP3WGG.js.map} +0 -0
- /package/dist/{chunk-WSBVOHYG.js.map → chunk-SE2AQAOH.js.map} +0 -0
- /package/dist/{chunk-OEFQPESB.js.map → chunk-UWVKWRM3.js.map} +0 -0
- /package/dist/{chunk-DJJAEVB2.js.map → chunk-YLLX27VK.js.map} +0 -0
|
@@ -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
|
|
4
|
+
var _chunkBVQYK3TOcjs = require('./chunk-BVQYK3TO.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
var _chunkZI27ALYXcjs = require('./chunk-ZI27ALYX.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 =
|
|
132
|
+
var DEFAULT_FOLDER_INDEX_FILE2 = _chunkBVQYK3TOcjs.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-
|
|
360
|
+
//# sourceMappingURL=chunk-ULZHN4XS.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-EUIYALFP.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-EUIYALFP.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-ULZHN4XS.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-ULZHN4XS.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"]}
|
|
@@ -90,7 +90,7 @@ import {
|
|
|
90
90
|
useCollapsible,
|
|
91
91
|
useIsHydrated,
|
|
92
92
|
useScrollFade
|
|
93
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-HJVKPG55.js";
|
|
94
94
|
import {
|
|
95
95
|
ToolIcon,
|
|
96
96
|
createHeadingIdDeduper,
|
|
@@ -28472,4 +28472,4 @@ export {
|
|
|
28472
28472
|
ReopenTicketRequestModal,
|
|
28473
28473
|
FilterPillRow
|
|
28474
28474
|
};
|
|
28475
|
-
//# sourceMappingURL=chunk-
|
|
28475
|
+
//# sourceMappingURL=chunk-UWVKWRM3.js.map
|
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunk7QBSMF3Acjs = require('./chunk-7QBSMF3A.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var _chunkULZHN4XScjs = require('./chunk-ULZHN4XS.cjs');
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
var
|
|
15
|
+
var _chunkIB7PMKJXcjs = require('./chunk-IB7PMKJX.cjs');
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
|
|
@@ -21,7 +21,7 @@ var _chunkXQ5RB7JRcjs = require('./chunk-XQ5RB7JR.cjs');
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
var
|
|
24
|
+
var _chunkBVQYK3TOcjs = require('./chunk-BVQYK3TO.cjs');
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
var _chunkLEISUAHFcjs = require('./chunk-LEISUAHF.cjs');
|
|
@@ -1119,8 +1119,8 @@ function toDocContent(value, requestedPath) {
|
|
|
1119
1119
|
}
|
|
1120
1120
|
function useDocumentTree(config, initialPath) {
|
|
1121
1121
|
const { structureEndpoint, contentEndpoint, baseRoute } = config;
|
|
1122
|
-
const folderIndexFile = _nullishCoalesce(config.folderIndexFile, () => (
|
|
1123
|
-
const cleanInitialPath =
|
|
1122
|
+
const folderIndexFile = _nullishCoalesce(config.folderIndexFile, () => ( _chunkBVQYK3TOcjs.DEFAULT_FOLDER_INDEX_FILE));
|
|
1123
|
+
const cleanInitialPath = _chunkBVQYK3TOcjs.stripFolderIndexFromPath.call(void 0, _optionalChain([initialPath, 'optionalAccess', _4 => _4.replace, 'call', _5 => _5(/\/$/, "")]) || "", folderIndexFile);
|
|
1124
1124
|
const [structure, setStructure] = _react.useState.call(void 0, []);
|
|
1125
1125
|
const [selectedPath, setSelectedPath] = _react.useState.call(void 0, cleanInitialPath);
|
|
1126
1126
|
const [content, setContent] = _react.useState.call(void 0, null);
|
|
@@ -1144,12 +1144,12 @@ function useDocumentTree(config, initialPath) {
|
|
|
1144
1144
|
} else if (pathname.startsWith(`${normalizedBaseRoute}/`)) {
|
|
1145
1145
|
pathFromUrl = pathname.substring(`${normalizedBaseRoute}/`.length);
|
|
1146
1146
|
}
|
|
1147
|
-
pathFromUrl =
|
|
1147
|
+
pathFromUrl = _chunkBVQYK3TOcjs.stripFolderIndexFromPath.call(void 0, pathFromUrl, folderIndexFile);
|
|
1148
1148
|
if (pathFromUrl !== selectedPathRef.current) {
|
|
1149
1149
|
setSelectedPath(pathFromUrl);
|
|
1150
1150
|
if (pathFromUrl) {
|
|
1151
1151
|
const parentPath = pathFromUrl.includes("/") ? pathFromUrl.substring(0, pathFromUrl.lastIndexOf("/")) : pathFromUrl;
|
|
1152
|
-
setExpandedNodes(new Set(
|
|
1152
|
+
setExpandedNodes(new Set(_chunkBVQYK3TOcjs.getDocAncestorNodeIds.call(void 0, parentPath)));
|
|
1153
1153
|
}
|
|
1154
1154
|
setTimeout(() => {
|
|
1155
1155
|
scrollToContent();
|
|
@@ -1167,7 +1167,7 @@ function useDocumentTree(config, initialPath) {
|
|
|
1167
1167
|
setSelectedPath(cleanInitialPath);
|
|
1168
1168
|
if (cleanInitialPath) {
|
|
1169
1169
|
const parentPath = cleanInitialPath.includes("/") ? cleanInitialPath.substring(0, cleanInitialPath.lastIndexOf("/")) : cleanInitialPath;
|
|
1170
|
-
setExpandedNodes(new Set(
|
|
1170
|
+
setExpandedNodes(new Set(_chunkBVQYK3TOcjs.getDocAncestorNodeIds.call(void 0, parentPath)));
|
|
1171
1171
|
}
|
|
1172
1172
|
setExternalNavCount((n) => n + 1);
|
|
1173
1173
|
}
|
|
@@ -1192,7 +1192,7 @@ function useDocumentTree(config, initialPath) {
|
|
|
1192
1192
|
if (cleanInitialPath) {
|
|
1193
1193
|
const pathForExpansion = cleanInitialPath.includes(".") ? cleanInitialPath.substring(0, cleanInitialPath.lastIndexOf("/")) : cleanInitialPath;
|
|
1194
1194
|
if (pathForExpansion) {
|
|
1195
|
-
setExpandedNodes(new Set(
|
|
1195
|
+
setExpandedNodes(new Set(_chunkBVQYK3TOcjs.getDocAncestorNodeIds.call(void 0, pathForExpansion)));
|
|
1196
1196
|
}
|
|
1197
1197
|
} else if (nodes.length > 0) {
|
|
1198
1198
|
const hasRootReadme = nodes.some((node) => node.type === "file" && node.path === folderIndexFile);
|
|
@@ -1232,7 +1232,7 @@ function useDocumentTree(config, initialPath) {
|
|
|
1232
1232
|
setContent(null);
|
|
1233
1233
|
return;
|
|
1234
1234
|
}
|
|
1235
|
-
const probe =
|
|
1235
|
+
const probe = _chunkBVQYK3TOcjs.findDocNodeByPath.call(void 0, _chunkBVQYK3TOcjs.stripFolderIndexFromPath.call(void 0, path, folderIndexFile), structure);
|
|
1236
1236
|
const probeIsNoReadmeFolder = !!probe && probe.type === "folder" && !probe.hasReadme;
|
|
1237
1237
|
const preStructureFolderLike = structure.length === 0 && !path.endsWith(".md");
|
|
1238
1238
|
if (probeIsNoReadmeFolder || preStructureFolderLike) {
|
|
@@ -1289,7 +1289,7 @@ function useDocumentTree(config, initialPath) {
|
|
|
1289
1289
|
if (selectedPath === "") {
|
|
1290
1290
|
pathToFetch = folderIndexFile;
|
|
1291
1291
|
} else {
|
|
1292
|
-
const node =
|
|
1292
|
+
const node = _chunkBVQYK3TOcjs.findDocNodeByPath.call(void 0, selectedPath, structure);
|
|
1293
1293
|
if (node && node.type === "folder" && !node.hasReadme) {
|
|
1294
1294
|
const firstDocPath = findFirstDocPath(node);
|
|
1295
1295
|
if (!firstDocPath) {
|
|
@@ -1330,16 +1330,16 @@ function useDocumentTree(config, initialPath) {
|
|
|
1330
1330
|
if (node.type === "folder") {
|
|
1331
1331
|
setExpandedNodes((prev) => {
|
|
1332
1332
|
if (prev.has(node.id)) {
|
|
1333
|
-
const ancestorIds =
|
|
1333
|
+
const ancestorIds = _chunkBVQYK3TOcjs.getDocAncestorNodeIds.call(void 0, node.path);
|
|
1334
1334
|
ancestorIds.pop();
|
|
1335
1335
|
return new Set(ancestorIds);
|
|
1336
1336
|
}
|
|
1337
|
-
return new Set(
|
|
1337
|
+
return new Set(_chunkBVQYK3TOcjs.getDocAncestorNodeIds.call(void 0, node.path));
|
|
1338
1338
|
});
|
|
1339
1339
|
} else {
|
|
1340
1340
|
const lastSlash = node.path.lastIndexOf("/");
|
|
1341
1341
|
if (lastSlash > 0) {
|
|
1342
|
-
setExpandedNodes(new Set(
|
|
1342
|
+
setExpandedNodes(new Set(_chunkBVQYK3TOcjs.getDocAncestorNodeIds.call(void 0, node.path.substring(0, lastSlash))));
|
|
1343
1343
|
}
|
|
1344
1344
|
}
|
|
1345
1345
|
lastFetchedPath.current = null;
|
|
@@ -1354,7 +1354,7 @@ function useDocumentTree(config, initialPath) {
|
|
|
1354
1354
|
const hashIndex = path.indexOf("#");
|
|
1355
1355
|
const anchor = hashIndex !== -1 ? path.substring(hashIndex) : "";
|
|
1356
1356
|
const cleanPath = path.replace(/\/$/, "").split("#")[0];
|
|
1357
|
-
const pathForSelection = anchor && _optionalChain([options, 'optionalAccess', _6 => _6.fromInternalLink]) && cleanPath === "" ? selectedPathRef.current :
|
|
1357
|
+
const pathForSelection = anchor && _optionalChain([options, 'optionalAccess', _6 => _6.fromInternalLink]) && cleanPath === "" ? selectedPathRef.current : _chunkBVQYK3TOcjs.stripFolderIndexFromPath.call(void 0, cleanPath, folderIndexFile);
|
|
1358
1358
|
if (anchor && _optionalChain([options, 'optionalAccess', _7 => _7.fromInternalLink]) && pathForSelection === selectedPathRef.current) {
|
|
1359
1359
|
_chunkZI27ALYXcjs.navigateSamePageHash.call(void 0, anchor, { headerOffset: _chunkZI27ALYXcjs.HUB_HEADER_OFFSET_PX });
|
|
1360
1360
|
return;
|
|
@@ -1418,15 +1418,15 @@ function useDocumentTree(config, initialPath) {
|
|
|
1418
1418
|
return docNavigation.register({
|
|
1419
1419
|
baseRoute: normalizedBaseRoute,
|
|
1420
1420
|
findNodeByPath: (path) => {
|
|
1421
|
-
const clean =
|
|
1422
|
-
return _nullishCoalesce(
|
|
1421
|
+
const clean = _chunkBVQYK3TOcjs.stripFolderIndexFromPath.call(void 0, path.replace(/\/$/, "").split("#")[0], folderIndexFile);
|
|
1422
|
+
return _nullishCoalesce(_chunkBVQYK3TOcjs.findDocNodeByPath.call(void 0, clean, structure), () => ( null));
|
|
1423
1423
|
},
|
|
1424
1424
|
selectNode
|
|
1425
1425
|
});
|
|
1426
1426
|
}, [docNavigation, normalizedBaseRoute, structure, selectNode, folderIndexFile]);
|
|
1427
1427
|
const isEmptyFolder = _react.useMemo.call(void 0, () => {
|
|
1428
1428
|
if (!selectedPath || structure.length === 0) return false;
|
|
1429
|
-
const node =
|
|
1429
|
+
const node = _chunkBVQYK3TOcjs.findDocNodeByPath.call(void 0, selectedPath, structure);
|
|
1430
1430
|
return !!node && node.type === "folder" && !node.hasReadme && !findFirstDocPath(node);
|
|
1431
1431
|
}, [selectedPath, structure]);
|
|
1432
1432
|
return {
|
|
@@ -1562,7 +1562,7 @@ function DocViewerContent({
|
|
|
1562
1562
|
label: _nullishCoalesce(_optionalChain([backButton, 'optionalAccess', _16 => _16.label]), () => ( "Back to home")),
|
|
1563
1563
|
onClick: () => router.push(_nullishCoalesce(_optionalChain([backButton, 'optionalAccess', _17 => _17.href]), () => ( "/")))
|
|
1564
1564
|
};
|
|
1565
|
-
const docSearch =
|
|
1565
|
+
const docSearch = _chunkIB7PMKJXcjs.useDocSearch.call(void 0, {
|
|
1566
1566
|
source: chatSource,
|
|
1567
1567
|
baseRoute,
|
|
1568
1568
|
searchEndpoint,
|
|
@@ -1586,7 +1586,7 @@ function DocViewerContent({
|
|
|
1586
1586
|
onResolveLink: resolveLink
|
|
1587
1587
|
});
|
|
1588
1588
|
}, [content, renderContent, navigateToDoc, sourceId, resolveLink]);
|
|
1589
|
-
const selectedNodeDocType = selectedPath && structure.length > 0 ? _optionalChain([
|
|
1589
|
+
const selectedNodeDocType = selectedPath && structure.length > 0 ? _optionalChain([_chunkBVQYK3TOcjs.findDocNodeByPath.call(void 0, selectedPath, structure), 'optionalAccess', _18 => _18.documentType]) : void 0;
|
|
1590
1590
|
const activeDocType = _nullishCoalesce(_optionalChain([content, 'optionalAccess', _19 => _19.documentType]), () => ( selectedNodeDocType));
|
|
1591
1591
|
const isMarkdownContent = !activeDocType || activeDocType === "markdown";
|
|
1592
1592
|
const showStickyNav = isMarkdownContent;
|
|
@@ -1597,9 +1597,9 @@ function DocViewerContent({
|
|
|
1597
1597
|
const containerBgStyle = colorPalette.containerBackground !== "transparent" ? { backgroundColor: colorPalette.containerBackground } : {};
|
|
1598
1598
|
const defaultEmptyText = structure.length > 0 ? "Select a document from the sidebar to view" : "No documents yet. Add content from the admin panel.";
|
|
1599
1599
|
const resolvedEmptyText = emptyStateText || defaultEmptyText;
|
|
1600
|
-
const inner = /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { ...bgStyle, ...containerBgStyle }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1600
|
+
const inner = /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { ...bgStyle, ...containerBgStyle }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBVQYK3TOcjs.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: [
|
|
1601
1601
|
showAIChat && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1602
|
-
|
|
1602
|
+
_chunkIB7PMKJXcjs.DocSearchBar,
|
|
1603
1603
|
{
|
|
1604
1604
|
placeholder: `Search ${_optionalChain([sidebarLabel, 'optionalAccess', _23 => _23.toLowerCase, 'call', _24 => _24()]) || "documents"}...`,
|
|
1605
1605
|
query: docSearch.query,
|
|
@@ -1620,7 +1620,7 @@ function DocViewerContent({
|
|
|
1620
1620
|
!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: [
|
|
1621
1621
|
/* @__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, CategorySidebarSkeleton, {}) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
1622
1622
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, PersistentMobileDropdown, { isLoading: false, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1623
|
-
|
|
1623
|
+
_chunkULZHN4XScjs.MobileNavigationDropdown,
|
|
1624
1624
|
{
|
|
1625
1625
|
nodes: structure,
|
|
1626
1626
|
selectedPath,
|
|
@@ -1634,7 +1634,7 @@ function DocViewerContent({
|
|
|
1634
1634
|
/* @__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: [
|
|
1635
1635
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-semibold text-ods-text-secondary text-h5", children: sidebarLabel }),
|
|
1636
1636
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1637
|
-
|
|
1637
|
+
_chunkULZHN4XScjs.MultiLevelNavigation,
|
|
1638
1638
|
{
|
|
1639
1639
|
nodes: structure,
|
|
1640
1640
|
selectedPath,
|
|
@@ -1673,7 +1673,7 @@ function DocViewerContent({
|
|
|
1673
1673
|
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: [
|
|
1674
1674
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "mb-4 font-semibold text-ods-text-secondary text-h5", children: "ON THIS PAGE" }),
|
|
1675
1675
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1676
|
-
|
|
1676
|
+
_chunkULZHN4XScjs.StickySectionNav,
|
|
1677
1677
|
{
|
|
1678
1678
|
sections: stickyNavSections,
|
|
1679
1679
|
activeSection,
|
|
@@ -1688,7 +1688,7 @@ function DocViewerContent({
|
|
|
1688
1688
|
) })
|
|
1689
1689
|
] })
|
|
1690
1690
|
] }) }) });
|
|
1691
|
-
return shell ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1691
|
+
return shell ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBVQYK3TOcjs.PageShell, { contentClassName: `${bgClass} ${className}`, children: inner }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: `page-shell-content ${bgClass} ${className}`.trim(), children: inner });
|
|
1692
1692
|
}
|
|
1693
1693
|
|
|
1694
1694
|
// src/components/docs/skeletons.tsx
|
|
@@ -1778,11 +1778,11 @@ function EmbedSkeleton({ documentType } = {}) {
|
|
|
1778
1778
|
|
|
1779
1779
|
var DEFAULT_TITLE = "Documents";
|
|
1780
1780
|
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" }) });
|
|
1781
|
-
var defaultPdfRenderer = (content, handlers) => content.fileUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1782
|
-
var defaultGoogleSheetRenderer = (content, handlers) => content.externalUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1783
|
-
var defaultFigmaRenderer = (content, handlers) => content.externalUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1781
|
+
var defaultPdfRenderer = (content, handlers) => content.fileUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7QBSMF3Acjs.PdfViewer, { src: content.fileUrl, fileName: content.fileName }) : defaultFallbackRenderer(content, handlers);
|
|
1782
|
+
var defaultGoogleSheetRenderer = (content, handlers) => content.externalUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7QBSMF3Acjs.GoogleSheetsViewer, { externalUrl: content.externalUrl, fileName: content.fileName }) : defaultFallbackRenderer(content, handlers);
|
|
1783
|
+
var defaultFigmaRenderer = (content, handlers) => content.externalUrl ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBVQYK3TOcjs.FigmaEmbed, { url: content.externalUrl, title: content.fileName, loading: "eager" }) : defaultFallbackRenderer(content, handlers);
|
|
1784
1784
|
var defaultFileRenderer = (content) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1785
|
-
|
|
1785
|
+
_chunk7QBSMF3Acjs.FileDownloadCard,
|
|
1786
1786
|
{
|
|
1787
1787
|
fileName: content.fileName,
|
|
1788
1788
|
mimeType: content.mimeType,
|
|
@@ -1864,4 +1864,4 @@ function DocsHubPage({
|
|
|
1864
1864
|
|
|
1865
1865
|
|
|
1866
1866
|
exports.UnifiedSkeleton = UnifiedSkeleton; exports.TextSkeleton = TextSkeleton; exports.InteractiveSkeleton = InteractiveSkeleton; exports.MediaSkeleton = MediaSkeleton; exports.CardSkeleton = CardSkeleton; exports.CardSkeletonGrid = CardSkeletonGrid; exports.AnnouncementBarSkeleton = AnnouncementBarSkeleton; exports.HeroSkeleton = HeroSkeleton; exports.SearchContainerSkeleton = SearchContainerSkeleton; exports.CategorySidebarSkeleton = CategorySidebarSkeleton; exports.BreadcrumbSkeleton = BreadcrumbSkeleton; exports.ResultsHeaderSkeleton = ResultsHeaderSkeleton; exports.TwoColumnLayoutSkeleton = TwoColumnLayoutSkeleton; exports.ArticleLayoutSkeleton = ArticleLayoutSkeleton; exports.VendorDetailLayoutSkeleton = VendorDetailLayoutSkeleton; exports.StatsSectionSkeleton = StatsSectionSkeleton; exports.BlogCardGridSkeleton = BlogCardGridSkeleton; exports.VendorGridSkeleton = VendorGridSkeleton; exports.SlackCommunitySkeleton = SlackCommunitySkeleton; 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;
|
|
1867
|
-
//# sourceMappingURL=chunk-
|
|
1867
|
+
//# sourceMappingURL=chunk-V3XCLT5V.cjs.map
|