@flamingo-stack/openframe-frontend-core 0.0.454 → 0.0.455-snapshot.20260719161719
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-UGFB5EAW.js → chunk-2I3GN7WW.js} +4 -4
- package/dist/{chunk-44AD5D3C.cjs → chunk-6K6LAD6H.cjs} +18 -18
- package/dist/{chunk-44AD5D3C.cjs.map → chunk-6K6LAD6H.cjs.map} +1 -1
- package/dist/{chunk-UPRY4I63.cjs → chunk-6TI3DCOG.cjs} +3 -3
- package/dist/{chunk-UPRY4I63.cjs.map → chunk-6TI3DCOG.cjs.map} +1 -1
- package/dist/{chunk-YAZIVPUF.cjs → chunk-A7FTNFBX.cjs} +73 -73
- package/dist/{chunk-YAZIVPUF.cjs.map → chunk-A7FTNFBX.cjs.map} +1 -1
- package/dist/{chunk-YJ7SPS7I.js → chunk-DAEKUR3J.js} +2 -2
- package/dist/{chunk-PT233TJV.js → chunk-DU6R7XNU.js} +2 -2
- package/dist/{chunk-OZZ4VQ52.cjs → chunk-DYBATZJP.cjs} +5 -5
- package/dist/{chunk-OZZ4VQ52.cjs.map → chunk-DYBATZJP.cjs.map} +1 -1
- package/dist/{chunk-PB24PKG2.cjs → chunk-F2CCUPKC.cjs} +29 -29
- package/dist/{chunk-PB24PKG2.cjs.map → chunk-F2CCUPKC.cjs.map} +1 -1
- package/dist/{chunk-OGKDOG5D.js → chunk-F3IBBAKV.js} +2 -2
- package/dist/{chunk-IM5A5F2E.cjs → chunk-GC63K4VD.cjs} +73 -73
- package/dist/{chunk-IM5A5F2E.cjs.map → chunk-GC63K4VD.cjs.map} +1 -1
- package/dist/{chunk-N2UFIQAD.cjs → chunk-GQZGCMRF.cjs} +7 -7
- package/dist/{chunk-N2UFIQAD.cjs.map → chunk-GQZGCMRF.cjs.map} +1 -1
- package/dist/{chunk-EQWE64RJ.js → chunk-ILUX3DXS.js} +2 -2
- package/dist/{chunk-NUT3HRKS.cjs → chunk-INH6SIP5.cjs} +12 -12
- package/dist/{chunk-NUT3HRKS.cjs.map → chunk-INH6SIP5.cjs.map} +1 -1
- package/dist/{chunk-QF3NQW7C.cjs → chunk-IOHQJOLR.cjs} +35 -81
- package/dist/chunk-IOHQJOLR.cjs.map +1 -0
- package/dist/{chunk-TMST2WFZ.js → chunk-JHIT44TA.js} +3 -3
- package/dist/{chunk-ACUD4XVZ.cjs → chunk-KH5VTGCS.cjs} +40 -40
- package/dist/{chunk-ACUD4XVZ.cjs.map → chunk-KH5VTGCS.cjs.map} +1 -1
- package/dist/{chunk-MX2ITMKK.js → chunk-LAFCXJVT.js} +5 -5
- package/dist/{chunk-55ISAJFV.js → chunk-LMBPJAQ2.js} +6 -6
- package/dist/{chunk-MLFFBQ5B.js → chunk-MK2YWJAA.js} +98 -144
- package/dist/chunk-MK2YWJAA.js.map +1 -0
- package/dist/{chunk-5HQV2F5K.cjs → chunk-TXS2AMFV.cjs} +32 -32
- package/dist/{chunk-5HQV2F5K.cjs.map → chunk-TXS2AMFV.cjs.map} +1 -1
- package/dist/{chunk-GOWE4WSU.js → chunk-U27TXTAK.js} +6 -6
- package/dist/{chunk-UOTHXOCS.js → chunk-UEKCD6WV.js} +5539 -5559
- package/dist/chunk-UEKCD6WV.js.map +1 -0
- package/dist/{chunk-XH33VG5A.cjs → chunk-UHVVNVUE.cjs} +40 -40
- package/dist/{chunk-XH33VG5A.cjs.map → chunk-UHVVNVUE.cjs.map} +1 -1
- package/dist/{chunk-AJAF456I.js → chunk-UXKSOJR7.js} +3 -3
- package/dist/{chunk-WLUIXASU.cjs → chunk-VZNJ3RYI.cjs} +15 -15
- package/dist/{chunk-WLUIXASU.cjs.map → chunk-VZNJ3RYI.cjs.map} +1 -1
- package/dist/{chunk-YED55PQY.js → chunk-YLTY4Z4B.js} +3 -3
- package/dist/{chunk-72VDY6MM.cjs → chunk-YMGOTPY7.cjs} +1431 -1451
- package/dist/chunk-YMGOTPY7.cjs.map +1 -0
- package/dist/{chunk-JUNKHNWE.js → chunk-ZQHGSR3H.js} +5 -5
- package/dist/components/case-studies/index.cjs +9 -9
- package/dist/components/case-studies/index.js +3 -3
- package/dist/components/chat/chat-message-list.d.ts.map +1 -1
- package/dist/components/chat/embeddable-chat.d.ts.map +1 -1
- package/dist/components/chat/guide-welcome.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +3 -9
- package/dist/components/chat/index.cjs.map +1 -1
- package/dist/components/chat/index.d.ts +0 -2
- package/dist/components/chat/index.d.ts.map +1 -1
- package/dist/components/chat/index.js +2 -8
- package/dist/components/chat/mingo-welcome.d.ts.map +1 -1
- package/dist/components/chat/quick-action-chip.d.ts +48 -0
- package/dist/components/chat/quick-action-chip.d.ts.map +1 -1
- package/dist/components/chat/quick-action-marquee.d.ts.map +1 -1
- package/dist/components/chat/quick-action-wall.d.ts +6 -3
- package/dist/components/chat/quick-action-wall.d.ts.map +1 -1
- package/dist/components/chat/types/component.types.d.ts +17 -12
- package/dist/components/chat/types/component.types.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +4 -4
- package/dist/components/contact/index.js +3 -3
- package/dist/components/docs/index.cjs +6 -6
- package/dist/components/docs/index.js +5 -5
- package/dist/components/embeds/index.cjs +4 -4
- package/dist/components/embeds/index.js +3 -3
- package/dist/components/faq/index.cjs +5 -5
- package/dist/components/faq/index.js +4 -4
- package/dist/components/features/cards-strip.d.ts.map +1 -1
- package/dist/components/features/index.cjs +3 -3
- package/dist/components/features/index.js +2 -2
- package/dist/components/help-center-pages/index.cjs +22 -22
- package/dist/components/help-center-pages/index.js +13 -13
- package/dist/components/index.cjs +135 -141
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +11 -17
- package/dist/components/index.js.map +1 -1
- package/dist/components/navigation/index.cjs +3 -3
- package/dist/components/navigation/index.js +2 -2
- package/dist/components/onboarding-guides/index.cjs +7 -7
- package/dist/components/onboarding-guides/index.js +6 -6
- package/dist/components/related-content/index.cjs +5 -5
- package/dist/components/related-content/index.js +4 -4
- package/dist/components/tickets/index.cjs +6 -6
- package/dist/components/tickets/index.js +5 -5
- package/dist/components/ui/index.cjs +3 -9
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.js +2 -8
- package/dist/components/ui/marquee-wall.d.ts +8 -1
- package/dist/components/ui/marquee-wall.d.ts.map +1 -1
- package/dist/hooks/index.cjs +2 -2
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +3 -3
- package/dist/hooks/ui/index.d.ts +1 -0
- package/dist/hooks/ui/index.d.ts.map +1 -1
- package/dist/hooks/ui/use-reset-on-page-hidden.d.ts +19 -0
- package/dist/hooks/ui/use-reset-on-page-hidden.d.ts.map +1 -0
- package/dist/hooks/use-near-viewport.d.ts +3 -1
- package/dist/hooks/use-near-viewport.d.ts.map +1 -1
- package/dist/index.cjs +3 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -10
- package/package.json +1 -1
- package/src/components/chat/approval-request-message.tsx +1 -1
- package/src/components/chat/chat-context-picker.tsx +1 -1
- package/src/components/chat/chat-input.tsx +1 -1
- package/src/components/chat/chat-message-list.tsx +47 -0
- package/src/components/chat/chat-message-skeleton.tsx +1 -1
- package/src/components/chat/chat-sidebar-skeleton.tsx +1 -1
- package/src/components/chat/chat-sidebar.tsx +2 -2
- package/src/components/chat/chat-ticket-list.tsx +1 -1
- package/src/components/chat/context-items-list.tsx +1 -1
- package/src/components/chat/embeddable-chat.tsx +46 -6
- package/src/components/chat/guide-welcome.tsx +24 -14
- package/src/components/chat/index.ts +0 -2
- package/src/components/chat/mingo-chat-history.tsx +1 -1
- package/src/components/chat/mingo-welcome.tsx +42 -27
- package/src/components/chat/quick-action-chip.tsx +77 -0
- package/src/components/chat/quick-action-marquee.tsx +1 -2
- package/src/components/chat/quick-action-wall.tsx +13 -4
- package/src/components/chat/slash-command-suggestions.tsx +1 -1
- package/src/components/chat/tool-call-blocks.tsx +1 -1
- package/src/components/chat/types/component.types.ts +17 -15
- package/src/components/features/cards-strip.tsx +16 -0
- package/src/components/ui/marquee-wall.tsx +160 -10
- package/src/hooks/.index.md +0 -1
- package/src/hooks/index.ts +0 -1
- package/src/hooks/ui/index.ts +1 -0
- package/src/hooks/ui/use-reset-on-page-hidden.ts +32 -0
- package/src/hooks/use-near-viewport.ts +36 -12
- package/src/stories/ChatContainer.stories.tsx +15 -12
- package/src/stories/QuickActionWall.stories.tsx +1 -2
- package/dist/chunk-72VDY6MM.cjs.map +0 -1
- package/dist/chunk-MLFFBQ5B.js.map +0 -1
- package/dist/chunk-QF3NQW7C.cjs.map +0 -1
- package/dist/chunk-UOTHXOCS.js.map +0 -1
- package/dist/components/chat/chat-quick-action-row.d.ts +0 -84
- package/dist/components/chat/chat-quick-action-row.d.ts.map +0 -1
- package/dist/components/chat/chat-quick-action.d.ts +0 -11
- package/dist/components/chat/chat-quick-action.d.ts.map +0 -1
- package/dist/hooks/use-quick-action-hint.d.ts +0 -25
- package/dist/hooks/use-quick-action-hint.d.ts.map +0 -1
- package/src/components/chat/.chat-quick-action.md +0 -46
- package/src/components/chat/chat-quick-action-row.tsx +0 -282
- package/src/components/chat/chat-quick-action.tsx +0 -59
- package/src/hooks/.use-quick-action-hint.md +0 -43
- package/src/hooks/use-quick-action-hint.ts +0 -126
- /package/dist/{chunk-UGFB5EAW.js.map → chunk-2I3GN7WW.js.map} +0 -0
- /package/dist/{chunk-YJ7SPS7I.js.map → chunk-DAEKUR3J.js.map} +0 -0
- /package/dist/{chunk-PT233TJV.js.map → chunk-DU6R7XNU.js.map} +0 -0
- /package/dist/{chunk-OGKDOG5D.js.map → chunk-F3IBBAKV.js.map} +0 -0
- /package/dist/{chunk-EQWE64RJ.js.map → chunk-ILUX3DXS.js.map} +0 -0
- /package/dist/{chunk-TMST2WFZ.js.map → chunk-JHIT44TA.js.map} +0 -0
- /package/dist/{chunk-MX2ITMKK.js.map → chunk-LAFCXJVT.js.map} +0 -0
- /package/dist/{chunk-55ISAJFV.js.map → chunk-LMBPJAQ2.js.map} +0 -0
- /package/dist/{chunk-GOWE4WSU.js.map → chunk-U27TXTAK.js.map} +0 -0
- /package/dist/{chunk-AJAF456I.js.map → chunk-UXKSOJR7.js.map} +0 -0
- /package/dist/{chunk-YED55PQY.js.map → chunk-YLTY4Z4B.js.map} +0 -0
- /package/dist/{chunk-JUNKHNWE.js.map → chunk-ZQHGSR3H.js.map} +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkYMGOTPY7cjs = require('./chunk-YMGOTPY7.cjs');
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
@@ -59,7 +59,7 @@ function PdfViewer({ src, fileName, onPreview, onDownload, height }) {
|
|
|
59
59
|
)
|
|
60
60
|
] })
|
|
61
61
|
] }),
|
|
62
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
62
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkYMGOTPY7cjs.EmbedIframe, { src, title: displayName, height })
|
|
63
63
|
] });
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -85,7 +85,7 @@ function GoogleSheetsViewer({ externalUrl, fileName, height }) {
|
|
|
85
85
|
{
|
|
86
86
|
variant: "outline",
|
|
87
87
|
size: "small-legacy",
|
|
88
|
-
href:
|
|
88
|
+
href: _chunkYMGOTPY7cjs.toGoogleSheetsOriginalUrl.call(void 0, externalUrl),
|
|
89
89
|
openInNewTab: true,
|
|
90
90
|
leftIcon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBGD345ZVcjs.GoogleSheetsIcon, { className: "w-4 h-4" }),
|
|
91
91
|
rightIcon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ExternalLink, { className: "w-4 h-4" }),
|
|
@@ -95,9 +95,9 @@ function GoogleSheetsViewer({ externalUrl, fileName, height }) {
|
|
|
95
95
|
)
|
|
96
96
|
] }),
|
|
97
97
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
98
|
-
|
|
98
|
+
_chunkYMGOTPY7cjs.EmbedIframe,
|
|
99
99
|
{
|
|
100
|
-
src:
|
|
100
|
+
src: _chunkYMGOTPY7cjs.toGoogleSheetsEmbedUrl.call(void 0, externalUrl),
|
|
101
101
|
title: displayName,
|
|
102
102
|
height
|
|
103
103
|
}
|
|
@@ -120,7 +120,7 @@ function FileDownloadCard({
|
|
|
120
120
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-h3 text-ods-text-primary", children: fileName || "File" }),
|
|
121
121
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-center gap-3 mt-2 text-h6 text-ods-text-secondary", children: [
|
|
122
122
|
mimeType && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: mimeType }),
|
|
123
|
-
typeof fileSize === "number" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children:
|
|
123
|
+
typeof fileSize === "number" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: _chunkYMGOTPY7cjs.formatFileSize.call(void 0, fileSize) })
|
|
124
124
|
] })
|
|
125
125
|
] }),
|
|
126
126
|
fileUrl && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
@@ -141,4 +141,4 @@ function FileDownloadCard({
|
|
|
141
141
|
|
|
142
142
|
|
|
143
143
|
exports.PdfViewer = PdfViewer; exports.GoogleSheetsViewer = GoogleSheetsViewer; exports.FileDownloadCard = FileDownloadCard;
|
|
144
|
-
//# sourceMappingURL=chunk-
|
|
144
|
+
//# sourceMappingURL=chunk-GQZGCMRF.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-N2UFIQAD.cjs","../src/components/embeds/pdf-viewer.tsx","../src/components/embeds/google-sheets-viewer.tsx","../src/components/embeds/file-download-card.tsx"],"names":["jsxs","jsx","Download"],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-N2UFIQAD.cjs","sourcesContent":[null,"\"use client\"\n\nimport React from 'react'\nimport { Button } from '../ui'\nimport { Download, Eye } from 'lucide-react'\nimport { AdobePdfIcon } from '../icons-v2-generated'\nimport { EmbedIframe } from './embed-iframe'\n\nexport interface PdfViewerProps {\n src: string\n fileName?: string\n onPreview?: () => void\n onDownload?: () => void\n height?: string\n}\n\nexport function PdfViewer({ src, fileName, onPreview, onDownload, height }: PdfViewerProps) {\n const displayName = fileName || 'PDF Document'\n\n if (!src) {\n return (\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n <AdobePdfIcon className=\"w-16 h-16 text-ods-text-secondary mb-4\" />\n <p className=\"text-ods-text-secondary\">PDF file not available</p>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <AdobePdfIcon className=\"w-5 h-5 shrink-0\" />\n <h2 className=\"text-h3 text-ods-text-primary truncate\">{displayName}</h2>\n </div>\n <div className=\"flex items-center gap-2 w-full sm:w-auto\">\n <Button\n variant=\"outline\"\n size=\"small-legacy\"\n href={onPreview ? undefined : src}\n openInNewTab={!onPreview}\n onClick={onPreview}\n leftIcon={<Eye className=\"w-4 h-4\" />}\n className=\"flex-1 sm:flex-initial\"\n >\n Preview\n </Button>\n <Button\n variant=\"outline\"\n size=\"small-legacy\"\n href={onDownload ? undefined : src}\n openInNewTab={!onDownload}\n onClick={onDownload}\n leftIcon={<Download className=\"w-4 h-4\" />}\n className=\"flex-1 sm:flex-initial\"\n >\n Download\n </Button>\n </div>\n </div>\n <EmbedIframe src={src} title={displayName} height={height} />\n </div>\n )\n}\n","\"use client\"\n\nimport React from 'react'\nimport { Button } from '../ui'\nimport { ExternalLink } from 'lucide-react'\nimport { GoogleSheetsIcon } from '../icons-v2-generated'\nimport { EmbedIframe } from './embed-iframe'\nimport { toGoogleSheetsEmbedUrl, toGoogleSheetsOriginalUrl } from '../../utils/embed-url-converters'\n\nexport interface GoogleSheetsViewerProps {\n externalUrl: string\n fileName?: string\n height?: string\n}\n\nexport function GoogleSheetsViewer({ externalUrl, fileName, height }: GoogleSheetsViewerProps) {\n const displayName = fileName || 'Google Sheet'\n\n if (!externalUrl) {\n return (\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n <GoogleSheetsIcon className=\"w-16 h-16 text-ods-text-secondary mb-4\" />\n <p className=\"text-ods-text-secondary\">Google Sheet URL not configured</p>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <GoogleSheetsIcon className=\"w-5 h-5 shrink-0\" />\n <h2 className=\"text-h3 text-ods-text-primary truncate\">{displayName}</h2>\n </div>\n <Button\n variant=\"outline\"\n size=\"small-legacy\"\n href={toGoogleSheetsOriginalUrl(externalUrl)}\n openInNewTab\n leftIcon={<GoogleSheetsIcon className=\"w-4 h-4\" />}\n rightIcon={<ExternalLink className=\"w-4 h-4\" />}\n className=\"w-full sm:w-auto\"\n >\n Open in Google Sheets\n </Button>\n </div>\n <EmbedIframe\n src={toGoogleSheetsEmbedUrl(externalUrl)}\n title={displayName}\n height={height}\n />\n </div>\n )\n}\n","import React from 'react'\nimport { Button } from '../ui'\nimport { FileText, Download } from 'lucide-react'\nimport { formatFileSize } from '../../utils'\n\nexport interface FileDownloadCardProps {\n fileName?: string\n mimeType?: string\n fileSize?: number\n fileUrl?: string\n}\n\n/**\n * Generic downloadable-file card for the `file` document type. Used by\n * `<DocsHubPage>`'s default `documentTypeRenderers.file`. Embedders can\n * override the default by passing their own `file` renderer.\n *\n * When `fileUrl` is missing, the Download button is omitted (the card still\n * renders the filename + type + size so the user knows what they were\n * about to download).\n */\nexport function FileDownloadCard({\n fileName,\n mimeType,\n fileSize,\n fileUrl,\n}: FileDownloadCardProps) {\n return (\n <div className=\"flex flex-col items-center justify-center py-16\">\n <div className=\"bg-ods-card border border-ods-border rounded-xl p-8 max-w-md w-full text-center space-y-4\">\n <FileText className=\"w-16 h-16 text-ods-text-secondary mx-auto\" />\n <div>\n <h3 className=\"text-h3 text-ods-text-primary\">\n {fileName || 'File'}\n </h3>\n <div className=\"flex items-center justify-center gap-3 mt-2 text-h6 text-ods-text-secondary\">\n {mimeType && <span>{mimeType}</span>}\n {typeof fileSize === 'number' && <span>{formatFileSize(fileSize)}</span>}\n </div>\n </div>\n {fileUrl && (\n <Button\n variant=\"accent\"\n href={fileUrl}\n openInNewTab\n leftIcon={<Download className=\"w-4 h-4\" />}\n >\n Download File\n </Button>\n )}\n </div>\n </div>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-GQZGCMRF.cjs","../src/components/embeds/pdf-viewer.tsx","../src/components/embeds/google-sheets-viewer.tsx","../src/components/embeds/file-download-card.tsx"],"names":["jsxs","jsx","Download"],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-GQZGCMRF.cjs","sourcesContent":[null,"\"use client\"\n\nimport React from 'react'\nimport { Button } from '../ui'\nimport { Download, Eye } from 'lucide-react'\nimport { AdobePdfIcon } from '../icons-v2-generated'\nimport { EmbedIframe } from './embed-iframe'\n\nexport interface PdfViewerProps {\n src: string\n fileName?: string\n onPreview?: () => void\n onDownload?: () => void\n height?: string\n}\n\nexport function PdfViewer({ src, fileName, onPreview, onDownload, height }: PdfViewerProps) {\n const displayName = fileName || 'PDF Document'\n\n if (!src) {\n return (\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n <AdobePdfIcon className=\"w-16 h-16 text-ods-text-secondary mb-4\" />\n <p className=\"text-ods-text-secondary\">PDF file not available</p>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <AdobePdfIcon className=\"w-5 h-5 shrink-0\" />\n <h2 className=\"text-h3 text-ods-text-primary truncate\">{displayName}</h2>\n </div>\n <div className=\"flex items-center gap-2 w-full sm:w-auto\">\n <Button\n variant=\"outline\"\n size=\"small-legacy\"\n href={onPreview ? undefined : src}\n openInNewTab={!onPreview}\n onClick={onPreview}\n leftIcon={<Eye className=\"w-4 h-4\" />}\n className=\"flex-1 sm:flex-initial\"\n >\n Preview\n </Button>\n <Button\n variant=\"outline\"\n size=\"small-legacy\"\n href={onDownload ? undefined : src}\n openInNewTab={!onDownload}\n onClick={onDownload}\n leftIcon={<Download className=\"w-4 h-4\" />}\n className=\"flex-1 sm:flex-initial\"\n >\n Download\n </Button>\n </div>\n </div>\n <EmbedIframe src={src} title={displayName} height={height} />\n </div>\n )\n}\n","\"use client\"\n\nimport React from 'react'\nimport { Button } from '../ui'\nimport { ExternalLink } from 'lucide-react'\nimport { GoogleSheetsIcon } from '../icons-v2-generated'\nimport { EmbedIframe } from './embed-iframe'\nimport { toGoogleSheetsEmbedUrl, toGoogleSheetsOriginalUrl } from '../../utils/embed-url-converters'\n\nexport interface GoogleSheetsViewerProps {\n externalUrl: string\n fileName?: string\n height?: string\n}\n\nexport function GoogleSheetsViewer({ externalUrl, fileName, height }: GoogleSheetsViewerProps) {\n const displayName = fileName || 'Google Sheet'\n\n if (!externalUrl) {\n return (\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n <GoogleSheetsIcon className=\"w-16 h-16 text-ods-text-secondary mb-4\" />\n <p className=\"text-ods-text-secondary\">Google Sheet URL not configured</p>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <GoogleSheetsIcon className=\"w-5 h-5 shrink-0\" />\n <h2 className=\"text-h3 text-ods-text-primary truncate\">{displayName}</h2>\n </div>\n <Button\n variant=\"outline\"\n size=\"small-legacy\"\n href={toGoogleSheetsOriginalUrl(externalUrl)}\n openInNewTab\n leftIcon={<GoogleSheetsIcon className=\"w-4 h-4\" />}\n rightIcon={<ExternalLink className=\"w-4 h-4\" />}\n className=\"w-full sm:w-auto\"\n >\n Open in Google Sheets\n </Button>\n </div>\n <EmbedIframe\n src={toGoogleSheetsEmbedUrl(externalUrl)}\n title={displayName}\n height={height}\n />\n </div>\n )\n}\n","import React from 'react'\nimport { Button } from '../ui'\nimport { FileText, Download } from 'lucide-react'\nimport { formatFileSize } from '../../utils'\n\nexport interface FileDownloadCardProps {\n fileName?: string\n mimeType?: string\n fileSize?: number\n fileUrl?: string\n}\n\n/**\n * Generic downloadable-file card for the `file` document type. Used by\n * `<DocsHubPage>`'s default `documentTypeRenderers.file`. Embedders can\n * override the default by passing their own `file` renderer.\n *\n * When `fileUrl` is missing, the Download button is omitted (the card still\n * renders the filename + type + size so the user knows what they were\n * about to download).\n */\nexport function FileDownloadCard({\n fileName,\n mimeType,\n fileSize,\n fileUrl,\n}: FileDownloadCardProps) {\n return (\n <div className=\"flex flex-col items-center justify-center py-16\">\n <div className=\"bg-ods-card border border-ods-border rounded-xl p-8 max-w-md w-full text-center space-y-4\">\n <FileText className=\"w-16 h-16 text-ods-text-secondary mx-auto\" />\n <div>\n <h3 className=\"text-h3 text-ods-text-primary\">\n {fileName || 'File'}\n </h3>\n <div className=\"flex items-center justify-center gap-3 mt-2 text-h6 text-ods-text-secondary\">\n {mimeType && <span>{mimeType}</span>}\n {typeof fileSize === 'number' && <span>{formatFileSize(fileSize)}</span>}\n </div>\n </div>\n {fileUrl && (\n <Button\n variant=\"accent\"\n href={fileUrl}\n openInNewTab\n leftIcon={<Download className=\"w-4 h-4\" />}\n >\n Download File\n </Button>\n )}\n </div>\n </div>\n )\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
contentFetch
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MK2YWJAA.js";
|
|
5
5
|
|
|
6
6
|
// src/hooks/use-self-fetch.ts
|
|
7
7
|
import { useEffect, useRef, useState } from "react";
|
|
@@ -78,4 +78,4 @@ function useSelfFetch(url, options) {
|
|
|
78
78
|
export {
|
|
79
79
|
useSelfFetch
|
|
80
80
|
};
|
|
81
|
-
//# sourceMappingURL=chunk-
|
|
81
|
+
//# sourceMappingURL=chunk-ILUX3DXS.js.map
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _chunkYMGOTPY7cjs = require('./chunk-YMGOTPY7.cjs');
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _chunkIOHQJOLRcjs = require('./chunk-IOHQJOLR.cjs');
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
var _chunk2B6773QMcjs = require('./chunk-2B6773QM.cjs');
|
|
@@ -34,7 +34,7 @@ function DocSearchResultRow({
|
|
|
34
34
|
}) {
|
|
35
35
|
const docType = _optionalChain([result, 'access', _ => _.metadata, 'optionalAccess', _2 => _2.documentType]) || void 0;
|
|
36
36
|
const sourceRepo = _optionalChain([result, 'access', _3 => _3.metadata, 'optionalAccess', _4 => _4.sourceRepo]) || void 0;
|
|
37
|
-
const { Icon: SourceIcon, label: iconLabel } =
|
|
37
|
+
const { Icon: SourceIcon, label: iconLabel } = _chunkYMGOTPY7cjs.resolveSourceIcon.call(void 0, {
|
|
38
38
|
sourceRepo,
|
|
39
39
|
documentType: docType
|
|
40
40
|
});
|
|
@@ -77,7 +77,7 @@ function DocSearchBar({
|
|
|
77
77
|
renderResult
|
|
78
78
|
}) {
|
|
79
79
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
80
|
-
|
|
80
|
+
_chunkYMGOTPY7cjs.SearchInput,
|
|
81
81
|
{
|
|
82
82
|
placeholder,
|
|
83
83
|
value: query,
|
|
@@ -186,7 +186,7 @@ function resolveSearchResultAction(result, source, runtimeMode) {
|
|
|
186
186
|
const externalUrl = meta.externalUrl;
|
|
187
187
|
if (externalUrl) {
|
|
188
188
|
const targetPlatform = meta.targetPlatform;
|
|
189
|
-
const isNewTab =
|
|
189
|
+
const isNewTab = _chunkYMGOTPY7cjs.decideNewTab.call(void 0, {
|
|
190
190
|
href: externalUrl,
|
|
191
191
|
targetPlatform,
|
|
192
192
|
surface: "useUnifiedNav",
|
|
@@ -231,7 +231,7 @@ function useDocSearch(config) {
|
|
|
231
231
|
const [query, setQuery] = _react.useState.call(void 0, "");
|
|
232
232
|
const [results, setResults] = _react.useState.call(void 0, []);
|
|
233
233
|
const [isFetching, setIsFetching] = _react.useState.call(void 0, false);
|
|
234
|
-
const debouncedQuery =
|
|
234
|
+
const debouncedQuery = _chunkIOHQJOLRcjs.useDebounce.call(void 0, query, 300);
|
|
235
235
|
_react.useEffect.call(void 0, () => {
|
|
236
236
|
if (!debouncedQuery || debouncedQuery.trim().length < 2) {
|
|
237
237
|
setResults([]);
|
|
@@ -248,7 +248,7 @@ function useDocSearch(config) {
|
|
|
248
248
|
limit: "10"
|
|
249
249
|
});
|
|
250
250
|
if (tableIdsKey) params.set("tableIds", tableIdsKey);
|
|
251
|
-
const response = await
|
|
251
|
+
const response = await _chunkIOHQJOLRcjs.contentFetch.call(void 0, `${resolvedSearchEndpoint}?${params.toString()}`);
|
|
252
252
|
if (!response.ok) {
|
|
253
253
|
throw new Error(`Search request failed: ${response.status}`);
|
|
254
254
|
}
|
|
@@ -288,7 +288,7 @@ function useDocSearch(config) {
|
|
|
288
288
|
if (_optionalChain([runtime, 'optionalAccess', _14 => _14.navigation, 'access', _15 => _15.mode]) === "embed") {
|
|
289
289
|
setKeepOpen(true);
|
|
290
290
|
const targetPlatform = _nullishCoalesce(_optionalChain([result, 'access', _16 => _16.metadata, 'optionalAccess', _17 => _17.targetPlatform]), () => ( null));
|
|
291
|
-
|
|
291
|
+
_chunkYMGOTPY7cjs.resolveExternalNavigation.call(void 0, {
|
|
292
292
|
href: action.href,
|
|
293
293
|
targetPlatform,
|
|
294
294
|
runtime
|
|
@@ -297,18 +297,18 @@ function useDocSearch(config) {
|
|
|
297
297
|
}
|
|
298
298
|
if (wantsNewTab) {
|
|
299
299
|
setKeepOpen(true);
|
|
300
|
-
window.open(action.href, "_blank",
|
|
300
|
+
window.open(action.href, "_blank", _chunkYMGOTPY7cjs.NEW_TAB_FEATURES);
|
|
301
301
|
return;
|
|
302
302
|
}
|
|
303
303
|
setKeepOpen(false);
|
|
304
304
|
const path = baseRoute && action.href.startsWith(`${baseRoute}/`) ? action.href.slice(baseRoute.length + 1) : null;
|
|
305
305
|
if (path && _optionalChain([onInPageSwap, 'optionalCall', _18 => _18(path)])) return;
|
|
306
|
-
router.push(
|
|
306
|
+
router.push(_chunkYMGOTPY7cjs.stripSameOriginToPath.call(void 0, action.href));
|
|
307
307
|
return;
|
|
308
308
|
}
|
|
309
309
|
case "navigate-new-tab":
|
|
310
310
|
setKeepOpen(true);
|
|
311
|
-
window.open(action.href, "_blank",
|
|
311
|
+
window.open(action.href, "_blank", _chunkYMGOTPY7cjs.NEW_TAB_FEATURES);
|
|
312
312
|
return;
|
|
313
313
|
case "ask-ai":
|
|
314
314
|
setKeepOpen(false);
|
|
@@ -347,4 +347,4 @@ function useDocSearch(config) {
|
|
|
347
347
|
|
|
348
348
|
|
|
349
349
|
exports.formatRelativePath = formatRelativePath; exports.DocSearchResultRow = DocSearchResultRow; exports.DocSearchBar = DocSearchBar; exports.mapDocSearchResults = mapDocSearchResults; exports.resolveSearchResultAction = resolveSearchResultAction; exports.useDocSearch = useDocSearch;
|
|
350
|
-
//# sourceMappingURL=chunk-
|
|
350
|
+
//# sourceMappingURL=chunk-INH6SIP5.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-NUT3HRKS.cjs","../src/components/shared/doc-search/format-relative-path.ts","../src/components/shared/doc-search/doc-search-result-row.tsx","../src/components/shared/doc-search/doc-search-bar.tsx","../src/components/shared/doc-search/map-doc-search-results.ts","../src/components/shared/doc-search/resolve-search-result-action.ts","../src/components/shared/doc-search/use-doc-search.ts"],"names":["jsx"],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-NUT3HRKS.cjs","sourcesContent":[null,"/**\n * Format a full document path as a breadcrumb trail.\n * Shows parent folders only (excludes the last segment / filename).\n *\n * @example\n * formatRelativePath('openframe-oss-tenant/architecture/api-controllers.md')\n * // → 'Openframe oss tenant / Architecture'\n */\nexport function formatRelativePath(fullPath: string): string {\n if (!fullPath) return ''\n const segments = fullPath.replace(/\\.md$/, '').split('/')\n // Show only parent path (exclude the filename itself since the title already shows it)\n const parentSegments = segments.length > 1 ? segments.slice(0, -1) : segments\n return parentSegments\n .map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1).replace(/-/g, ' '))\n .join(' / ')\n}\n","'use client'\n\n/**\n * Single row in the `<SearchInput>` dropdown — the standard layout\n * used by every doc-search-backed surface (company-hub data-room\n * search bar, onboarding-guide catalog search, …). Single source of\n * truth for the row appearance so search dropdowns are visually\n * identical everywhere.\n *\n * Resolves the source icon via the same `resolveSourceIcon()`\n * registry the inline chat-card refs use, so a row pointing at e.g.\n * an onboarding-guide surfaces the SAME `<GraduationCap>` glyph the\n * chat card surfaces — no cross-surface drift.\n */\n\nimport { resolveSourceIcon } from '../../chat/utils/source-row-cta'\nimport { formatRelativePath } from './format-relative-path'\n\n/**\n * Minimal result shape this row renders. Compatible with any\n * doc-search hook whose result type exposes `{ title?, path?,\n * metadata? }`. The two hub consumers (onboarding-guide catalog,\n * data-room sidebar) both satisfy this shape via their\n * `useDocSearch` hook result.\n */\nexport interface DocSearchResultRowEntry {\n title?: string\n path?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface DocSearchResultRowProps {\n result: DocSearchResultRowEntry\n isHighlighted: boolean\n}\n\nexport function DocSearchResultRow({\n result,\n isHighlighted,\n}: DocSearchResultRowProps) {\n const docType = (result.metadata?.documentType as string) || undefined\n const sourceRepo = (result.metadata?.sourceRepo as string) || undefined\n const { Icon: SourceIcon, label: iconLabel } = resolveSourceIcon({\n sourceRepo,\n documentType: docType,\n })\n const isGroup = result.metadata?.isGroup as boolean | undefined\n\n return (\n <div className=\"flex items-center gap-3 w-full min-w-0\">\n <span\n className=\"flex-shrink-0 text-ods-text-secondary\"\n title={iconLabel}\n >\n <SourceIcon className=\"size-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div\n className={`text-h6 truncate ${\n isHighlighted ? 'text-ods-accent' : 'text-ods-text-primary'\n }`}\n >\n {result.title || result.path}\n </div>\n {!isGroup && result.path?.includes('/') && (\n <div className=\"text-h6 text-ods-text-secondary truncate mt-0.5\">\n {formatRelativePath(result.path)}\n </div>\n )}\n </div>\n </div>\n )\n}\n","'use client'\n\n/**\n * `<DocSearchBar>` — the canonical RAG-search dropdown surface.\n *\n * Mounted by every doc-search consumer (data-room sidebar, onboarding-\n * guide catalog, and any future surface that needs typeahead against\n * `/api/docs/search`). Wraps `<SearchInput>` with the lib's standard\n * `<DocSearchResultRow>` so the dropdown looks identical everywhere.\n *\n * ## Why a presentation component, not a \"search bar that owns its\n * own hook\"\n *\n * The data-fetching hook (`useDocSearch`) lives hub-side because it\n * depends on hub-only context (`useDocNavigation`, the rag-table-\n * config registry, the hub's `decideNewTab` helper). Moving the hook\n * would cascade ~5 more file migrations into the lib.\n *\n * Instead, the hook stays hub-side and callers pass its result into\n * this component as plain props. Both consumers shrink to ~5 lines.\n */\n\nimport type { ReactNode } from 'react'\nimport { SearchInput, type SearchResult } from '../../ui/search-input'\nimport { DocSearchResultRow } from './doc-search-result-row'\n\nexport interface DocSearchBarProps {\n placeholder: string\n query: string\n onQueryChange: (value: string) => void\n /** Hook-fetched results. Reuses the lib's `<SearchInput>` `SearchResult`\n * shape directly so callers don't translate. */\n results: SearchResult[]\n isLoading: boolean\n /** Result selection handler. Mirrors `<SearchInput>` — the second\n * `modifiers` argument is preserved so cmd-click / shift-click on\n * a result row still forces new-tab behavior. Hub `useDocSearch`\n * reads these to short-circuit to `window.open()`. */\n onResultSelect: (\n result: SearchResult,\n modifiers?: {\n metaKey?: boolean\n ctrlKey?: boolean\n shiftKey?: boolean\n altKey?: boolean\n button?: number\n },\n ) => void\n /** Lets the caller's hook force the dropdown open after a recent\n * internal action (e.g. result navigation). `undefined` falls back\n * to `<SearchInput>`'s built-in focus/hover heuristics. */\n showDropdown?: boolean\n /** Defaults to 2 — matches the existing data-room and onboarding-\n * guide consumers. Override only if a surface needs different\n * typeahead semantics. */\n minQueryLength?: number\n /** Defaults to 0 — both existing consumers debounce inside the\n * hook, not the input. */\n debounceMs?: number\n className?: string\n /** Optional row-renderer override. Defaults to the lib's standard\n * `<DocSearchResultRow>` (source icon + title + path breadcrumb).\n * Override only when a surface needs custom row chrome. */\n renderResult?: (result: SearchResult, isHighlighted: boolean) => ReactNode\n}\n\nexport function DocSearchBar({\n placeholder,\n query,\n onQueryChange,\n results,\n isLoading,\n onResultSelect,\n showDropdown,\n minQueryLength = 2,\n debounceMs = 0,\n className = 'w-full',\n renderResult,\n}: DocSearchBarProps) {\n return (\n <SearchInput\n placeholder={placeholder}\n value={query}\n onChange={onQueryChange}\n results={results}\n isLoading={isLoading}\n onResultSelect={onResultSelect}\n showDropdown={showDropdown || undefined}\n debounceMs={debounceMs}\n minQueryLength={minQueryLength}\n className={className}\n renderResult={\n renderResult ??\n ((result, isHighlighted) => (\n <DocSearchResultRow result={result} isHighlighted={isHighlighted} />\n ))\n }\n />\n )\n}\n","/**\n * Map RAG `/api/docs/search` wire results into the `<DocSearchBar>`\n * dropdown's row shape, collapsing entity-table rows into grouped\n * results so the dropdown lists ONE \"Cap Table (12 records)\" row\n * instead of 12 individual rows.\n *\n * Pure transform — no telemetry, no navigation, no React deps. Lifted\n * from the hub's `hooks/use-docs.ts:mapDocSearchResults` (the hub's\n * `traceCompose` call was hub-only telemetry and is intentionally\n * dropped — callers that want logging can wrap this helper).\n */\n\nimport type { SearchResult } from '../../ui/search-input'\nimport type { DocSearchResult } from './types'\n\n/** Source repos that should be collapsed into grouped results in the search bar.\n * Only financial tables (all rows link to the same admin page).\n * Content tables (blog, webinar, podcast, etc.) stay individual since each has a unique URL. */\nconst SEARCH_GROUP_REPOS = new Set([\n 'financial-cap-table',\n 'financial-kpis',\n 'financial-pnl',\n 'financial-balance-sheet',\n 'financial-cash-flow',\n])\n\nconst ENTITY_LABELS: Record<string, string> = {\n 'financial-cap-table': 'Cap Table',\n 'financial-kpis': 'Financial KPIs',\n 'financial-pnl': 'Profit & Loss',\n 'financial-balance-sheet': 'Balance Sheets',\n 'financial-cash-flow': 'Cash Flow',\n 'blog-posts': 'Blog Posts',\n 'product-releases': 'Product Releases',\n 'case-studies': 'Case Studies',\n webinars: 'Webinars',\n events: 'Events',\n podcasts: 'Podcasts',\n}\n\nexport function mapDocSearchResults(docs: DocSearchResult[]): SearchResult[] {\n const entityGroups = new Map<string, DocSearchResult[]>()\n // Track insertion order — groups appear where the FIRST row of that\n // repo appeared in the response.\n const order: Array<\n { type: 'entity'; repo: string } | { type: 'doc'; doc: DocSearchResult }\n > = []\n const seenRepos = new Set<string>()\n\n for (const doc of docs) {\n if (doc.sourceRepo && SEARCH_GROUP_REPOS.has(doc.sourceRepo)) {\n const group = entityGroups.get(doc.sourceRepo) || []\n group.push(doc)\n entityGroups.set(doc.sourceRepo, group)\n if (!seenRepos.has(doc.sourceRepo)) {\n seenRepos.add(doc.sourceRepo)\n order.push({ type: 'entity', repo: doc.sourceRepo })\n }\n } else {\n order.push({ type: 'doc', doc })\n }\n }\n\n const results: SearchResult[] = []\n for (const entry of order) {\n if (entry.type === 'entity') {\n const rows = entityGroups.get(entry.repo)!\n const label = ENTITY_LABELS[entry.repo] || entry.repo\n results.push({\n id: `group-${entry.repo}`,\n title: `${label} (${rows.length} ${rows.length === 1 ? 'record' : 'records'})`,\n path: rows[0].path,\n type: 'file',\n metadata: {\n documentType: rows[0].documentType,\n externalUrl: rows[0].externalUrl,\n sourceRepo: entry.repo,\n id: rows[0].entityId,\n isGroup: true,\n items: rows.map((r) => ({\n name: r.name,\n externalUrl: r.externalUrl,\n id: r.entityId,\n sourceRepo: r.sourceRepo,\n documentType: r.documentType,\n })),\n },\n })\n } else {\n const doc = entry.doc\n const isNonMarkdown = doc.documentType && doc.documentType !== 'markdown'\n results.push({\n id: doc.path,\n title: doc.name,\n description: isNonMarkdown ? doc.name : doc.snippet,\n path: doc.path,\n type: doc.type,\n metadata: {\n matchType: doc.matchType,\n ...(doc.documentType ? { documentType: doc.documentType } : {}),\n ...(doc.externalUrl ? { externalUrl: doc.externalUrl } : {}),\n ...(doc.targetPlatform != null\n ? { targetPlatform: doc.targetPlatform }\n : {}),\n ...(doc.sourceRepo ? { sourceRepo: doc.sourceRepo } : {}),\n ...(doc.entityId ? { id: doc.entityId } : {}),\n },\n })\n }\n }\n\n return results\n}\n","/**\n * Resolve what should happen when the user picks a search result.\n * Returns one of five typed actions so the caller is a single switch.\n *\n * Resolution order:\n * 1. `externalUrl` present → use `decideNewTab` to choose same-tab vs\n * new-tab against the row's `targetPlatform`.\n * 2. Row has `id` + `sourceRepo` + `documentType` → synth an Ask-AI\n * action (entity drill-in via primary key, no URL).\n * 3. Row has only `path` → legacy navigation fallback.\n * 4. Nothing actionable → noop.\n *\n * Lifted from the hub's `hooks/use-docs.ts:resolveSearchResultAction`.\n * Pure — no React, no telemetry.\n */\n\nimport type { SearchResult } from '../../ui/search-input'\nimport type { ChatRef } from '../../chat/chat-ref.types'\nimport { decideNewTab } from '../../chat/utils/decide-new-tab'\n\nexport type SearchResultAction =\n | { kind: 'navigate-same-tab'; href: string }\n | { kind: 'navigate-new-tab'; href: string }\n | { kind: 'ask-ai'; detail: { source: string; ref: ChatRef } }\n | { kind: 'route'; path: string }\n | { kind: 'noop' }\n\nexport function resolveSearchResultAction(\n result: SearchResult,\n source: string,\n runtimeMode?: 'host' | 'embed',\n): SearchResultAction {\n const meta = result.metadata ?? {}\n const externalUrl = meta.externalUrl as string | undefined\n if (externalUrl) {\n // Same pure helper `useNavLink` and `useUnifiedNav` call — single\n // decision rule across cards, chips, and autocomplete rows. Thread\n // the caller's `source` as `currentSource` so the platform-vs-\n // platform comparison matches the hub's pre-migration behavior.\n const targetPlatform = meta.targetPlatform as string | null | undefined\n const isNewTab = decideNewTab({\n href: externalUrl,\n targetPlatform,\n surface: 'useUnifiedNav',\n runtimeMode,\n currentSource: source,\n })\n return isNewTab\n ? { kind: 'navigate-new-tab', href: externalUrl }\n : { kind: 'navigate-same-tab', href: externalUrl }\n }\n const rowId = meta.id as string | undefined\n const sourceRepo = meta.sourceRepo as string | undefined\n const documentType = meta.documentType as string | undefined\n if (rowId && sourceRepo && documentType) {\n return {\n kind: 'ask-ai',\n detail: {\n source,\n ref: { type: documentType, id: rowId, title: result.title, url: null },\n },\n }\n }\n if (result.path) {\n return { kind: 'route', path: result.path }\n }\n return { kind: 'noop' }\n}\n","'use client'\n\n/**\n * `useDocSearch` — debounced RAG-search hook against `/api/docs/search`.\n *\n * Pure fetch + navigation glue. Embedders can mount this directly\n * (any host with a reverse-proxy that exposes `/api/docs/search` will\n * work). Hub callers wire it into the lib `<DocSearchBar>` for the\n * canonical typeahead dropdown.\n *\n * ## What moved from hub to lib\n *\n * Lifted from `multi-platform-hub/hooks/use-docs.ts:useDocSearch`. Two\n * hub-only concerns are now optional injection points instead of\n * direct imports:\n *\n * - `useDocNavigation()` (hub's in-page doc-tree swap) → optional\n * `onInPageSwap?: (path: string) => boolean` config callback. When\n * present and returns true, the hook treats a same-origin result\n * click as \"handled in-page\"; when absent or returns false, the\n * hook falls back to `onNavigate(path)` (`router.push` on hub,\n * `window.location.assign` on bare embedders).\n * - `traceCompose` (hub-only telemetry) → dropped. The lib has no\n * equivalent runtime-context yet; bring it back when there is one.\n *\n * Everything else (debounce, `useChatRuntime` for embed-mode short-\n * circuit, embed-shim router, the action-resolver + result-mapper) is\n * now lib-resident.\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useRouter } from '../../../embed-shims'\nimport { useDebounce } from '../../../hooks/ui/use-debounce'\nimport { useChatRuntime } from '../../../contexts/chat-runtime-context'\nimport { contentFetch } from '../../../utils/embed-content-fetch'\nimport type { SearchResult } from '../../ui/search-input'\nimport {\n resolveExternalNavigation,\n stripSameOriginToPath,\n NEW_TAB_FEATURES,\n} from '../../chat/utils/chat-nav-resolution'\nimport type { DocSearchResult } from './types'\nimport { mapDocSearchResults } from './map-doc-search-results'\nimport { resolveSearchResultAction } from './resolve-search-result-action'\n\nexport interface UseDocSearchConfig {\n /** Discriminator passed to `/api/docs/search?source=` (e.g.\n * `'openframe'`). Embedders set it to whatever discriminator their\n * reverse-proxy expects. */\n source: string\n /** Base route prefix this search lives under (e.g. `'/onboarding-guides'`).\n * When a result's href starts with `${baseRoute}/`, the hook\n * attempts the optional in-page swap path before falling through\n * to a full nav. */\n baseRoute: string\n /** Imperative navigation fallback. Called when no override\n * (in-page swap, new-tab) applies. Hub callers pass\n * `(path) => router.push(path)`; embedders pass an equivalent. */\n onNavigate: (path: string) => void\n /** Optional `RagTableConfig.id` list to narrow the search to specific\n * tables (e.g. `['onboarding-guides']`). Forwarded to\n * `/api/docs/search?tableIds=…` which intersects with the source's\n * standing set. */\n tableIds?: string[]\n /** Optional in-page swap callback. When the result's href is under\n * `baseRoute` AND this callback returns true, the hook treats the\n * click as handled in-page (no router push). Hub's\n * `<DocumentationSection>` wires this to\n * `useDocNavigation().navigate(path)`. */\n onInPageSwap?: (path: string) => boolean\n /** Optional endpoint override. Defaults to `'/api/docs/search'`\n * (the hub's reverse-proxy route). Embedders with a different\n * path can override. */\n searchEndpoint?: string\n}\n\nexport function useDocSearch(config: UseDocSearchConfig) {\n const {\n source,\n baseRoute,\n onNavigate,\n tableIds,\n onInPageSwap,\n searchEndpoint,\n } = config\n const tableIdsKey = tableIds && tableIds.length > 0 ? tableIds.join(',') : ''\n\n const router = useRouter()\n // Optional chat-runtime read — when present and mode='embed' the\n // search-result row click short-circuits to a new-tab open against\n // the absolutized URL. Null/host preserves today's behavior.\n // Also used as the proxy-prefix fallback for `searchEndpoint`, matching\n // how tickets resolves `findTicketUrl`.\n const runtime = useChatRuntime()\n const resolvedSearchEndpoint =\n searchEndpoint ?? runtime?.endpoints.docsSearchUrl ?? '/api/docs/search'\n\n const [query, setQuery] = useState('')\n const [results, setResults] = useState<SearchResult[]>([])\n const [isFetching, setIsFetching] = useState(false)\n const debouncedQuery = useDebounce(query, 300)\n\n useEffect(() => {\n if (!debouncedQuery || debouncedQuery.trim().length < 2) {\n setResults([])\n setIsFetching(false)\n return\n }\n\n let cancelled = false\n\n async function fetchResults() {\n setIsFetching(true)\n try {\n const params = new URLSearchParams({\n q: debouncedQuery,\n source,\n limit: '10',\n })\n if (tableIdsKey) params.set('tableIds', tableIdsKey)\n\n const response = await contentFetch(`${resolvedSearchEndpoint}?${params.toString()}`)\n if (!response.ok) {\n throw new Error(`Search request failed: ${response.status}`)\n }\n\n const json = await response.json()\n\n if (!cancelled && json.success && Array.isArray(json.data)) {\n const mapped = mapDocSearchResults(json.data as DocSearchResult[])\n setResults(mapped)\n }\n } catch (error) {\n console.error('Doc search error:', error)\n if (!cancelled) {\n setResults([])\n }\n } finally {\n if (!cancelled) {\n setIsFetching(false)\n }\n }\n }\n\n fetchResults()\n\n return () => {\n cancelled = true\n }\n }, [debouncedQuery, source, tableIdsKey, resolvedSearchEndpoint])\n\n // Derived loading state — single source of truth for \"should the\n // dropdown show 'Loading...' instead of 'No results found'\":\n const isLoading =\n query.trim().length >= 2 && (query !== debouncedQuery || isFetching)\n\n // Track whether dropdown should stay open (external link opened in new tab).\n const [keepOpen, setKeepOpen] = useState(false)\n\n const handleResultSelect = useCallback(\n (\n result: SearchResult,\n modifiers?: {\n metaKey?: boolean\n ctrlKey?: boolean\n shiftKey?: boolean\n altKey?: boolean\n button?: number\n },\n ) => {\n const action = resolveSearchResultAction(\n result,\n source,\n runtime?.navigation.mode,\n )\n // Modifier / non-primary mouse click → force new tab regardless of\n // same-tab/new-tab decision. The dropdown row is a `<div>`, not an\n // `<a target=\"_blank\">`, so the browser doesn't background-tab\n // natively on cmd-click. Honor it explicitly here for parity with\n // the anchor-based surfaces (cards, chips, related-content). Plain\n // Enter from the keyboard passes `modifiers === undefined`.\n const wantsNewTab =\n modifiers &&\n (modifiers.metaKey ||\n modifiers.ctrlKey ||\n modifiers.shiftKey ||\n modifiers.altKey ||\n (typeof modifiers.button === 'number' && modifiers.button !== 0))\n switch (action.kind) {\n case 'navigate-same-tab': {\n // Embed-mode short-circuit — autocomplete row clicked while\n // the chat panel is hosted inside an embedding app.\n if (runtime?.navigation.mode === 'embed') {\n setKeepOpen(true)\n const targetPlatform =\n (result.metadata?.targetPlatform as string | null | undefined) ?? null\n resolveExternalNavigation({\n href: action.href,\n targetPlatform,\n runtime,\n }).open()\n return\n }\n if (wantsNewTab) {\n setKeepOpen(true)\n window.open(action.href, '_blank', NEW_TAB_FEATURES)\n return\n }\n // Same-origin click:\n // 1. If the href is under the current doc-tree's baseRoute AND\n // an `onInPageSwap` callback is wired AND returns true →\n // consider in-page swap handled.\n // 2. Otherwise → embed-shim `router.push()` (soft RSC nav on\n // Next.js hosts, window.location.assign on bare hosts).\n setKeepOpen(false)\n const path =\n baseRoute && action.href.startsWith(`${baseRoute}/`)\n ? action.href.slice(baseRoute.length + 1)\n : null\n if (path && onInPageSwap?.(path)) return\n router.push(stripSameOriginToPath(action.href))\n return\n }\n case 'navigate-new-tab':\n // Cross-origin (e.g. clicking a flamingo.run release from\n // product-hub) — open in a new tab. Keep dropdown open so the\n // user can pick another result without re-searching.\n setKeepOpen(true)\n window.open(action.href, '_blank', NEW_TAB_FEATURES)\n return\n case 'ask-ai':\n // Row is searchable-but-not-openable (cap_table positions,\n // financial-kpi snapshots, anything backed by\n // `resolveUrl: () => null`). Dispatch a CustomEvent that\n // GlobalAskAI listens for — opens chat + drills via\n // `entityIdFilter` (primary-key only, same as inline-card Ask).\n setKeepOpen(false)\n window.dispatchEvent(\n new CustomEvent('ask-ai:open-with-ref', { detail: action.detail }),\n )\n return\n case 'route':\n // Final fallback: legacy navigation by path. Hits when a row\n // has neither URL nor pk metadata — a mapper/API regression.\n setKeepOpen(false)\n onNavigate(action.path)\n return\n case 'noop':\n return\n }\n },\n [onNavigate, source, baseRoute, router, onInPageSwap, runtime],\n )\n\n // Reset keepOpen when query changes.\n useEffect(() => {\n setKeepOpen(false)\n }, [query])\n\n return {\n query,\n setQuery,\n results,\n isLoading,\n handleResultSelect,\n keepDropdownOpen: keepOpen,\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-INH6SIP5.cjs","../src/components/shared/doc-search/format-relative-path.ts","../src/components/shared/doc-search/doc-search-result-row.tsx","../src/components/shared/doc-search/doc-search-bar.tsx","../src/components/shared/doc-search/map-doc-search-results.ts","../src/components/shared/doc-search/resolve-search-result-action.ts","../src/components/shared/doc-search/use-doc-search.ts"],"names":["jsx"],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-INH6SIP5.cjs","sourcesContent":[null,"/**\n * Format a full document path as a breadcrumb trail.\n * Shows parent folders only (excludes the last segment / filename).\n *\n * @example\n * formatRelativePath('openframe-oss-tenant/architecture/api-controllers.md')\n * // → 'Openframe oss tenant / Architecture'\n */\nexport function formatRelativePath(fullPath: string): string {\n if (!fullPath) return ''\n const segments = fullPath.replace(/\\.md$/, '').split('/')\n // Show only parent path (exclude the filename itself since the title already shows it)\n const parentSegments = segments.length > 1 ? segments.slice(0, -1) : segments\n return parentSegments\n .map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1).replace(/-/g, ' '))\n .join(' / ')\n}\n","'use client'\n\n/**\n * Single row in the `<SearchInput>` dropdown — the standard layout\n * used by every doc-search-backed surface (company-hub data-room\n * search bar, onboarding-guide catalog search, …). Single source of\n * truth for the row appearance so search dropdowns are visually\n * identical everywhere.\n *\n * Resolves the source icon via the same `resolveSourceIcon()`\n * registry the inline chat-card refs use, so a row pointing at e.g.\n * an onboarding-guide surfaces the SAME `<GraduationCap>` glyph the\n * chat card surfaces — no cross-surface drift.\n */\n\nimport { resolveSourceIcon } from '../../chat/utils/source-row-cta'\nimport { formatRelativePath } from './format-relative-path'\n\n/**\n * Minimal result shape this row renders. Compatible with any\n * doc-search hook whose result type exposes `{ title?, path?,\n * metadata? }`. The two hub consumers (onboarding-guide catalog,\n * data-room sidebar) both satisfy this shape via their\n * `useDocSearch` hook result.\n */\nexport interface DocSearchResultRowEntry {\n title?: string\n path?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface DocSearchResultRowProps {\n result: DocSearchResultRowEntry\n isHighlighted: boolean\n}\n\nexport function DocSearchResultRow({\n result,\n isHighlighted,\n}: DocSearchResultRowProps) {\n const docType = (result.metadata?.documentType as string) || undefined\n const sourceRepo = (result.metadata?.sourceRepo as string) || undefined\n const { Icon: SourceIcon, label: iconLabel } = resolveSourceIcon({\n sourceRepo,\n documentType: docType,\n })\n const isGroup = result.metadata?.isGroup as boolean | undefined\n\n return (\n <div className=\"flex items-center gap-3 w-full min-w-0\">\n <span\n className=\"flex-shrink-0 text-ods-text-secondary\"\n title={iconLabel}\n >\n <SourceIcon className=\"size-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div\n className={`text-h6 truncate ${\n isHighlighted ? 'text-ods-accent' : 'text-ods-text-primary'\n }`}\n >\n {result.title || result.path}\n </div>\n {!isGroup && result.path?.includes('/') && (\n <div className=\"text-h6 text-ods-text-secondary truncate mt-0.5\">\n {formatRelativePath(result.path)}\n </div>\n )}\n </div>\n </div>\n )\n}\n","'use client'\n\n/**\n * `<DocSearchBar>` — the canonical RAG-search dropdown surface.\n *\n * Mounted by every doc-search consumer (data-room sidebar, onboarding-\n * guide catalog, and any future surface that needs typeahead against\n * `/api/docs/search`). Wraps `<SearchInput>` with the lib's standard\n * `<DocSearchResultRow>` so the dropdown looks identical everywhere.\n *\n * ## Why a presentation component, not a \"search bar that owns its\n * own hook\"\n *\n * The data-fetching hook (`useDocSearch`) lives hub-side because it\n * depends on hub-only context (`useDocNavigation`, the rag-table-\n * config registry, the hub's `decideNewTab` helper). Moving the hook\n * would cascade ~5 more file migrations into the lib.\n *\n * Instead, the hook stays hub-side and callers pass its result into\n * this component as plain props. Both consumers shrink to ~5 lines.\n */\n\nimport type { ReactNode } from 'react'\nimport { SearchInput, type SearchResult } from '../../ui/search-input'\nimport { DocSearchResultRow } from './doc-search-result-row'\n\nexport interface DocSearchBarProps {\n placeholder: string\n query: string\n onQueryChange: (value: string) => void\n /** Hook-fetched results. Reuses the lib's `<SearchInput>` `SearchResult`\n * shape directly so callers don't translate. */\n results: SearchResult[]\n isLoading: boolean\n /** Result selection handler. Mirrors `<SearchInput>` — the second\n * `modifiers` argument is preserved so cmd-click / shift-click on\n * a result row still forces new-tab behavior. Hub `useDocSearch`\n * reads these to short-circuit to `window.open()`. */\n onResultSelect: (\n result: SearchResult,\n modifiers?: {\n metaKey?: boolean\n ctrlKey?: boolean\n shiftKey?: boolean\n altKey?: boolean\n button?: number\n },\n ) => void\n /** Lets the caller's hook force the dropdown open after a recent\n * internal action (e.g. result navigation). `undefined` falls back\n * to `<SearchInput>`'s built-in focus/hover heuristics. */\n showDropdown?: boolean\n /** Defaults to 2 — matches the existing data-room and onboarding-\n * guide consumers. Override only if a surface needs different\n * typeahead semantics. */\n minQueryLength?: number\n /** Defaults to 0 — both existing consumers debounce inside the\n * hook, not the input. */\n debounceMs?: number\n className?: string\n /** Optional row-renderer override. Defaults to the lib's standard\n * `<DocSearchResultRow>` (source icon + title + path breadcrumb).\n * Override only when a surface needs custom row chrome. */\n renderResult?: (result: SearchResult, isHighlighted: boolean) => ReactNode\n}\n\nexport function DocSearchBar({\n placeholder,\n query,\n onQueryChange,\n results,\n isLoading,\n onResultSelect,\n showDropdown,\n minQueryLength = 2,\n debounceMs = 0,\n className = 'w-full',\n renderResult,\n}: DocSearchBarProps) {\n return (\n <SearchInput\n placeholder={placeholder}\n value={query}\n onChange={onQueryChange}\n results={results}\n isLoading={isLoading}\n onResultSelect={onResultSelect}\n showDropdown={showDropdown || undefined}\n debounceMs={debounceMs}\n minQueryLength={minQueryLength}\n className={className}\n renderResult={\n renderResult ??\n ((result, isHighlighted) => (\n <DocSearchResultRow result={result} isHighlighted={isHighlighted} />\n ))\n }\n />\n )\n}\n","/**\n * Map RAG `/api/docs/search` wire results into the `<DocSearchBar>`\n * dropdown's row shape, collapsing entity-table rows into grouped\n * results so the dropdown lists ONE \"Cap Table (12 records)\" row\n * instead of 12 individual rows.\n *\n * Pure transform — no telemetry, no navigation, no React deps. Lifted\n * from the hub's `hooks/use-docs.ts:mapDocSearchResults` (the hub's\n * `traceCompose` call was hub-only telemetry and is intentionally\n * dropped — callers that want logging can wrap this helper).\n */\n\nimport type { SearchResult } from '../../ui/search-input'\nimport type { DocSearchResult } from './types'\n\n/** Source repos that should be collapsed into grouped results in the search bar.\n * Only financial tables (all rows link to the same admin page).\n * Content tables (blog, webinar, podcast, etc.) stay individual since each has a unique URL. */\nconst SEARCH_GROUP_REPOS = new Set([\n 'financial-cap-table',\n 'financial-kpis',\n 'financial-pnl',\n 'financial-balance-sheet',\n 'financial-cash-flow',\n])\n\nconst ENTITY_LABELS: Record<string, string> = {\n 'financial-cap-table': 'Cap Table',\n 'financial-kpis': 'Financial KPIs',\n 'financial-pnl': 'Profit & Loss',\n 'financial-balance-sheet': 'Balance Sheets',\n 'financial-cash-flow': 'Cash Flow',\n 'blog-posts': 'Blog Posts',\n 'product-releases': 'Product Releases',\n 'case-studies': 'Case Studies',\n webinars: 'Webinars',\n events: 'Events',\n podcasts: 'Podcasts',\n}\n\nexport function mapDocSearchResults(docs: DocSearchResult[]): SearchResult[] {\n const entityGroups = new Map<string, DocSearchResult[]>()\n // Track insertion order — groups appear where the FIRST row of that\n // repo appeared in the response.\n const order: Array<\n { type: 'entity'; repo: string } | { type: 'doc'; doc: DocSearchResult }\n > = []\n const seenRepos = new Set<string>()\n\n for (const doc of docs) {\n if (doc.sourceRepo && SEARCH_GROUP_REPOS.has(doc.sourceRepo)) {\n const group = entityGroups.get(doc.sourceRepo) || []\n group.push(doc)\n entityGroups.set(doc.sourceRepo, group)\n if (!seenRepos.has(doc.sourceRepo)) {\n seenRepos.add(doc.sourceRepo)\n order.push({ type: 'entity', repo: doc.sourceRepo })\n }\n } else {\n order.push({ type: 'doc', doc })\n }\n }\n\n const results: SearchResult[] = []\n for (const entry of order) {\n if (entry.type === 'entity') {\n const rows = entityGroups.get(entry.repo)!\n const label = ENTITY_LABELS[entry.repo] || entry.repo\n results.push({\n id: `group-${entry.repo}`,\n title: `${label} (${rows.length} ${rows.length === 1 ? 'record' : 'records'})`,\n path: rows[0].path,\n type: 'file',\n metadata: {\n documentType: rows[0].documentType,\n externalUrl: rows[0].externalUrl,\n sourceRepo: entry.repo,\n id: rows[0].entityId,\n isGroup: true,\n items: rows.map((r) => ({\n name: r.name,\n externalUrl: r.externalUrl,\n id: r.entityId,\n sourceRepo: r.sourceRepo,\n documentType: r.documentType,\n })),\n },\n })\n } else {\n const doc = entry.doc\n const isNonMarkdown = doc.documentType && doc.documentType !== 'markdown'\n results.push({\n id: doc.path,\n title: doc.name,\n description: isNonMarkdown ? doc.name : doc.snippet,\n path: doc.path,\n type: doc.type,\n metadata: {\n matchType: doc.matchType,\n ...(doc.documentType ? { documentType: doc.documentType } : {}),\n ...(doc.externalUrl ? { externalUrl: doc.externalUrl } : {}),\n ...(doc.targetPlatform != null\n ? { targetPlatform: doc.targetPlatform }\n : {}),\n ...(doc.sourceRepo ? { sourceRepo: doc.sourceRepo } : {}),\n ...(doc.entityId ? { id: doc.entityId } : {}),\n },\n })\n }\n }\n\n return results\n}\n","/**\n * Resolve what should happen when the user picks a search result.\n * Returns one of five typed actions so the caller is a single switch.\n *\n * Resolution order:\n * 1. `externalUrl` present → use `decideNewTab` to choose same-tab vs\n * new-tab against the row's `targetPlatform`.\n * 2. Row has `id` + `sourceRepo` + `documentType` → synth an Ask-AI\n * action (entity drill-in via primary key, no URL).\n * 3. Row has only `path` → legacy navigation fallback.\n * 4. Nothing actionable → noop.\n *\n * Lifted from the hub's `hooks/use-docs.ts:resolveSearchResultAction`.\n * Pure — no React, no telemetry.\n */\n\nimport type { SearchResult } from '../../ui/search-input'\nimport type { ChatRef } from '../../chat/chat-ref.types'\nimport { decideNewTab } from '../../chat/utils/decide-new-tab'\n\nexport type SearchResultAction =\n | { kind: 'navigate-same-tab'; href: string }\n | { kind: 'navigate-new-tab'; href: string }\n | { kind: 'ask-ai'; detail: { source: string; ref: ChatRef } }\n | { kind: 'route'; path: string }\n | { kind: 'noop' }\n\nexport function resolveSearchResultAction(\n result: SearchResult,\n source: string,\n runtimeMode?: 'host' | 'embed',\n): SearchResultAction {\n const meta = result.metadata ?? {}\n const externalUrl = meta.externalUrl as string | undefined\n if (externalUrl) {\n // Same pure helper `useNavLink` and `useUnifiedNav` call — single\n // decision rule across cards, chips, and autocomplete rows. Thread\n // the caller's `source` as `currentSource` so the platform-vs-\n // platform comparison matches the hub's pre-migration behavior.\n const targetPlatform = meta.targetPlatform as string | null | undefined\n const isNewTab = decideNewTab({\n href: externalUrl,\n targetPlatform,\n surface: 'useUnifiedNav',\n runtimeMode,\n currentSource: source,\n })\n return isNewTab\n ? { kind: 'navigate-new-tab', href: externalUrl }\n : { kind: 'navigate-same-tab', href: externalUrl }\n }\n const rowId = meta.id as string | undefined\n const sourceRepo = meta.sourceRepo as string | undefined\n const documentType = meta.documentType as string | undefined\n if (rowId && sourceRepo && documentType) {\n return {\n kind: 'ask-ai',\n detail: {\n source,\n ref: { type: documentType, id: rowId, title: result.title, url: null },\n },\n }\n }\n if (result.path) {\n return { kind: 'route', path: result.path }\n }\n return { kind: 'noop' }\n}\n","'use client'\n\n/**\n * `useDocSearch` — debounced RAG-search hook against `/api/docs/search`.\n *\n * Pure fetch + navigation glue. Embedders can mount this directly\n * (any host with a reverse-proxy that exposes `/api/docs/search` will\n * work). Hub callers wire it into the lib `<DocSearchBar>` for the\n * canonical typeahead dropdown.\n *\n * ## What moved from hub to lib\n *\n * Lifted from `multi-platform-hub/hooks/use-docs.ts:useDocSearch`. Two\n * hub-only concerns are now optional injection points instead of\n * direct imports:\n *\n * - `useDocNavigation()` (hub's in-page doc-tree swap) → optional\n * `onInPageSwap?: (path: string) => boolean` config callback. When\n * present and returns true, the hook treats a same-origin result\n * click as \"handled in-page\"; when absent or returns false, the\n * hook falls back to `onNavigate(path)` (`router.push` on hub,\n * `window.location.assign` on bare embedders).\n * - `traceCompose` (hub-only telemetry) → dropped. The lib has no\n * equivalent runtime-context yet; bring it back when there is one.\n *\n * Everything else (debounce, `useChatRuntime` for embed-mode short-\n * circuit, embed-shim router, the action-resolver + result-mapper) is\n * now lib-resident.\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useRouter } from '../../../embed-shims'\nimport { useDebounce } from '../../../hooks/ui/use-debounce'\nimport { useChatRuntime } from '../../../contexts/chat-runtime-context'\nimport { contentFetch } from '../../../utils/embed-content-fetch'\nimport type { SearchResult } from '../../ui/search-input'\nimport {\n resolveExternalNavigation,\n stripSameOriginToPath,\n NEW_TAB_FEATURES,\n} from '../../chat/utils/chat-nav-resolution'\nimport type { DocSearchResult } from './types'\nimport { mapDocSearchResults } from './map-doc-search-results'\nimport { resolveSearchResultAction } from './resolve-search-result-action'\n\nexport interface UseDocSearchConfig {\n /** Discriminator passed to `/api/docs/search?source=` (e.g.\n * `'openframe'`). Embedders set it to whatever discriminator their\n * reverse-proxy expects. */\n source: string\n /** Base route prefix this search lives under (e.g. `'/onboarding-guides'`).\n * When a result's href starts with `${baseRoute}/`, the hook\n * attempts the optional in-page swap path before falling through\n * to a full nav. */\n baseRoute: string\n /** Imperative navigation fallback. Called when no override\n * (in-page swap, new-tab) applies. Hub callers pass\n * `(path) => router.push(path)`; embedders pass an equivalent. */\n onNavigate: (path: string) => void\n /** Optional `RagTableConfig.id` list to narrow the search to specific\n * tables (e.g. `['onboarding-guides']`). Forwarded to\n * `/api/docs/search?tableIds=…` which intersects with the source's\n * standing set. */\n tableIds?: string[]\n /** Optional in-page swap callback. When the result's href is under\n * `baseRoute` AND this callback returns true, the hook treats the\n * click as handled in-page (no router push). Hub's\n * `<DocumentationSection>` wires this to\n * `useDocNavigation().navigate(path)`. */\n onInPageSwap?: (path: string) => boolean\n /** Optional endpoint override. Defaults to `'/api/docs/search'`\n * (the hub's reverse-proxy route). Embedders with a different\n * path can override. */\n searchEndpoint?: string\n}\n\nexport function useDocSearch(config: UseDocSearchConfig) {\n const {\n source,\n baseRoute,\n onNavigate,\n tableIds,\n onInPageSwap,\n searchEndpoint,\n } = config\n const tableIdsKey = tableIds && tableIds.length > 0 ? tableIds.join(',') : ''\n\n const router = useRouter()\n // Optional chat-runtime read — when present and mode='embed' the\n // search-result row click short-circuits to a new-tab open against\n // the absolutized URL. Null/host preserves today's behavior.\n // Also used as the proxy-prefix fallback for `searchEndpoint`, matching\n // how tickets resolves `findTicketUrl`.\n const runtime = useChatRuntime()\n const resolvedSearchEndpoint =\n searchEndpoint ?? runtime?.endpoints.docsSearchUrl ?? '/api/docs/search'\n\n const [query, setQuery] = useState('')\n const [results, setResults] = useState<SearchResult[]>([])\n const [isFetching, setIsFetching] = useState(false)\n const debouncedQuery = useDebounce(query, 300)\n\n useEffect(() => {\n if (!debouncedQuery || debouncedQuery.trim().length < 2) {\n setResults([])\n setIsFetching(false)\n return\n }\n\n let cancelled = false\n\n async function fetchResults() {\n setIsFetching(true)\n try {\n const params = new URLSearchParams({\n q: debouncedQuery,\n source,\n limit: '10',\n })\n if (tableIdsKey) params.set('tableIds', tableIdsKey)\n\n const response = await contentFetch(`${resolvedSearchEndpoint}?${params.toString()}`)\n if (!response.ok) {\n throw new Error(`Search request failed: ${response.status}`)\n }\n\n const json = await response.json()\n\n if (!cancelled && json.success && Array.isArray(json.data)) {\n const mapped = mapDocSearchResults(json.data as DocSearchResult[])\n setResults(mapped)\n }\n } catch (error) {\n console.error('Doc search error:', error)\n if (!cancelled) {\n setResults([])\n }\n } finally {\n if (!cancelled) {\n setIsFetching(false)\n }\n }\n }\n\n fetchResults()\n\n return () => {\n cancelled = true\n }\n }, [debouncedQuery, source, tableIdsKey, resolvedSearchEndpoint])\n\n // Derived loading state — single source of truth for \"should the\n // dropdown show 'Loading...' instead of 'No results found'\":\n const isLoading =\n query.trim().length >= 2 && (query !== debouncedQuery || isFetching)\n\n // Track whether dropdown should stay open (external link opened in new tab).\n const [keepOpen, setKeepOpen] = useState(false)\n\n const handleResultSelect = useCallback(\n (\n result: SearchResult,\n modifiers?: {\n metaKey?: boolean\n ctrlKey?: boolean\n shiftKey?: boolean\n altKey?: boolean\n button?: number\n },\n ) => {\n const action = resolveSearchResultAction(\n result,\n source,\n runtime?.navigation.mode,\n )\n // Modifier / non-primary mouse click → force new tab regardless of\n // same-tab/new-tab decision. The dropdown row is a `<div>`, not an\n // `<a target=\"_blank\">`, so the browser doesn't background-tab\n // natively on cmd-click. Honor it explicitly here for parity with\n // the anchor-based surfaces (cards, chips, related-content). Plain\n // Enter from the keyboard passes `modifiers === undefined`.\n const wantsNewTab =\n modifiers &&\n (modifiers.metaKey ||\n modifiers.ctrlKey ||\n modifiers.shiftKey ||\n modifiers.altKey ||\n (typeof modifiers.button === 'number' && modifiers.button !== 0))\n switch (action.kind) {\n case 'navigate-same-tab': {\n // Embed-mode short-circuit — autocomplete row clicked while\n // the chat panel is hosted inside an embedding app.\n if (runtime?.navigation.mode === 'embed') {\n setKeepOpen(true)\n const targetPlatform =\n (result.metadata?.targetPlatform as string | null | undefined) ?? null\n resolveExternalNavigation({\n href: action.href,\n targetPlatform,\n runtime,\n }).open()\n return\n }\n if (wantsNewTab) {\n setKeepOpen(true)\n window.open(action.href, '_blank', NEW_TAB_FEATURES)\n return\n }\n // Same-origin click:\n // 1. If the href is under the current doc-tree's baseRoute AND\n // an `onInPageSwap` callback is wired AND returns true →\n // consider in-page swap handled.\n // 2. Otherwise → embed-shim `router.push()` (soft RSC nav on\n // Next.js hosts, window.location.assign on bare hosts).\n setKeepOpen(false)\n const path =\n baseRoute && action.href.startsWith(`${baseRoute}/`)\n ? action.href.slice(baseRoute.length + 1)\n : null\n if (path && onInPageSwap?.(path)) return\n router.push(stripSameOriginToPath(action.href))\n return\n }\n case 'navigate-new-tab':\n // Cross-origin (e.g. clicking a flamingo.run release from\n // product-hub) — open in a new tab. Keep dropdown open so the\n // user can pick another result without re-searching.\n setKeepOpen(true)\n window.open(action.href, '_blank', NEW_TAB_FEATURES)\n return\n case 'ask-ai':\n // Row is searchable-but-not-openable (cap_table positions,\n // financial-kpi snapshots, anything backed by\n // `resolveUrl: () => null`). Dispatch a CustomEvent that\n // GlobalAskAI listens for — opens chat + drills via\n // `entityIdFilter` (primary-key only, same as inline-card Ask).\n setKeepOpen(false)\n window.dispatchEvent(\n new CustomEvent('ask-ai:open-with-ref', { detail: action.detail }),\n )\n return\n case 'route':\n // Final fallback: legacy navigation by path. Hits when a row\n // has neither URL nor pk metadata — a mapper/API regression.\n setKeepOpen(false)\n onNavigate(action.path)\n return\n case 'noop':\n return\n }\n },\n [onNavigate, source, baseRoute, router, onInPageSwap, runtime],\n )\n\n // Reset keepOpen when query changes.\n useEffect(() => {\n setKeepOpen(false)\n }, [query])\n\n return {\n query,\n setQuery,\n results,\n isLoading,\n handleResultSelect,\n keepDropdownOpen: keepOpen,\n }\n}\n"]}
|
|
@@ -889,6 +889,22 @@ function useOnboardingState(storageKey = "openframe-onboarding-state") {
|
|
|
889
889
|
};
|
|
890
890
|
}
|
|
891
891
|
|
|
892
|
+
// src/hooks/ui/use-reset-on-page-hidden.ts
|
|
893
|
+
|
|
894
|
+
function useResetOnPageHidden(reset) {
|
|
895
|
+
_react.useEffect.call(void 0, () => {
|
|
896
|
+
const onVisibility = () => {
|
|
897
|
+
if (document.visibilityState === "hidden") reset();
|
|
898
|
+
};
|
|
899
|
+
window.addEventListener("blur", reset);
|
|
900
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
901
|
+
return () => {
|
|
902
|
+
window.removeEventListener("blur", reset);
|
|
903
|
+
document.removeEventListener("visibilitychange", onVisibility);
|
|
904
|
+
};
|
|
905
|
+
}, [reset]);
|
|
906
|
+
}
|
|
907
|
+
|
|
892
908
|
// src/hooks/ui/use-search.ts
|
|
893
909
|
|
|
894
910
|
function useSearch(config) {
|
|
@@ -2009,75 +2025,6 @@ function useContactSubmission(options = {}) {
|
|
|
2009
2025
|
return { submit, isSubmitting, isSuccess, setIsSuccess };
|
|
2010
2026
|
}
|
|
2011
2027
|
|
|
2012
|
-
// src/hooks/use-quick-action-hint.ts
|
|
2013
|
-
|
|
2014
|
-
function useQuickActionHint({
|
|
2015
|
-
actionCount,
|
|
2016
|
-
cycleDuration = 5e3,
|
|
2017
|
-
enabled = true
|
|
2018
|
-
}) {
|
|
2019
|
-
const [activeHintIndex, setActiveHintIndex] = _react.useState.call(void 0, -1);
|
|
2020
|
-
const containerRef = _react.useRef.call(void 0, null);
|
|
2021
|
-
const timeoutRef = _react.useRef.call(void 0, null);
|
|
2022
|
-
const cycleCountRef = _react.useRef.call(void 0, 0);
|
|
2023
|
-
const currentIndexRef = _react.useRef.call(void 0, 0);
|
|
2024
|
-
const sequenceRef = _react.useRef.call(void 0, []);
|
|
2025
|
-
const shuffleIndices = _react.useCallback.call(void 0, (length) => {
|
|
2026
|
-
const indices = Array.from({ length }, (_, i) => i);
|
|
2027
|
-
for (let i = indices.length - 1; i > 0; i--) {
|
|
2028
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
2029
|
-
[indices[i], indices[j]] = [indices[j], indices[i]];
|
|
2030
|
-
}
|
|
2031
|
-
return indices;
|
|
2032
|
-
}, []);
|
|
2033
|
-
const stopHint = _react.useCallback.call(void 0, () => {
|
|
2034
|
-
if (timeoutRef.current) {
|
|
2035
|
-
clearTimeout(timeoutRef.current);
|
|
2036
|
-
timeoutRef.current = null;
|
|
2037
|
-
}
|
|
2038
|
-
setActiveHintIndex(-1);
|
|
2039
|
-
cycleCountRef.current = 0;
|
|
2040
|
-
currentIndexRef.current = 0;
|
|
2041
|
-
sequenceRef.current = [];
|
|
2042
|
-
}, []);
|
|
2043
|
-
const advanceHint = _react.useCallback.call(void 0, () => {
|
|
2044
|
-
if (currentIndexRef.current === 0) {
|
|
2045
|
-
sequenceRef.current = shuffleIndices(actionCount);
|
|
2046
|
-
}
|
|
2047
|
-
const nextIndex = sequenceRef.current[currentIndexRef.current];
|
|
2048
|
-
setActiveHintIndex(nextIndex);
|
|
2049
|
-
currentIndexRef.current++;
|
|
2050
|
-
if (currentIndexRef.current >= actionCount) {
|
|
2051
|
-
currentIndexRef.current = 0;
|
|
2052
|
-
cycleCountRef.current++;
|
|
2053
|
-
}
|
|
2054
|
-
timeoutRef.current = setTimeout(advanceHint, cycleDuration);
|
|
2055
|
-
}, [actionCount, cycleDuration, shuffleIndices]);
|
|
2056
|
-
_react.useEffect.call(void 0, () => {
|
|
2057
|
-
if (!enabled || actionCount === 0) {
|
|
2058
|
-
return;
|
|
2059
|
-
}
|
|
2060
|
-
if (typeof window !== "undefined") {
|
|
2061
|
-
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
2062
|
-
if (prefersReducedMotion) return;
|
|
2063
|
-
}
|
|
2064
|
-
const startTimeout = setTimeout(() => {
|
|
2065
|
-
cycleCountRef.current = 0;
|
|
2066
|
-
currentIndexRef.current = 0;
|
|
2067
|
-
advanceHint();
|
|
2068
|
-
}, 500);
|
|
2069
|
-
return () => {
|
|
2070
|
-
clearTimeout(startTimeout);
|
|
2071
|
-
stopHint();
|
|
2072
|
-
};
|
|
2073
|
-
}, [enabled, actionCount, advanceHint, stopHint]);
|
|
2074
|
-
return {
|
|
2075
|
-
activeHintIndex,
|
|
2076
|
-
stopHint,
|
|
2077
|
-
containerRef
|
|
2078
|
-
};
|
|
2079
|
-
}
|
|
2080
|
-
|
|
2081
2028
|
// src/hooks/use-copy-to-clipboard.ts
|
|
2082
2029
|
|
|
2083
2030
|
function useCopyToClipboard({
|
|
@@ -3327,13 +3274,19 @@ function useNatsClient(clientOptions, options = {}) {
|
|
|
3327
3274
|
|
|
3328
3275
|
var observers = /* @__PURE__ */ new Map();
|
|
3329
3276
|
var subscribers = /* @__PURE__ */ new WeakMap();
|
|
3330
|
-
|
|
3331
|
-
|
|
3277
|
+
var THRESHOLD_EPSILON = 0.01;
|
|
3278
|
+
function observerKey(rootMargin, threshold) {
|
|
3279
|
+
return `${rootMargin}|${threshold}`;
|
|
3280
|
+
}
|
|
3281
|
+
function getObserverFor(rootMargin, threshold) {
|
|
3282
|
+
const key = observerKey(rootMargin, threshold);
|
|
3283
|
+
const existing = observers.get(key);
|
|
3332
3284
|
if (existing) return existing;
|
|
3333
3285
|
const io = new IntersectionObserver(
|
|
3334
3286
|
(entries) => {
|
|
3335
3287
|
entries.forEach((entry) => {
|
|
3336
3288
|
if (!entry.isIntersecting) return;
|
|
3289
|
+
if (entry.intersectionRatio < threshold - THRESHOLD_EPSILON) return;
|
|
3337
3290
|
const cb = subscribers.get(entry.target);
|
|
3338
3291
|
if (cb) {
|
|
3339
3292
|
cb();
|
|
@@ -3342,15 +3295,16 @@ function getObserverFor(rootMargin) {
|
|
|
3342
3295
|
}
|
|
3343
3296
|
});
|
|
3344
3297
|
},
|
|
3345
|
-
{ rootMargin }
|
|
3298
|
+
{ rootMargin, threshold }
|
|
3346
3299
|
);
|
|
3347
|
-
observers.set(
|
|
3300
|
+
observers.set(key, io);
|
|
3348
3301
|
return io;
|
|
3349
3302
|
}
|
|
3350
3303
|
var NEAR_VIEWPORT_ROOT_MARGIN = "500px";
|
|
3351
|
-
function useNearViewport(rootMargin = NEAR_VIEWPORT_ROOT_MARGIN) {
|
|
3304
|
+
function useNearViewport(rootMargin = NEAR_VIEWPORT_ROOT_MARGIN, threshold = 0) {
|
|
3352
3305
|
const [isNear, setIsNear] = _react.useState.call(void 0, false);
|
|
3353
3306
|
const elRef = _react.useRef.call(void 0, null);
|
|
3307
|
+
const key = observerKey(rootMargin, threshold);
|
|
3354
3308
|
const ref = _react.useCallback.call(void 0,
|
|
3355
3309
|
(node) => {
|
|
3356
3310
|
const prev = elRef.current;
|
|
@@ -3358,16 +3312,16 @@ function useNearViewport(rootMargin = NEAR_VIEWPORT_ROOT_MARGIN) {
|
|
|
3358
3312
|
const stillOurs = subscribers.get(prev);
|
|
3359
3313
|
if (stillOurs) {
|
|
3360
3314
|
subscribers.delete(prev);
|
|
3361
|
-
_optionalChain([observers, 'access', _47 => _47.get, 'call', _48 => _48(
|
|
3315
|
+
_optionalChain([observers, 'access', _47 => _47.get, 'call', _48 => _48(key), 'optionalAccess', _49 => _49.unobserve, 'call', _50 => _50(prev)]);
|
|
3362
3316
|
}
|
|
3363
3317
|
}
|
|
3364
3318
|
elRef.current = node;
|
|
3365
3319
|
if (!node) return;
|
|
3366
3320
|
const cb = () => setIsNear(true);
|
|
3367
3321
|
subscribers.set(node, cb);
|
|
3368
|
-
getObserverFor(rootMargin).observe(node);
|
|
3322
|
+
getObserverFor(rootMargin, threshold).observe(node);
|
|
3369
3323
|
},
|
|
3370
|
-
[rootMargin]
|
|
3324
|
+
[key, rootMargin, threshold]
|
|
3371
3325
|
);
|
|
3372
3326
|
_react.useEffect.call(void 0, () => {
|
|
3373
3327
|
return () => {
|
|
@@ -3375,10 +3329,10 @@ function useNearViewport(rootMargin = NEAR_VIEWPORT_ROOT_MARGIN) {
|
|
|
3375
3329
|
if (!el) return;
|
|
3376
3330
|
if (subscribers.get(el)) {
|
|
3377
3331
|
subscribers.delete(el);
|
|
3378
|
-
_optionalChain([observers, 'access', _51 => _51.get, 'call', _52 => _52(
|
|
3332
|
+
_optionalChain([observers, 'access', _51 => _51.get, 'call', _52 => _52(key), 'optionalAccess', _53 => _53.unobserve, 'call', _54 => _54(el)]);
|
|
3379
3333
|
}
|
|
3380
3334
|
};
|
|
3381
|
-
}, [
|
|
3335
|
+
}, [key]);
|
|
3382
3336
|
return { ref, isNear };
|
|
3383
3337
|
}
|
|
3384
3338
|
|
|
@@ -3863,5 +3817,5 @@ function useHumanitySignals() {
|
|
|
3863
3817
|
|
|
3864
3818
|
|
|
3865
3819
|
|
|
3866
|
-
exports.useAutoLimitTags = useAutoLimitTags; exports.useDebounce = useDebounce; exports.useDeferredError = useDeferredError; exports.useFocusTrap = useFocusTrap; exports.useHeaderHeight = useHeaderHeight; exports.useHorizontalScrollbar = useHorizontalScrollbar; exports.useImageEdgeColor = useImageEdgeColor; exports.useLocalStorage = useLocalStorage; exports.useMarqueeEngine = useMarqueeEngine; exports.useMediaQuery = useMediaQuery; exports.breakpoints = breakpoints; exports.useSmUp = useSmUp; exports.useMdUp = useMdUp; exports.useLgUp = useLgUp; exports.useMemoizedCallback = useMemoizedCallback; exports.useNotificationPermission = useNotificationPermission; exports.useOnboardingState = useOnboardingState; exports.useSearch = useSearch; exports.useSuppressCloneFocus = useSuppressCloneFocus; exports.useTablePagination = useTablePagination; exports.useThrottle = useThrottle; exports.useWindowSize = useWindowSize; exports.usePreventScroll = _overlays.usePreventScroll; exports.platformIcons = platformIcons; exports.platformColors = platformColors; exports.platformDisplayNames = platformDisplayNames; exports.platformDescriptions = platformDescriptions; exports.platformSlogans = platformSlogans; exports.platformHexColors = platformHexColors; exports.platformIconNames = platformIconNames; exports.getDefaultColorForPlatform = getDefaultColorForPlatform; exports.getDefaultIconForPlatform = getDefaultIconForPlatform; exports.transformPlatformConfigsToOptions = transformPlatformConfigsToOptions; exports.getPlatformIcon = getPlatformIcon; exports.getPlatformColor = getPlatformColor; exports.getPlatformDisplayName = getPlatformDisplayName; exports.getPlatformDescription = getPlatformDescription; exports.getPlatformSlogan = getPlatformSlogan; exports.getSmallPlatformIcon = getSmallPlatformIcon; exports.getPlatformIconComponent = getPlatformIconComponent; exports.usePlatformConfig = usePlatformConfig; exports.usePlatformByValue = usePlatformByValue; exports.useValidatePlatform = useValidatePlatform; exports.ToolTypeValues = ToolTypeValues; exports.toolLabels = toolLabels; exports.ToolIcon = ToolIcon; exports.dotColorByVariant = dotColorByVariant; exports.progressColorByVariant = progressColorByVariant; exports.ToastCard = ToastCard; exports.CommandApprovalToast = CommandApprovalToast; exports.Toaster = Toaster; exports.showToast = showToast; exports.showCommandApprovalToast = showCommandApprovalToast; exports.toast = toast; exports.useToast = useToast; exports.getAppType = getAppType; exports.getEmbedProxyAuth = getEmbedProxyAuth; exports.getPersistedProxyEmail = getPersistedProxyEmail; exports.setEmbedProxyAuth = setEmbedProxyAuth; exports.clearEmbedProxyAuth = clearEmbedProxyAuth; exports.applyProxyAuth = applyProxyAuth; exports.setEmbedAuthAdapter = setEmbedAuthAdapter; exports.embedAuthedFetch = embedAuthedFetch; exports.contentFetch = contentFetch; exports.useContactSubmission = useContactSubmission; exports.
|
|
3867
|
-
//# sourceMappingURL=chunk-
|
|
3820
|
+
exports.useAutoLimitTags = useAutoLimitTags; exports.useDebounce = useDebounce; exports.useDeferredError = useDeferredError; exports.useFocusTrap = useFocusTrap; exports.useHeaderHeight = useHeaderHeight; exports.useHorizontalScrollbar = useHorizontalScrollbar; exports.useImageEdgeColor = useImageEdgeColor; exports.useLocalStorage = useLocalStorage; exports.useMarqueeEngine = useMarqueeEngine; exports.useMediaQuery = useMediaQuery; exports.breakpoints = breakpoints; exports.useSmUp = useSmUp; exports.useMdUp = useMdUp; exports.useLgUp = useLgUp; exports.useMemoizedCallback = useMemoizedCallback; exports.useNotificationPermission = useNotificationPermission; exports.useOnboardingState = useOnboardingState; exports.useResetOnPageHidden = useResetOnPageHidden; exports.useSearch = useSearch; exports.useSuppressCloneFocus = useSuppressCloneFocus; exports.useTablePagination = useTablePagination; exports.useThrottle = useThrottle; exports.useWindowSize = useWindowSize; exports.usePreventScroll = _overlays.usePreventScroll; exports.platformIcons = platformIcons; exports.platformColors = platformColors; exports.platformDisplayNames = platformDisplayNames; exports.platformDescriptions = platformDescriptions; exports.platformSlogans = platformSlogans; exports.platformHexColors = platformHexColors; exports.platformIconNames = platformIconNames; exports.getDefaultColorForPlatform = getDefaultColorForPlatform; exports.getDefaultIconForPlatform = getDefaultIconForPlatform; exports.transformPlatformConfigsToOptions = transformPlatformConfigsToOptions; exports.getPlatformIcon = getPlatformIcon; exports.getPlatformColor = getPlatformColor; exports.getPlatformDisplayName = getPlatformDisplayName; exports.getPlatformDescription = getPlatformDescription; exports.getPlatformSlogan = getPlatformSlogan; exports.getSmallPlatformIcon = getSmallPlatformIcon; exports.getPlatformIconComponent = getPlatformIconComponent; exports.usePlatformConfig = usePlatformConfig; exports.usePlatformByValue = usePlatformByValue; exports.useValidatePlatform = useValidatePlatform; exports.ToolTypeValues = ToolTypeValues; exports.toolLabels = toolLabels; exports.ToolIcon = ToolIcon; exports.dotColorByVariant = dotColorByVariant; exports.progressColorByVariant = progressColorByVariant; exports.ToastCard = ToastCard; exports.CommandApprovalToast = CommandApprovalToast; exports.Toaster = Toaster; exports.showToast = showToast; exports.showCommandApprovalToast = showCommandApprovalToast; exports.toast = toast; exports.useToast = useToast; exports.getAppType = getAppType; exports.getEmbedProxyAuth = getEmbedProxyAuth; exports.getPersistedProxyEmail = getPersistedProxyEmail; exports.setEmbedProxyAuth = setEmbedProxyAuth; exports.clearEmbedProxyAuth = clearEmbedProxyAuth; exports.applyProxyAuth = applyProxyAuth; exports.setEmbedAuthAdapter = setEmbedAuthAdapter; exports.embedAuthedFetch = embedAuthedFetch; exports.contentFetch = contentFetch; exports.useContactSubmission = useContactSubmission; exports.useCopyToClipboard = useCopyToClipboard; exports.configureBatchImageFetch = configureBatchImageFetch; exports.batchFetchAuthenticatedImages = batchFetchAuthenticatedImages; exports.useBatchImages = useBatchImages; exports.configureAuthenticatedImage = configureAuthenticatedImage; exports.useAuthenticatedImage = useAuthenticatedImage; exports.extractVariablesFromQuery = extractVariablesFromQuery; exports.isScalarType = isScalarType; exports.isInputObjectType = isInputObjectType; exports.flattenQueryVariables = flattenQueryVariables; exports.mergeDefaults = mergeDefaults; exports.validateSchema = validateSchema; exports.getArrayParams = getArrayParams; exports.getRequiredParams = getRequiredParams; exports.shouldIncludeInUrl = shouldIncludeInUrl; exports.urlParamsToVariables = urlParamsToVariables; exports.variablesToUrlParams = variablesToUrlParams; exports.coerceValue = coerceValue; exports.setNestedValue = setNestedValue; exports.getNestedValue = getNestedValue; exports.mergeVariables = mergeVariables; exports.clearParams = clearParams; exports.validateVariables = validateVariables; exports.GraphQLIntrospector = GraphQLIntrospector; exports.introspector = introspector; exports.useQueryParams = useQueryParams; exports.useApiParams = useApiParams; exports.createSearchParams = createSearchParams; exports.useCursorPaginationState = useCursorPaginationState; exports.useNatsClient = useNatsClient; exports.NEAR_VIEWPORT_ROOT_MARGIN = NEAR_VIEWPORT_ROOT_MARGIN; exports.useNearViewport = useNearViewport; exports.validateAccessCode = validateAccessCode; exports.consumeAccessCode = consumeAccessCode; exports.validateAndConsumeAccessCode = validateAndConsumeAccessCode; exports.useAccessCodeIntegration = useAccessCodeIntegration; exports.buildOgPlaceholderUrl = buildOgPlaceholderUrl; exports.useOgPlaceholderUrl = useOgPlaceholderUrl; exports.scrollElementIntoView = scrollElementIntoView; exports.STICKY_HEADER_OFFSET_PX = STICKY_HEADER_OFFSET_PX; exports.HUB_HEADER_OFFSET_PX = HUB_HEADER_OFFSET_PX; exports.normalizeHashFragment = normalizeHashFragment; exports.navigateSamePageHash = navigateSamePageHash; exports.useScrollToHash = useScrollToHash; exports.HONEYPOT_FIELD = HONEYPOT_FIELD; exports.ELAPSED_MS_FIELD = ELAPSED_MS_FIELD; exports.DEFAULT_MIN_FILL_MS = DEFAULT_MIN_FILL_MS; exports.extractHumanitySignals = extractHumanitySignals; exports.evaluateHumanitySignals = evaluateHumanitySignals; exports.splitCsvEnv = splitCsvEnv; exports.useHumanitySignals = useHumanitySignals;
|
|
3821
|
+
//# sourceMappingURL=chunk-IOHQJOLR.cjs.map
|