@flamingo-stack/openframe-frontend-core 0.0.848 → 0.0.850
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/build/export-map.json +1 -1
- package/dist/{chunk-MWYEROAP.cjs → chunk-2QZUTNL3.cjs} +55 -55
- package/dist/{chunk-YXKAHQYS.cjs → chunk-533QK4R6.cjs} +2 -1
- package/dist/{chunk-5HOWR4TG.cjs → chunk-5CBI2ZYV.cjs} +5 -5
- package/dist/{chunk-NYT6IBIX.cjs → chunk-5PIR77V5.cjs} +4 -4
- package/dist/{chunk-IIUZE73M.cjs → chunk-6AJYGXXS.cjs} +14 -14
- package/dist/{chunk-VW4446JR.cjs → chunk-7ICHJVAT.cjs} +16 -16
- package/dist/{chunk-U7UBYJEZ.cjs → chunk-BU2PSRAS.cjs} +5 -5
- package/dist/{chunk-IKOL6NJY.cjs → chunk-CAGNWDVJ.cjs} +11 -1
- package/dist/{chunk-O4BXHCMK.cjs → chunk-FRG724DU.cjs} +2 -2
- package/dist/{chunk-YAW7CHLV.cjs → chunk-FXLROQUT.cjs} +41 -38
- package/dist/{chunk-IUZVOQXP.cjs → chunk-GAYLAA3L.cjs} +45 -45
- package/dist/{chunk-7YJQTQPV.cjs → chunk-IG6ROHPS.cjs} +46 -46
- package/dist/{chunk-INA2FX2N.cjs → chunk-IHY7E4EX.cjs} +2 -2
- package/dist/{chunk-Y2ZWWIUA.cjs → chunk-IN3LA2FU.cjs} +2 -2
- package/dist/{chunk-74Z34I2C.cjs → chunk-IPGGSFR7.cjs} +6 -6
- package/dist/{chunk-7DW3LZ52.cjs → chunk-JWIITCVB.cjs} +94 -173
- package/dist/{chunk-OCJXOSIH.cjs → chunk-LGYPCUHO.cjs} +32 -32
- package/dist/{chunk-7LE4HWHA.cjs → chunk-OHHDX3Z4.cjs} +24 -24
- package/dist/{chunk-C3WZXOZJ.cjs → chunk-QJER2ZNA.cjs} +3 -3
- package/dist/{chunk-GASFYPGH.cjs → chunk-R5JPZ6TY.cjs} +14 -14
- package/dist/{chunk-QUSCSYHJ.cjs → chunk-TX4NTH22.cjs} +45 -26
- package/dist/{chunk-Y4BG7SPX.cjs → chunk-VRWBJL7B.cjs} +66 -66
- package/dist/{chunk-2V6FCVUL.cjs → chunk-XKOL5CNU.cjs} +449 -390
- package/dist/{chunk-I3YRYS23.cjs → chunk-ZDSC3GFX.cjs} +38 -12
- package/dist/{cloud-tenants-YAZHLPOQ.cjs → cloud-tenants-TVB3DT3J.cjs} +8 -8
- package/dist/components/case-studies/index.cjs +22 -22
- package/dist/components/chat/entity-cards/dispatch.d.ts.map +1 -1
- package/dist/components/chat/entity-cards/dispatch.js +1 -0
- package/dist/components/chat/index.cjs +5 -5
- package/dist/components/contact/index.cjs +9 -9
- package/dist/components/docs/doc-viewer.d.ts +7 -7
- package/dist/components/docs/doc-viewer.d.ts.map +1 -1
- package/dist/components/docs/doc-viewer.js +29 -16
- package/dist/components/docs/docs-hub-page.d.ts +1 -1
- package/dist/components/docs/docs-hub-page.d.ts.map +1 -1
- package/dist/components/docs/docs-hub-page.js +4 -11
- package/dist/components/docs/index.cjs +12 -12
- package/dist/components/docs/use-document-tree.d.ts.map +1 -1
- package/dist/components/docs/use-document-tree.js +24 -24
- package/dist/components/embeds/claude-embed.d.ts +2 -2
- package/dist/components/embeds/claude-embed.d.ts.map +1 -1
- package/dist/components/embeds/claude-embed.js +3 -3
- package/dist/components/embeds/embed-iframe.d.ts +5 -3
- package/dist/components/embeds/embed-iframe.d.ts.map +1 -1
- package/dist/components/embeds/embed-iframe.js +4 -3
- package/dist/components/embeds/embed-viewer-frame.d.ts +14 -9
- package/dist/components/embeds/embed-viewer-frame.d.ts.map +1 -1
- package/dist/components/embeds/embed-viewer-frame.js +31 -7
- package/dist/components/embeds/figma-embed.d.ts +4 -2
- package/dist/components/embeds/figma-embed.d.ts.map +1 -1
- package/dist/components/embeds/figma-embed.js +4 -3
- package/dist/components/embeds/file-download-card.d.ts +3 -1
- package/dist/components/embeds/file-download-card.d.ts.map +1 -1
- package/dist/components/embeds/file-download-card.js +18 -3
- package/dist/components/embeds/google-sheets-viewer.d.ts +3 -1
- package/dist/components/embeds/google-sheets-viewer.d.ts.map +1 -1
- package/dist/components/embeds/google-sheets-viewer.js +7 -4
- package/dist/components/embeds/index.cjs +9 -9
- package/dist/components/embeds/pdf-viewer.d.ts +3 -1
- package/dist/components/embeds/pdf-viewer.d.ts.map +1 -1
- package/dist/components/embeds/pdf-viewer.js +7 -2
- package/dist/components/faq/index.cjs +10 -10
- package/dist/components/features/index.cjs +10 -8
- package/dist/components/features/software/index.d.ts +1 -1
- package/dist/components/features/software/index.d.ts.map +1 -1
- package/dist/components/features/software/index.js +2 -0
- package/dist/components/features/software/software-action-copy.d.ts.map +1 -1
- package/dist/components/features/software/software-action-copy.js +6 -12
- package/dist/components/features/software/software-action-form.d.ts +7 -1
- package/dist/components/features/software/software-action-form.d.ts.map +1 -1
- package/dist/components/features/software/software-action-form.js +11 -3
- package/dist/components/features/software/update-settings-fields.d.ts +12 -1
- package/dist/components/features/software/update-settings-fields.d.ts.map +1 -1
- package/dist/components/features/software/update-settings-fields.js +57 -29
- package/dist/components/help-center-pages/index.cjs +87 -87
- package/dist/components/index.cjs +52 -50
- package/dist/components/meeting-scheduler/index.cjs +40 -40
- package/dist/components/navigation/index.cjs +11 -11
- package/dist/components/onboarding-guides/index.cjs +11 -11
- package/dist/components/product-demo/index.cjs +18 -18
- package/dist/components/related-content/index.cjs +4 -4
- package/dist/components/tickets/index.cjs +13 -13
- package/dist/components/ui/index.cjs +8 -8
- package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +1 -1
- package/dist/components/ui/markdown/rich/rich-markdown-renderer.js +7 -3
- package/dist/components/ui/page-actions.d.ts.map +1 -1
- package/dist/components/ui/page-actions.js +11 -1
- package/dist/{devices-IZROCLFK.cjs → devices-NGCTSXIU.cjs} +9 -9
- package/dist/{embeddable-chat-ETW6S22E.cjs → embeddable-chat-322NDFP5.cjs} +74 -74
- package/dist/index.cjs +18 -12
- package/dist/{knowledge-4IRWLTNW.cjs → knowledge-75PO5DYS.cjs} +9 -9
- package/dist/{logs-EFDGY5IO.cjs → logs-PZESOAIG.cjs} +15 -15
- package/dist/{policies-3KEXZ5BP.cjs → policies-6XNMBFWO.cjs} +12 -12
- package/dist/{remote-session-NT4NG7EF.cjs → remote-session-Q2FIBCGT.cjs} +4 -4
- package/dist/{scripts-PCGTZLZL.cjs → scripts-B3JW6TPF.cjs} +15 -15
- package/dist/{software-update-YCDNVFJE.cjs → software-update-NWP542J7.cjs} +12 -12
- package/dist/types/doc-source.d.ts +2 -2
- package/dist/types/doc-source.d.ts.map +1 -1
- package/dist/utils/doc-tree-nav.d.ts +7 -0
- package/dist/utils/doc-tree-nav.d.ts.map +1 -1
- package/dist/utils/doc-tree-nav.js +19 -0
- package/dist/utils/index.cjs +25 -2
- package/dist/utils/list-url.d.ts.map +1 -1
- package/dist/utils/list-url.js +2 -1
- package/dist/utils/source-grouping.d.ts +2 -2
- package/dist/utils/source-grouping.d.ts.map +1 -1
- package/dist/utils/source-grouping.js +1 -1
- package/dist/utils/source-icons.d.ts.map +1 -1
- package/dist/utils/source-icons.js +3 -0
- package/package.json +1 -1
- package/src/components/chat/entity-cards/dispatch.tsx +3 -0
- package/src/components/docs/doc-viewer.tsx +56 -35
- package/src/components/docs/docs-hub-page.tsx +13 -37
- package/src/components/docs/use-document-tree.ts +33 -23
- package/src/components/embeds/claude-embed.tsx +4 -4
- package/src/components/embeds/embed-iframe.tsx +8 -5
- package/src/components/embeds/embed-viewer-frame.tsx +43 -15
- package/src/components/embeds/figma-embed.tsx +9 -4
- package/src/components/embeds/file-download-card.tsx +28 -4
- package/src/components/embeds/google-sheets-viewer.tsx +9 -3
- package/src/components/embeds/pdf-viewer.tsx +12 -2
- package/src/components/features/software/index.ts +1 -0
- package/src/components/features/software/software-action-copy.ts +19 -12
- package/src/components/features/software/software-action-form.tsx +16 -3
- package/src/components/features/software/update-settings-fields.tsx +104 -32
- package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +4 -0
- package/src/components/ui/page-actions.tsx +19 -2
- package/src/types/doc-source.ts +2 -2
- package/src/utils/doc-tree-nav.ts +27 -0
- package/src/utils/list-url.ts +2 -1
- package/src/utils/source-grouping.ts +2 -2
- package/src/utils/source-icons.ts +3 -0
- package/dist/components/docs/skeletons.d.ts +0 -25
- package/dist/components/docs/skeletons.d.ts.map +0 -1
- package/dist/components/docs/skeletons.js +0 -83
- package/src/components/docs/skeletons.tsx +0 -131
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useMemo } from "react";
|
|
4
4
|
import { useRouter } from "../../embed-shims/next-navigation.js";
|
|
5
|
-
import { findDocNodeByPath } from "../../utils/doc-tree-nav.js";
|
|
5
|
+
import { findDocNodeByPath, rootDocumentPath } from "../../utils/doc-tree-nav.js";
|
|
6
6
|
import { PageShell } from "../layout/article-detail-layout.js";
|
|
7
7
|
import { PageLayout } from "../layout/page-layout.js";
|
|
8
|
-
import { UnifiedSkeleton } from "../loading/unified-skeleton.js";
|
|
9
8
|
import { MultiLevelNavigation, MobileNavigationDropdown } from "../navigation/multi-level-navigation.js";
|
|
10
9
|
import { StickySectionNav } from "../navigation/sticky-section-nav.js";
|
|
11
10
|
import { PersistentSidebar, PersistentMobileDropdown } from "../persistent-filter-controls.js";
|
|
12
11
|
import { DocSearchBar, useDocSearch } from "../shared/doc-search/index.js";
|
|
13
12
|
import { DataSyncLine } from "../ui/data-attribution.js";
|
|
13
|
+
import { LoadingScope } from "../ui/loading-scope.js";
|
|
14
14
|
import { useDocNavigation } from "./doc-navigation-context.js";
|
|
15
15
|
import { useDocsResolveLink } from "./use-docs-resolve-link.js";
|
|
16
16
|
import { useDocumentTree } from "./use-document-tree.js";
|
|
@@ -29,11 +29,12 @@ function DocViewer(props) {
|
|
|
29
29
|
return /* @__PURE__ */ jsx(DocViewerContent, { ...props });
|
|
30
30
|
}
|
|
31
31
|
const ON_THIS_PAGE_LABEL = "ON THIS PAGE";
|
|
32
|
+
const NO_SECTION_CLICK = () => {
|
|
33
|
+
};
|
|
32
34
|
const ON_THIS_PAGE_HEADING_CLASS = "mb-4 font-semibold text-ods-text-secondary text-h5";
|
|
33
35
|
function DocViewerContent({
|
|
34
36
|
sourceId,
|
|
35
37
|
renderContent,
|
|
36
|
-
renderSkeleton,
|
|
37
38
|
chatSource,
|
|
38
39
|
title,
|
|
39
40
|
subtitle,
|
|
@@ -41,6 +42,7 @@ function DocViewerContent({
|
|
|
41
42
|
className = "",
|
|
42
43
|
shell = true,
|
|
43
44
|
docPath,
|
|
45
|
+
initialDocumentType,
|
|
44
46
|
sidebarLabel = "DOCUMENTATION",
|
|
45
47
|
structureEndpoint,
|
|
46
48
|
contentEndpoint,
|
|
@@ -107,8 +109,14 @@ function DocViewerContent({
|
|
|
107
109
|
onResolveLink: resolveLink
|
|
108
110
|
});
|
|
109
111
|
}, [content, renderContent, navigateToDoc, sourceId, resolveLink]);
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
+
const selectedNodePath = structure.length > 0 && !selectedPath ? rootDocumentPath(structure, folderIndexFile) : selectedPath;
|
|
113
|
+
const selectedNodeDocType = structure.length > 0 ? selectedNodePath ? findDocNodeByPath(selectedNodePath, structure)?.documentType : void 0 : initialDocumentType;
|
|
114
|
+
const isLoadingDocument = isLoadingContent || isLoadingStructure;
|
|
115
|
+
const loadingContent = isLoadingDocument ? renderContent(
|
|
116
|
+
{ content: "", sections: [], path: selectedPath ?? "", documentType: selectedNodeDocType },
|
|
117
|
+
{ onInternalLinkClick: navigateToDoc, currentPath: selectedPath ?? "", sourceId }
|
|
118
|
+
) : null;
|
|
119
|
+
const activeDocType = isLoadingDocument ? selectedNodeDocType : content?.documentType ?? selectedNodeDocType;
|
|
112
120
|
const isMarkdownContent = !activeDocType || activeDocType === "markdown";
|
|
113
121
|
const showStickyNav = isMarkdownContent;
|
|
114
122
|
const stickyNavSections = content?.sections?.map((s) => ({ id: s.id, label: s.title })) ?? [];
|
|
@@ -116,8 +124,7 @@ function DocViewerContent({
|
|
|
116
124
|
const bgStyle = isColorValue ? { backgroundColor: colorPalette.background } : {};
|
|
117
125
|
const bgClass = !isColorValue ? colorPalette.background : "";
|
|
118
126
|
const containerBgStyle = colorPalette.containerBackground !== "transparent" ? { backgroundColor: colorPalette.containerBackground } : {};
|
|
119
|
-
const
|
|
120
|
-
const resolvedEmptyText = emptyStateText || defaultEmptyText;
|
|
127
|
+
const resolvedEmptyText = structure.length > 0 ? "Select a document from the sidebar to view" : emptyStateText || "No documents yet.";
|
|
121
128
|
const inner = /* @__PURE__ */ jsx("div", { style: { ...bgStyle, ...containerBgStyle }, children: /* @__PURE__ */ jsx(PageLayout, { title, subtitle, titleSize: "h1", titleWrap: true, backButton: backCfg ?? void 0, children: /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-10", children: [
|
|
122
129
|
synced && /* @__PURE__ */ jsx(DataSyncLine, { sync: content?.sync, loading: !content && (isLoadingContent || isLoadingStructure) }),
|
|
123
130
|
showAIChat && /* @__PURE__ */ jsx(
|
|
@@ -180,17 +187,23 @@ function DocViewerContent({
|
|
|
180
187
|
// shouldn't be on file pages" bug.
|
|
181
188
|
isMarkdownContent && (showStickyNav && stickyNavSections.length > 0 || isLoadingContent || isLoadingStructure) ? "content-lg:grid-cols-[1fr_280px]" : ""} gap-8`,
|
|
182
189
|
children: [
|
|
183
|
-
/* @__PURE__ */ jsx("div", { className: `w-full min-w-0 ${isMarkdownContent ? "mx-auto max-w-4xl" : ""}`, children: /* @__PURE__ */ jsx("article", { className: "space-y-2", children:
|
|
184
|
-
|
|
190
|
+
/* @__PURE__ */ jsx("div", { className: `w-full min-w-0 ${isMarkdownContent ? "mx-auto max-w-4xl" : ""}`, children: /* @__PURE__ */ jsx("article", { className: "space-y-2", children: isLoadingDocument ? (
|
|
191
|
+
// The document being opened draws its own loading form: its renderer, in a loading scope,
|
|
192
|
+
// with an empty document of its type (no words, no address), never a skeleton picked here.
|
|
193
|
+
/* @__PURE__ */ jsx(LoadingScope, { children: loadingContent })
|
|
194
|
+
) : !content ? /* @__PURE__ */ jsx("div", { className: "py-16 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-ods-text-secondary text-h4", children: resolvedEmptyText }) }) : renderedContent }) }),
|
|
195
|
+
isMarkdownContent && isLoadingDocument && /* @__PURE__ */ jsx("div", { className: "hidden content-lg:block", children: /* @__PURE__ */ jsxs("div", { className: "sticky top-24", children: [
|
|
185
196
|
/* @__PURE__ */ jsx("h3", { className: ON_THIS_PAGE_HEADING_CLASS, children: ON_THIS_PAGE_LABEL }),
|
|
186
|
-
/* @__PURE__ */ jsx(
|
|
187
|
-
|
|
197
|
+
/* @__PURE__ */ jsx(LoadingScope, { children: /* @__PURE__ */ jsx(
|
|
198
|
+
StickySectionNav,
|
|
188
199
|
{
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
200
|
+
sections: [],
|
|
201
|
+
activeSection: "",
|
|
202
|
+
onSectionClick: NO_SECTION_CLICK,
|
|
203
|
+
ribbonPosition: "left",
|
|
204
|
+
ribbonColor: "var(--ods-accent)"
|
|
205
|
+
}
|
|
206
|
+
) })
|
|
194
207
|
] }) }),
|
|
195
208
|
showStickyNav && content && stickyNavSections.length > 0 && !isLoadingContent && /* @__PURE__ */ jsx("div", { className: "hidden content-lg:block", children: /* @__PURE__ */ jsxs("div", { className: "sticky top-24", children: [
|
|
196
209
|
/* @__PURE__ */ jsx("h3", { className: ON_THIS_PAGE_HEADING_CLASS, children: ON_THIS_PAGE_LABEL }),
|
|
@@ -14,7 +14,7 @@ type DocRenderer = (content: DocContent, handlers: DocRenderHandlers) => React.R
|
|
|
14
14
|
export type DocumentTypeRenderers = {
|
|
15
15
|
markdown: DocRenderer;
|
|
16
16
|
} & Partial<Record<DocumentType, DocRenderer>>;
|
|
17
|
-
export interface DocsHubPageProps extends Omit<DocViewerProps, 'renderContent' | '
|
|
17
|
+
export interface DocsHubPageProps extends Omit<DocViewerProps, 'renderContent' | 'showAIChat'> {
|
|
18
18
|
/** Per-document-type renderer map. `markdown` is REQUIRED. */
|
|
19
19
|
documentTypeRenderers: DocumentTypeRenderers;
|
|
20
20
|
/** Renderer for unknown / future document types. Defaults to a lib-styled
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs-hub-page.d.ts","sourceRoot":"","sources":["../../../src/components/docs/docs-hub-page.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAK1F,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"docs-hub-page.d.ts","sourceRoot":"","sources":["../../../src/components/docs/docs-hub-page.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAK1F,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9D,KAAK,WAAW,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,KAAK,KAAK,CAAC,SAAS,CAAC;AAEzF;;;;;;;;GAQG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAAE,QAAQ,EAAE,WAAW,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC;AAE3G,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,cAAc,EAAE,eAAe,GAAG,YAAY,CAAC;IAC5F,8DAA8D;IAC9D,qBAAqB,EAAE,qBAAqB,CAAC;IAE7C;+CAC2C;IAC3C,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAE/B;;sEAEkE;IAClE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAkCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAqB,EACrB,qBAAqB,EACrB,gBAA0C,EAC1C,UAAiB,EACjB,SAA0B,EAC1B,YAA8B,EAC9B,GAAG,cAAc,EAClB,EAAE,gBAAgB,qBAyBlB"}
|
|
@@ -5,12 +5,11 @@ import { FileDownloadCard } from "../embeds/file-download-card.js";
|
|
|
5
5
|
import { GoogleSheetsViewer } from "../embeds/google-sheets-viewer.js";
|
|
6
6
|
import { PdfViewer } from "../embeds/pdf-viewer.js";
|
|
7
7
|
import { DocViewer } from "./doc-viewer.js";
|
|
8
|
-
import { MarkdownSkeleton, EmbedSkeleton } from "./skeletons.js";
|
|
9
8
|
const DEFAULT_TITLE = "Documents";
|
|
10
9
|
const defaultFallbackRenderer = () => /* @__PURE__ */ jsx("div", { className: "py-16 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-ods-text-secondary", children: "Unsupported document type" }) });
|
|
11
|
-
const defaultPdfRenderer = (content
|
|
12
|
-
const defaultGoogleSheetRenderer = (content
|
|
13
|
-
const defaultFigmaRenderer = (content
|
|
10
|
+
const defaultPdfRenderer = (content) => /* @__PURE__ */ jsx(PdfViewer, { src: content.fileUrl ?? "", fileName: content.fileName });
|
|
11
|
+
const defaultGoogleSheetRenderer = (content) => /* @__PURE__ */ jsx(GoogleSheetsViewer, { externalUrl: content.externalUrl ?? "", fileName: content.fileName });
|
|
12
|
+
const defaultFigmaRenderer = (content) => /* @__PURE__ */ jsx(FigmaEmbed, { url: content.externalUrl ?? "", title: content.fileName, iframeLoading: "eager" });
|
|
14
13
|
const defaultFileRenderer = (content) => /* @__PURE__ */ jsx(
|
|
15
14
|
FileDownloadCard,
|
|
16
15
|
{
|
|
@@ -20,11 +19,6 @@ const defaultFileRenderer = (content) => /* @__PURE__ */ jsx(
|
|
|
20
19
|
fileUrl: content.fileUrl
|
|
21
20
|
}
|
|
22
21
|
);
|
|
23
|
-
const documentLoadingForm = (documentType) => !documentType || documentType === "markdown" ? /* @__PURE__ */ jsx(MarkdownSkeleton, {}) : (
|
|
24
|
-
// Forward the documentType so the embed skeleton renders the right
|
|
25
|
-
// shape (PDF=2 buttons, sheets/figma=1 button, file=centered card).
|
|
26
|
-
/* @__PURE__ */ jsx(EmbedSkeleton, { documentType })
|
|
27
|
-
);
|
|
28
22
|
function DocsHubPage({
|
|
29
23
|
title = DEFAULT_TITLE,
|
|
30
24
|
documentTypeRenderers,
|
|
@@ -54,8 +48,7 @@ function DocsHubPage({
|
|
|
54
48
|
showAIChat,
|
|
55
49
|
className,
|
|
56
50
|
sidebarLabel,
|
|
57
|
-
renderContent
|
|
58
|
-
renderSkeleton: documentLoadingForm
|
|
51
|
+
renderContent
|
|
59
52
|
}
|
|
60
53
|
);
|
|
61
54
|
}
|
|
@@ -6,16 +6,16 @@
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
10
|
-
require('../../chunk-
|
|
9
|
+
var _chunkJWIITCVBcjs = require('../../chunk-JWIITCVB.cjs');
|
|
10
|
+
require('../../chunk-ZDSC3GFX.cjs');
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
14
|
-
require('../../chunk-
|
|
15
|
-
require('../../chunk-
|
|
16
|
-
require('../../chunk-
|
|
13
|
+
var _chunkFRG724DUcjs = require('../../chunk-FRG724DU.cjs');
|
|
14
|
+
require('../../chunk-5CBI2ZYV.cjs');
|
|
15
|
+
require('../../chunk-XKOL5CNU.cjs');
|
|
16
|
+
require('../../chunk-CAGNWDVJ.cjs');
|
|
17
17
|
require('../../chunk-SA2NNWIJ.cjs');
|
|
18
|
-
require('../../chunk-
|
|
18
|
+
require('../../chunk-IHY7E4EX.cjs');
|
|
19
19
|
require('../../chunk-HQQE74RO.cjs');
|
|
20
20
|
require('../../chunk-DEY6XXGO.cjs');
|
|
21
21
|
require('../../chunk-FNQWL4W4.cjs');
|
|
@@ -23,9 +23,9 @@ require('../../chunk-IUDBG3HJ.cjs');
|
|
|
23
23
|
require('../../chunk-24I6RFVU.cjs');
|
|
24
24
|
require('../../chunk-MZ4KBSH7.cjs');
|
|
25
25
|
require('../../chunk-ZZDFMUEU.cjs');
|
|
26
|
-
require('../../chunk-
|
|
26
|
+
require('../../chunk-TX4NTH22.cjs');
|
|
27
27
|
require('../../chunk-OT6P57ZS.cjs');
|
|
28
|
-
require('../../chunk-
|
|
28
|
+
require('../../chunk-FXLROQUT.cjs');
|
|
29
29
|
require('../../chunk-3W4ASAXN.cjs');
|
|
30
30
|
require('../../chunk-4YBS4HIO.cjs');
|
|
31
31
|
require('../../chunk-YJZ7R3W5.cjs');
|
|
@@ -1829,8 +1829,8 @@ require('../../chunk-SKI6NKOE.cjs');
|
|
|
1829
1829
|
require('../../chunk-EWPR7662.cjs');
|
|
1830
1830
|
require('../../chunk-IX2E3AN7.cjs');
|
|
1831
1831
|
require('../../chunk-7DNL734S.cjs');
|
|
1832
|
-
require('../../chunk-
|
|
1833
|
-
require('../../chunk-
|
|
1832
|
+
require('../../chunk-BU2PSRAS.cjs');
|
|
1833
|
+
require('../../chunk-533QK4R6.cjs');
|
|
1834
1834
|
require('../../chunk-HTYJUMFB.cjs');
|
|
1835
1835
|
require('../../chunk-W7OFAROY.cjs');
|
|
1836
1836
|
require('../../chunk-MDLT6D46.cjs');
|
|
@@ -1872,4 +1872,4 @@ require('../../chunk-QDB2JO55.cjs');
|
|
|
1872
1872
|
|
|
1873
1873
|
|
|
1874
1874
|
|
|
1875
|
-
exports.DocNavigationProvider =
|
|
1875
|
+
exports.DocNavigationProvider = _chunkJWIITCVBcjs.DocNavigationProvider; exports.DocViewer = _chunkJWIITCVBcjs.DocViewer; exports.DocsHubPage = _chunkJWIITCVBcjs.DocsHubPage; exports.useDocNavigation = _chunkJWIITCVBcjs.useDocNavigation; exports.useDocumentTree = _chunkJWIITCVBcjs.useDocumentTree; exports.useScrollSpy = _chunkFRG724DUcjs.useScrollSpy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-document-tree.d.ts","sourceRoot":"","sources":["../../../src/components/docs/use-document-tree.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAgB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"use-document-tree.d.ts","sourceRoot":"","sources":["../../../src/components/docs/use-document-tree.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAgB,MAAM,wBAAwB,CAAC;AAiLhF,MAAM,WAAW,qBAAqB;IACpC,4DAA4D;IAC5D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,qBAAqB,EAAE,WAAW,CAAC,EAAE,MAAM;;;;;;;;;yBAsWzC,MAAM;uBAiBrC,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;0BAgCnD,MAAM,YAAY;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE;;;EA0JlF"}
|
|
@@ -6,7 +6,9 @@ import {
|
|
|
6
6
|
stripFolderIndexFromPath,
|
|
7
7
|
findDocNodeByPath,
|
|
8
8
|
getDocAncestorNodeIds,
|
|
9
|
-
DEFAULT_FOLDER_INDEX_FILE
|
|
9
|
+
DEFAULT_FOLDER_INDEX_FILE,
|
|
10
|
+
findFirstDocPath,
|
|
11
|
+
rootDocumentPath
|
|
10
12
|
} from "../../utils/doc-tree-nav.js";
|
|
11
13
|
import { contentFetch } from "../../utils/embed-content-fetch.js";
|
|
12
14
|
import { navigateSamePageHash, HUB_HEADER_OFFSET_PX } from "../../utils/same-page-hash-nav.js";
|
|
@@ -21,21 +23,6 @@ function scrollToContent() {
|
|
|
21
23
|
scrollElementIntoView(document.documentElement);
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
|
-
function findFirstDocPath(folder) {
|
|
25
|
-
const children = folder.children ?? [];
|
|
26
|
-
for (const child of children) {
|
|
27
|
-
if (child.type === "file" && !child.path.toLowerCase().endsWith(".mmd")) {
|
|
28
|
-
return child.path;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
for (const child of children) {
|
|
32
|
-
if (child.type === "folder") {
|
|
33
|
-
const nested = findFirstDocPath(child);
|
|
34
|
-
if (nested) return nested;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
26
|
function isRecord(value) {
|
|
40
27
|
return typeof value === "object" && value !== null;
|
|
41
28
|
}
|
|
@@ -127,6 +114,10 @@ function useDocumentTree(config, initialPath) {
|
|
|
127
114
|
const folderIndexFile = config.folderIndexFile ?? DEFAULT_FOLDER_INDEX_FILE;
|
|
128
115
|
const cleanInitialPath = stripFolderIndexFromPath(initialPath?.replace(/\/$/, "") || "", folderIndexFile);
|
|
129
116
|
const [structure, setStructure] = useState([]);
|
|
117
|
+
const structureRef = useRef(structure);
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
structureRef.current = structure;
|
|
120
|
+
}, [structure]);
|
|
130
121
|
const [selectedPath, setSelectedPath] = useState(cleanInitialPath);
|
|
131
122
|
const [content, setContent] = useState(null);
|
|
132
123
|
const [isLoadingStructure, setIsLoadingStructure] = useState(true);
|
|
@@ -239,9 +230,10 @@ function useDocumentTree(config, initialPath) {
|
|
|
239
230
|
setContent(null);
|
|
240
231
|
return;
|
|
241
232
|
}
|
|
242
|
-
const
|
|
233
|
+
const latestStructure = structureRef.current;
|
|
234
|
+
const probe = findDocNodeByPath(stripFolderIndexFromPath(path, folderIndexFile), latestStructure);
|
|
243
235
|
const probeIsNoReadmeFolder = !!probe && probe.type === "folder" && !probe.hasReadme;
|
|
244
|
-
const preStructureFolderLike =
|
|
236
|
+
const preStructureFolderLike = latestStructure.length === 0 && !path.endsWith(".md");
|
|
245
237
|
if (probeIsNoReadmeFolder || preStructureFolderLike) {
|
|
246
238
|
lastFetchedPath.current = null;
|
|
247
239
|
setError(null);
|
|
@@ -296,7 +288,12 @@ function useDocumentTree(config, initialPath) {
|
|
|
296
288
|
if (!structure || structure.length === 0) return;
|
|
297
289
|
let pathToFetch = null;
|
|
298
290
|
if (selectedPath === "") {
|
|
299
|
-
|
|
291
|
+
const rootPath = rootDocumentPath(structure, folderIndexFile);
|
|
292
|
+
if (!rootPath) {
|
|
293
|
+
lastFetchedPath.current = null;
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
pathToFetch = rootPath;
|
|
300
297
|
} else {
|
|
301
298
|
const node = findDocNodeByPath(selectedPath, structure);
|
|
302
299
|
if (node && node.type === "folder" && !node.hasReadme) {
|
|
@@ -434,18 +431,21 @@ function useDocumentTree(config, initialPath) {
|
|
|
434
431
|
});
|
|
435
432
|
}, [docNavigation, normalizedBaseRoute, structure, selectNode, folderIndexFile]);
|
|
436
433
|
const isEmptyFolder = useMemo(() => {
|
|
437
|
-
if (
|
|
434
|
+
if (structure.length === 0) return false;
|
|
435
|
+
if (!selectedPath) return !rootDocumentPath(structure, folderIndexFile);
|
|
438
436
|
const node = findDocNodeByPath(selectedPath, structure);
|
|
439
437
|
return !!node && node.type === "folder" && !node.hasReadme && !findFirstDocPath(node);
|
|
440
|
-
}, [selectedPath, structure]);
|
|
438
|
+
}, [selectedPath, structure, folderIndexFile]);
|
|
439
|
+
const isEmptySource = !isLoadingStructure && structure.length === 0;
|
|
440
|
+
const settled = isEmptyFolder || isEmptySource;
|
|
441
441
|
return {
|
|
442
442
|
structure,
|
|
443
443
|
selectedPath,
|
|
444
444
|
setSelectedPath,
|
|
445
|
-
content:
|
|
445
|
+
content: settled ? null : content,
|
|
446
446
|
isLoadingStructure,
|
|
447
|
-
isLoadingContent:
|
|
448
|
-
error:
|
|
447
|
+
isLoadingContent: settled ? false : isLoadingContent,
|
|
448
|
+
error: settled ? null : error,
|
|
449
449
|
expandedNodes,
|
|
450
450
|
toggleNode,
|
|
451
451
|
selectNode,
|
|
@@ -9,7 +9,7 @@ export interface ClaudeEmbedProps {
|
|
|
9
9
|
/** iframe height (CSS value), matching `FigmaEmbed`'s prop. */
|
|
10
10
|
height?: string;
|
|
11
11
|
/** iframe loading strategy. Defaults to `lazy`, as `FigmaEmbed` does. */
|
|
12
|
-
|
|
12
|
+
iframeLoading?: 'eager' | 'lazy';
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* A Claude artifact, in the SAME chrome as every other embed viewer
|
|
@@ -35,5 +35,5 @@ export interface ClaudeEmbedProps {
|
|
|
35
35
|
* a Claude Design url (no embed route), an artifact whose author has not
|
|
36
36
|
* allow-listed this host, or an http host (mixed content).
|
|
37
37
|
*/
|
|
38
|
-
export declare function ClaudeEmbed({ url, kind, title, height,
|
|
38
|
+
export declare function ClaudeEmbed({ url, kind, title, height, iframeLoading }: ClaudeEmbedProps): import("react").JSX.Element;
|
|
39
39
|
//# sourceMappingURL=claude-embed.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-embed.d.ts","sourceRoot":"","sources":["../../../src/components/embeds/claude-embed.tsx"],"names":[],"mappings":"AASA,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,mEAAmE;IACnE,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,
|
|
1
|
+
{"version":3,"file":"claude-embed.d.ts","sourceRoot":"","sources":["../../../src/components/embeds/claude-embed.tsx"],"names":[],"mappings":"AASA,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,mEAAmE;IACnE,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAClC;AAOD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,WAAW,CAAC,EAAE,GAAG,EAAE,IAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,aAAsB,EAAE,EAAE,gBAAgB,+BAkE9G"}
|
|
@@ -10,7 +10,7 @@ const KIND_HEADING = {
|
|
|
10
10
|
artifact: "Claude Artifact",
|
|
11
11
|
design: "Claude Design"
|
|
12
12
|
};
|
|
13
|
-
function ClaudeEmbed({ url, kind = "artifact", title, height,
|
|
13
|
+
function ClaudeEmbed({ url, kind = "artifact", title, height, iframeLoading = "lazy" }) {
|
|
14
14
|
const { src: mirrorSrc, status } = useClaudeMirrorSrc(url);
|
|
15
15
|
const isProbing = status === "probing";
|
|
16
16
|
const embedUrl = isProbing ? null : mirrorSrc ?? toClaudeEmbedUrl(url);
|
|
@@ -21,7 +21,7 @@ function ClaudeEmbed({ url, kind = "artifact", title, height, loading = "lazy" }
|
|
|
21
21
|
icon: /* @__PURE__ */ jsx(ClaudeIcon, { className: "h-5 w-5 shrink-0" }),
|
|
22
22
|
title: title?.trim() || KIND_HEADING[kind],
|
|
23
23
|
titleVariant: "h6",
|
|
24
|
-
|
|
24
|
+
resolving: isProbing,
|
|
25
25
|
actions: /* @__PURE__ */ jsx(
|
|
26
26
|
Button,
|
|
27
27
|
{
|
|
@@ -37,7 +37,7 @@ function ClaudeEmbed({ url, kind = "artifact", title, height, loading = "lazy" }
|
|
|
37
37
|
),
|
|
38
38
|
src: embedUrl,
|
|
39
39
|
fullscreenControl: true,
|
|
40
|
-
|
|
40
|
+
iframeLoading,
|
|
41
41
|
height,
|
|
42
42
|
allow: "clipboard-write; clipboard-read; fullscreen",
|
|
43
43
|
sandbox: mirrorSrc ? "allow-scripts allow-popups allow-forms" : "allow-scripts allow-same-origin allow-popups allow-forms",
|
|
@@ -25,8 +25,10 @@ export interface EmbedIframeProps {
|
|
|
25
25
|
allow?: string;
|
|
26
26
|
/** iframe `referrerPolicy` attribute */
|
|
27
27
|
referrerPolicy?: React.IframeHTMLAttributes<HTMLIFrameElement>['referrerPolicy'];
|
|
28
|
-
/** iframe `loading` attribute */
|
|
29
|
-
|
|
28
|
+
/** iframe `loading` attribute (eager or lazy). */
|
|
29
|
+
iframeLoading?: 'eager' | 'lazy';
|
|
30
|
+
/** The frame's source is not known yet: the frame draws its loading form. A loading scope does the same. */
|
|
31
|
+
loading?: boolean;
|
|
30
32
|
/** iframe `allowFullScreen` attribute */
|
|
31
33
|
allowFullScreen?: boolean;
|
|
32
34
|
/**
|
|
@@ -48,5 +50,5 @@ export interface EmbedIframeProps {
|
|
|
48
50
|
* - Setting iframe src to about:blank on unmount to release the embedded document
|
|
49
51
|
* - Resetting loaded state when src changes
|
|
50
52
|
*/
|
|
51
|
-
export declare function EmbedIframe({ src, title, className, height, allow, referrerPolicy, loading, allowFullScreen, sandbox, }: EmbedIframeProps): React.JSX.Element;
|
|
53
|
+
export declare function EmbedIframe({ src, title, className, height, allow, referrerPolicy, iframeLoading, loading, allowFullScreen, sandbox, }: EmbedIframeProps): React.JSX.Element;
|
|
52
54
|
//# sourceMappingURL=embed-iframe.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embed-iframe.d.ts","sourceRoot":"","sources":["../../../src/components/embeds/embed-iframe.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B;;;;;;;yEAOyE;AACzE,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,MAAa,GACd,EAAE;IACD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0GAA0G;IAC1G,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,qBAQA;AAED,MAAM,WAAW,gBAAgB;IAC/B,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,cAAc,CAAC,EAAE,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC,gBAAgB,CAAC,CAAC;IACjF,
|
|
1
|
+
{"version":3,"file":"embed-iframe.d.ts","sourceRoot":"","sources":["../../../src/components/embeds/embed-iframe.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B;;;;;;;yEAOyE;AACzE,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,MAAa,GACd,EAAE;IACD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0GAA0G;IAC1G,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,qBAQA;AAED,MAAM,WAAW,gBAAgB;IAC/B,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,cAAc,CAAC,EAAE,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC,gBAAgB,CAAC,CAAC;IACjF,kDAAkD;IAClD,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,4GAA4G;IAC5G,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yCAAyC;IACzC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,EAC1B,GAAG,EACH,KAAK,EACL,SAAS,EACT,MAAM,EACN,KAAK,EACL,cAAc,EACd,aAAa,EACb,OAAe,EACf,eAAe,EACf,OAAO,GACR,EAAE,gBAAgB,qBAqDlB"}
|
|
@@ -23,7 +23,8 @@ function EmbedIframe({
|
|
|
23
23
|
height,
|
|
24
24
|
allow,
|
|
25
25
|
referrerPolicy,
|
|
26
|
-
|
|
26
|
+
iframeLoading,
|
|
27
|
+
loading = false,
|
|
27
28
|
allowFullScreen,
|
|
28
29
|
sandbox
|
|
29
30
|
}) {
|
|
@@ -31,7 +32,7 @@ function EmbedIframe({
|
|
|
31
32
|
const isLoaded = loadedSrc === src;
|
|
32
33
|
const iframeRef = useRef(null);
|
|
33
34
|
const handleLoad = useCallback(() => setLoadedSrc(src), [src]);
|
|
34
|
-
const held = useLoadingScope();
|
|
35
|
+
const held = useLoadingScope() || loading;
|
|
35
36
|
useEffect(() => {
|
|
36
37
|
const iframe = iframeRef.current;
|
|
37
38
|
return () => {
|
|
@@ -62,7 +63,7 @@ function EmbedIframe({
|
|
|
62
63
|
onLoad: handleLoad,
|
|
63
64
|
allow,
|
|
64
65
|
referrerPolicy,
|
|
65
|
-
loading,
|
|
66
|
+
loading: iframeLoading,
|
|
66
67
|
allowFullScreen: allow?.includes("fullscreen") ? void 0 : allowFullScreen,
|
|
67
68
|
sandbox
|
|
68
69
|
},
|
|
@@ -30,21 +30,22 @@ export interface EmbedViewerFrameProps {
|
|
|
30
30
|
/** Rendered verbatim in the header row — the caller owns its own container/state. */
|
|
31
31
|
actions?: React.ReactNode;
|
|
32
32
|
/** Iframe source; falsy renders the inline empty state (or the loading
|
|
33
|
-
* state when `
|
|
33
|
+
* state when `loading` or `resolving`) under the header. */
|
|
34
34
|
src: string | null | undefined;
|
|
35
|
-
/**
|
|
36
|
-
* loading skeleton
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
*
|
|
40
|
-
|
|
35
|
+
/** The document is being read (the standard `loading` prop; a loading scope does the same): the whole frame is its
|
|
36
|
+
* loading form, a skeleton title, its buttons' loading forms and the frame's loading box. */
|
|
37
|
+
loading?: boolean;
|
|
38
|
+
/** The document is known (its title shows) but the viewer is still finding where its frame points (ClaudeEmbed
|
|
39
|
+
* probing for a self-hosted mirror): only the body is its loading box. */
|
|
40
|
+
resolving?: boolean;
|
|
41
41
|
/** Large icon for the inline empty state (the viewers pass `w-16 h-16`). */
|
|
42
42
|
emptyIcon?: React.ReactNode;
|
|
43
43
|
emptyMessage?: string;
|
|
44
44
|
height?: string;
|
|
45
45
|
allow?: string;
|
|
46
46
|
allowFullScreen?: boolean;
|
|
47
|
-
loading
|
|
47
|
+
/** iframe loading strategy (eager or lazy). */
|
|
48
|
+
iframeLoading?: 'eager' | 'lazy';
|
|
48
49
|
/** iframe `sandbox` — see `EmbedIframe`. Set it for user-authored contents. */
|
|
49
50
|
sandbox?: string;
|
|
50
51
|
/** Wrapper classes; defaults to the sheets/pdf `space-y-4`. */
|
|
@@ -56,6 +57,10 @@ export interface EmbedViewerFrameProps {
|
|
|
56
57
|
* button (the Figma player) and some cannot (a self-hosted Claude
|
|
57
58
|
* artifact mirror) — the shell provides the affordance uniformly. */
|
|
58
59
|
fullscreenControl?: boolean;
|
|
60
|
+
/** How many buttons `actions` draws (PDF: Preview and Download): the header's loading form draws as many. Default 1. */
|
|
61
|
+
loadingActionCount?: number;
|
|
59
62
|
}
|
|
60
|
-
|
|
63
|
+
/** The header's loading form draws one button by default: most viewers have one action (the PDF viewer passes two). */
|
|
64
|
+
export declare const EMBED_VIEWER_SKELETON_ACTIONS = 1;
|
|
65
|
+
export declare function EmbedViewerFrame({ icon, title, titleVariant, actions, src, loading: loadingGiven, resolving, emptyIcon, emptyMessage, height, allow, allowFullScreen, iframeLoading, sandbox, className, fullscreenControl, loadingActionCount, }: EmbedViewerFrameProps): React.JSX.Element;
|
|
61
66
|
//# sourceMappingURL=embed-viewer-frame.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embed-viewer-frame.d.ts","sourceRoot":"","sources":["../../../src/components/embeds/embed-viewer-frame.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"embed-viewer-frame.d.ts","sourceRoot":"","sources":["../../../src/components/embeds/embed-viewer-frame.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,qBAAqB;IACpC,6EAA6E;IAC7E,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,YAAY,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC3B,qFAAqF;IACrF,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;iEAC6D;IAC7D,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/B;kGAC8F;IAC9F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;+EAC2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,+CAA+C;IAC/C,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;0EAKsE;IACtE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,wHAAwH;IACxH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,uHAAuH;AACvH,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAE/C,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,KAAK,EACL,YAAmB,EACnB,OAAO,EACP,GAAG,EACH,OAAO,EAAE,YAAoB,EAC7B,SAAiB,EACjB,SAAS,EACT,YAAsC,EACtC,MAAM,EACN,KAAK,EACL,eAAe,EACf,aAAa,EACb,OAAO,EACP,SAAS,EACT,iBAAiB,EACjB,kBAAkD,GACnD,EAAE,qBAAqB,qBAmIvB"}
|
|
@@ -4,27 +4,32 @@ import { Maximize2, Minimize2 } from "lucide-react";
|
|
|
4
4
|
import { useEffect, useRef, useState } from "react";
|
|
5
5
|
import { cn } from "../../utils/cn.js";
|
|
6
6
|
import { FullscreenSwitchController } from "../../utils/fullscreen-switch.js";
|
|
7
|
+
import { InteractiveSkeleton, TextLineSkeleton } from "../loading/unified-skeleton.js";
|
|
7
8
|
import { Button } from "../ui/button/button.js";
|
|
8
9
|
import { useLoadingScope } from "../ui/loading-scope.js";
|
|
9
10
|
import { EmbedIframe, EmbedLoadingSkeleton } from "./embed-iframe.js";
|
|
11
|
+
const EMBED_VIEWER_SKELETON_ACTIONS = 1;
|
|
10
12
|
function EmbedViewerFrame({
|
|
11
13
|
icon,
|
|
12
14
|
title,
|
|
13
15
|
titleVariant = "h3",
|
|
14
16
|
actions,
|
|
15
17
|
src,
|
|
16
|
-
|
|
18
|
+
loading: loadingGiven = false,
|
|
19
|
+
resolving = false,
|
|
17
20
|
emptyIcon,
|
|
18
21
|
emptyMessage = "Content not available",
|
|
19
22
|
height,
|
|
20
23
|
allow,
|
|
21
24
|
allowFullScreen,
|
|
22
|
-
|
|
25
|
+
iframeLoading,
|
|
23
26
|
sandbox,
|
|
24
27
|
className,
|
|
25
|
-
fullscreenControl
|
|
28
|
+
fullscreenControl,
|
|
29
|
+
loadingActionCount = EMBED_VIEWER_SKELETON_ACTIONS
|
|
26
30
|
}) {
|
|
27
|
-
const
|
|
31
|
+
const loadingForm = useLoadingScope() || loadingGiven;
|
|
32
|
+
const isLoading = loadingForm || resolving;
|
|
28
33
|
const frameRef = useRef(null);
|
|
29
34
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
30
35
|
const controllerRef = useRef(null);
|
|
@@ -57,9 +62,27 @@ function EmbedViewerFrame({
|
|
|
57
62
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 content-sm:flex-row content-sm:items-center content-sm:justify-between", children: [
|
|
58
63
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
59
64
|
icon,
|
|
60
|
-
|
|
65
|
+
loadingForm ? (
|
|
66
|
+
// The document is being read: its name is not known yet. (A viewer still resolving its frame, with a
|
|
67
|
+
// known title, keeps it.)
|
|
68
|
+
/* @__PURE__ */ jsx(TextLineSkeleton, { type: titleVariant, className: "w-48 max-w-full" })
|
|
69
|
+
) : titleVariant === "h3" ? /* @__PURE__ */ jsx("h2", { className: "truncate text-ods-text-primary text-h3", children: title }) : /* @__PURE__ */ jsx("span", { className: "truncate font-semibold text-ods-text-primary text-h6", children: title })
|
|
61
70
|
] }),
|
|
62
|
-
|
|
71
|
+
loadingForm ? (
|
|
72
|
+
// The actions point at the document being read: each its button's loading form, in the actions' row.
|
|
73
|
+
/* @__PURE__ */ jsx("div", { className: "flex w-full items-center gap-2 content-sm:w-auto", children: Array.from({ length: loadingActionCount }, (_, i) => (
|
|
74
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: loading buttons never reorder
|
|
75
|
+
/* @__PURE__ */ jsx(
|
|
76
|
+
InteractiveSkeleton.Button,
|
|
77
|
+
{
|
|
78
|
+
"data-loading-item": true,
|
|
79
|
+
size: "small-legacy",
|
|
80
|
+
className: "flex-1 content-sm:flex-initial"
|
|
81
|
+
},
|
|
82
|
+
i
|
|
83
|
+
)
|
|
84
|
+
)) })
|
|
85
|
+
) : fullscreenControl && src ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-[var(--spacing-system-xsf)] content-sm:flex-row content-sm:items-center", children: [
|
|
63
86
|
actions,
|
|
64
87
|
/* @__PURE__ */ jsx(
|
|
65
88
|
Button,
|
|
@@ -83,7 +106,7 @@ function EmbedViewerFrame({
|
|
|
83
106
|
height: isFullscreen ? "calc(100vh - 96px)" : height,
|
|
84
107
|
allow,
|
|
85
108
|
allowFullScreen,
|
|
86
|
-
|
|
109
|
+
iframeLoading,
|
|
87
110
|
sandbox
|
|
88
111
|
}
|
|
89
112
|
) : isLoading ? (
|
|
@@ -117,5 +140,6 @@ function EmbedViewerFrame({
|
|
|
117
140
|
);
|
|
118
141
|
}
|
|
119
142
|
export {
|
|
143
|
+
EMBED_VIEWER_SKELETON_ACTIONS,
|
|
120
144
|
EmbedViewerFrame
|
|
121
145
|
};
|
|
@@ -10,7 +10,9 @@ export interface FigmaEmbedProps {
|
|
|
10
10
|
*/
|
|
11
11
|
height?: string;
|
|
12
12
|
/** iframe loading strategy. Defaults to `"lazy"`; the data-room viewer passes `"eager"`. */
|
|
13
|
-
|
|
13
|
+
iframeLoading?: 'eager' | 'lazy';
|
|
14
|
+
/** The document is being read: the embed draws its loading form. A loading scope does the same. */
|
|
15
|
+
loading?: boolean;
|
|
14
16
|
}
|
|
15
17
|
/**
|
|
16
18
|
* Single source of truth for every Figma surface — the data-room document viewer
|
|
@@ -26,5 +28,5 @@ export interface FigmaEmbedProps {
|
|
|
26
28
|
* plain ReactNode) — flipping it recomputes `embedSrc`, and the frame's
|
|
27
29
|
* `EmbedIframe` remounts on the new src exactly as before the extraction.
|
|
28
30
|
*/
|
|
29
|
-
export declare function FigmaEmbed({ url, title, height, loading }: FigmaEmbedProps): import("react").JSX.Element;
|
|
31
|
+
export declare function FigmaEmbed({ url, title, height, iframeLoading, loading }: FigmaEmbedProps): import("react").JSX.Element;
|
|
30
32
|
//# sourceMappingURL=figma-embed.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"figma-embed.d.ts","sourceRoot":"","sources":["../../../src/components/embeds/figma-embed.tsx"],"names":[],"mappings":"AASA,MAAM,WAAW,eAAe;IAC9B,4FAA4F;IAC5F,GAAG,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,
|
|
1
|
+
{"version":3,"file":"figma-embed.d.ts","sourceRoot":"","sources":["../../../src/components/embeds/figma-embed.tsx"],"names":[],"mappings":"AASA,MAAM,WAAW,eAAe;IAC9B,4FAA4F;IAC5F,GAAG,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,mGAAmG;IACnG,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAgDD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,aAAsB,EAAE,OAAe,EAAE,EAAE,eAAe,+BAoD1G"}
|
|
@@ -20,7 +20,7 @@ function SlidesViewToggle({ view, onChange }) {
|
|
|
20
20
|
if (v && v !== view) onChange(v);
|
|
21
21
|
},
|
|
22
22
|
"aria-label": "Figma slides view mode",
|
|
23
|
-
className: "flex shrink-0 items-center gap-0.5 rounded-lg border border-ods-border bg-ods-card p-0.5",
|
|
23
|
+
className: "flex h-10 shrink-0 items-center gap-0.5 rounded-lg border border-ods-border bg-ods-card p-0.5",
|
|
24
24
|
children: options.map(({ key, label, Icon }) => {
|
|
25
25
|
const active = view === key;
|
|
26
26
|
return /* @__PURE__ */ jsxs(
|
|
@@ -28,7 +28,7 @@ function SlidesViewToggle({ view, onChange }) {
|
|
|
28
28
|
{
|
|
29
29
|
value: key,
|
|
30
30
|
"aria-label": label,
|
|
31
|
-
className: `flex items-center gap-1.5 rounded-md px-2.5 py-1 transition-colors text-h6 ${active ? "bg-ods-accent text-ods-text-on-accent" : "text-ods-text-secondary hover:bg-ods-bg-hover hover:text-ods-text-primary"}`,
|
|
31
|
+
className: `flex h-full items-center gap-1.5 rounded-md px-2.5 py-1 transition-colors text-h6 ${active ? "bg-ods-accent text-ods-text-on-accent" : "text-ods-text-secondary hover:bg-ods-bg-hover hover:text-ods-text-primary"}`,
|
|
32
32
|
children: [
|
|
33
33
|
/* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 shrink-0" }),
|
|
34
34
|
label
|
|
@@ -40,7 +40,7 @@ function SlidesViewToggle({ view, onChange }) {
|
|
|
40
40
|
}
|
|
41
41
|
);
|
|
42
42
|
}
|
|
43
|
-
function FigmaEmbed({ url, title, height,
|
|
43
|
+
function FigmaEmbed({ url, title, height, iframeLoading = "lazy", loading = false }) {
|
|
44
44
|
const [view, setView] = useState("present");
|
|
45
45
|
const isSlides = url ? isFigmaSlidesUrl(url) : false;
|
|
46
46
|
const embedSrc = url ? toFigmaEmbedUrl(url, { slidesView: view }) : null;
|
|
@@ -82,6 +82,7 @@ function FigmaEmbed({ url, title, height, loading = "lazy" }) {
|
|
|
82
82
|
] }),
|
|
83
83
|
src: embedSrc,
|
|
84
84
|
allow: "clipboard-write; clipboard-read; fullscreen",
|
|
85
|
+
iframeLoading,
|
|
85
86
|
loading,
|
|
86
87
|
height,
|
|
87
88
|
allowFullScreen: true,
|