@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.
Files changed (137) hide show
  1. package/dist/build/export-map.json +1 -1
  2. package/dist/{chunk-MWYEROAP.cjs → chunk-2QZUTNL3.cjs} +55 -55
  3. package/dist/{chunk-YXKAHQYS.cjs → chunk-533QK4R6.cjs} +2 -1
  4. package/dist/{chunk-5HOWR4TG.cjs → chunk-5CBI2ZYV.cjs} +5 -5
  5. package/dist/{chunk-NYT6IBIX.cjs → chunk-5PIR77V5.cjs} +4 -4
  6. package/dist/{chunk-IIUZE73M.cjs → chunk-6AJYGXXS.cjs} +14 -14
  7. package/dist/{chunk-VW4446JR.cjs → chunk-7ICHJVAT.cjs} +16 -16
  8. package/dist/{chunk-U7UBYJEZ.cjs → chunk-BU2PSRAS.cjs} +5 -5
  9. package/dist/{chunk-IKOL6NJY.cjs → chunk-CAGNWDVJ.cjs} +11 -1
  10. package/dist/{chunk-O4BXHCMK.cjs → chunk-FRG724DU.cjs} +2 -2
  11. package/dist/{chunk-YAW7CHLV.cjs → chunk-FXLROQUT.cjs} +41 -38
  12. package/dist/{chunk-IUZVOQXP.cjs → chunk-GAYLAA3L.cjs} +45 -45
  13. package/dist/{chunk-7YJQTQPV.cjs → chunk-IG6ROHPS.cjs} +46 -46
  14. package/dist/{chunk-INA2FX2N.cjs → chunk-IHY7E4EX.cjs} +2 -2
  15. package/dist/{chunk-Y2ZWWIUA.cjs → chunk-IN3LA2FU.cjs} +2 -2
  16. package/dist/{chunk-74Z34I2C.cjs → chunk-IPGGSFR7.cjs} +6 -6
  17. package/dist/{chunk-7DW3LZ52.cjs → chunk-JWIITCVB.cjs} +94 -173
  18. package/dist/{chunk-OCJXOSIH.cjs → chunk-LGYPCUHO.cjs} +32 -32
  19. package/dist/{chunk-7LE4HWHA.cjs → chunk-OHHDX3Z4.cjs} +24 -24
  20. package/dist/{chunk-C3WZXOZJ.cjs → chunk-QJER2ZNA.cjs} +3 -3
  21. package/dist/{chunk-GASFYPGH.cjs → chunk-R5JPZ6TY.cjs} +14 -14
  22. package/dist/{chunk-QUSCSYHJ.cjs → chunk-TX4NTH22.cjs} +45 -26
  23. package/dist/{chunk-Y4BG7SPX.cjs → chunk-VRWBJL7B.cjs} +66 -66
  24. package/dist/{chunk-2V6FCVUL.cjs → chunk-XKOL5CNU.cjs} +449 -390
  25. package/dist/{chunk-I3YRYS23.cjs → chunk-ZDSC3GFX.cjs} +38 -12
  26. package/dist/{cloud-tenants-YAZHLPOQ.cjs → cloud-tenants-TVB3DT3J.cjs} +8 -8
  27. package/dist/components/case-studies/index.cjs +22 -22
  28. package/dist/components/chat/entity-cards/dispatch.d.ts.map +1 -1
  29. package/dist/components/chat/entity-cards/dispatch.js +1 -0
  30. package/dist/components/chat/index.cjs +5 -5
  31. package/dist/components/contact/index.cjs +9 -9
  32. package/dist/components/docs/doc-viewer.d.ts +7 -7
  33. package/dist/components/docs/doc-viewer.d.ts.map +1 -1
  34. package/dist/components/docs/doc-viewer.js +29 -16
  35. package/dist/components/docs/docs-hub-page.d.ts +1 -1
  36. package/dist/components/docs/docs-hub-page.d.ts.map +1 -1
  37. package/dist/components/docs/docs-hub-page.js +4 -11
  38. package/dist/components/docs/index.cjs +12 -12
  39. package/dist/components/docs/use-document-tree.d.ts.map +1 -1
  40. package/dist/components/docs/use-document-tree.js +24 -24
  41. package/dist/components/embeds/claude-embed.d.ts +2 -2
  42. package/dist/components/embeds/claude-embed.d.ts.map +1 -1
  43. package/dist/components/embeds/claude-embed.js +3 -3
  44. package/dist/components/embeds/embed-iframe.d.ts +5 -3
  45. package/dist/components/embeds/embed-iframe.d.ts.map +1 -1
  46. package/dist/components/embeds/embed-iframe.js +4 -3
  47. package/dist/components/embeds/embed-viewer-frame.d.ts +14 -9
  48. package/dist/components/embeds/embed-viewer-frame.d.ts.map +1 -1
  49. package/dist/components/embeds/embed-viewer-frame.js +31 -7
  50. package/dist/components/embeds/figma-embed.d.ts +4 -2
  51. package/dist/components/embeds/figma-embed.d.ts.map +1 -1
  52. package/dist/components/embeds/figma-embed.js +4 -3
  53. package/dist/components/embeds/file-download-card.d.ts +3 -1
  54. package/dist/components/embeds/file-download-card.d.ts.map +1 -1
  55. package/dist/components/embeds/file-download-card.js +18 -3
  56. package/dist/components/embeds/google-sheets-viewer.d.ts +3 -1
  57. package/dist/components/embeds/google-sheets-viewer.d.ts.map +1 -1
  58. package/dist/components/embeds/google-sheets-viewer.js +7 -4
  59. package/dist/components/embeds/index.cjs +9 -9
  60. package/dist/components/embeds/pdf-viewer.d.ts +3 -1
  61. package/dist/components/embeds/pdf-viewer.d.ts.map +1 -1
  62. package/dist/components/embeds/pdf-viewer.js +7 -2
  63. package/dist/components/faq/index.cjs +10 -10
  64. package/dist/components/features/index.cjs +10 -8
  65. package/dist/components/features/software/index.d.ts +1 -1
  66. package/dist/components/features/software/index.d.ts.map +1 -1
  67. package/dist/components/features/software/index.js +2 -0
  68. package/dist/components/features/software/software-action-copy.d.ts.map +1 -1
  69. package/dist/components/features/software/software-action-copy.js +6 -12
  70. package/dist/components/features/software/software-action-form.d.ts +7 -1
  71. package/dist/components/features/software/software-action-form.d.ts.map +1 -1
  72. package/dist/components/features/software/software-action-form.js +11 -3
  73. package/dist/components/features/software/update-settings-fields.d.ts +12 -1
  74. package/dist/components/features/software/update-settings-fields.d.ts.map +1 -1
  75. package/dist/components/features/software/update-settings-fields.js +57 -29
  76. package/dist/components/help-center-pages/index.cjs +87 -87
  77. package/dist/components/index.cjs +52 -50
  78. package/dist/components/meeting-scheduler/index.cjs +40 -40
  79. package/dist/components/navigation/index.cjs +11 -11
  80. package/dist/components/onboarding-guides/index.cjs +11 -11
  81. package/dist/components/product-demo/index.cjs +18 -18
  82. package/dist/components/related-content/index.cjs +4 -4
  83. package/dist/components/tickets/index.cjs +13 -13
  84. package/dist/components/ui/index.cjs +8 -8
  85. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +1 -1
  86. package/dist/components/ui/markdown/rich/rich-markdown-renderer.js +7 -3
  87. package/dist/components/ui/page-actions.d.ts.map +1 -1
  88. package/dist/components/ui/page-actions.js +11 -1
  89. package/dist/{devices-IZROCLFK.cjs → devices-NGCTSXIU.cjs} +9 -9
  90. package/dist/{embeddable-chat-ETW6S22E.cjs → embeddable-chat-322NDFP5.cjs} +74 -74
  91. package/dist/index.cjs +18 -12
  92. package/dist/{knowledge-4IRWLTNW.cjs → knowledge-75PO5DYS.cjs} +9 -9
  93. package/dist/{logs-EFDGY5IO.cjs → logs-PZESOAIG.cjs} +15 -15
  94. package/dist/{policies-3KEXZ5BP.cjs → policies-6XNMBFWO.cjs} +12 -12
  95. package/dist/{remote-session-NT4NG7EF.cjs → remote-session-Q2FIBCGT.cjs} +4 -4
  96. package/dist/{scripts-PCGTZLZL.cjs → scripts-B3JW6TPF.cjs} +15 -15
  97. package/dist/{software-update-YCDNVFJE.cjs → software-update-NWP542J7.cjs} +12 -12
  98. package/dist/types/doc-source.d.ts +2 -2
  99. package/dist/types/doc-source.d.ts.map +1 -1
  100. package/dist/utils/doc-tree-nav.d.ts +7 -0
  101. package/dist/utils/doc-tree-nav.d.ts.map +1 -1
  102. package/dist/utils/doc-tree-nav.js +19 -0
  103. package/dist/utils/index.cjs +25 -2
  104. package/dist/utils/list-url.d.ts.map +1 -1
  105. package/dist/utils/list-url.js +2 -1
  106. package/dist/utils/source-grouping.d.ts +2 -2
  107. package/dist/utils/source-grouping.d.ts.map +1 -1
  108. package/dist/utils/source-grouping.js +1 -1
  109. package/dist/utils/source-icons.d.ts.map +1 -1
  110. package/dist/utils/source-icons.js +3 -0
  111. package/package.json +1 -1
  112. package/src/components/chat/entity-cards/dispatch.tsx +3 -0
  113. package/src/components/docs/doc-viewer.tsx +56 -35
  114. package/src/components/docs/docs-hub-page.tsx +13 -37
  115. package/src/components/docs/use-document-tree.ts +33 -23
  116. package/src/components/embeds/claude-embed.tsx +4 -4
  117. package/src/components/embeds/embed-iframe.tsx +8 -5
  118. package/src/components/embeds/embed-viewer-frame.tsx +43 -15
  119. package/src/components/embeds/figma-embed.tsx +9 -4
  120. package/src/components/embeds/file-download-card.tsx +28 -4
  121. package/src/components/embeds/google-sheets-viewer.tsx +9 -3
  122. package/src/components/embeds/pdf-viewer.tsx +12 -2
  123. package/src/components/features/software/index.ts +1 -0
  124. package/src/components/features/software/software-action-copy.ts +19 -12
  125. package/src/components/features/software/software-action-form.tsx +16 -3
  126. package/src/components/features/software/update-settings-fields.tsx +104 -32
  127. package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +4 -0
  128. package/src/components/ui/page-actions.tsx +19 -2
  129. package/src/types/doc-source.ts +2 -2
  130. package/src/utils/doc-tree-nav.ts +27 -0
  131. package/src/utils/list-url.ts +2 -1
  132. package/src/utils/source-grouping.ts +2 -2
  133. package/src/utils/source-icons.ts +3 -0
  134. package/dist/components/docs/skeletons.d.ts +0 -25
  135. package/dist/components/docs/skeletons.d.ts.map +0 -1
  136. package/dist/components/docs/skeletons.js +0 -83
  137. package/src/components/docs/skeletons.tsx +0 -131
@@ -99,7 +99,8 @@ const BUILDERS: Record<string, (ids: string[], base: string) => string> = {
99
99
  slack_message: (ids, b) => `${b}/api/slack-community/messages?ids=${ids.join(',')}`,
100
100
  hubspot_ticket: (ids, b) => `${b}/api/tickets/internal?ids=${ids.join(',')}`,
101
101
  hubspot_ticket_anon: (ids, b) => `${b}/api/tickets/known-issues?ids=${ids.join(',')}`,
102
- data_room_doc: (ids, b) => `${b}/api/data-room/documents?ids=${ids.join(',')}`,
102
+ data_room_doc: (ids, b) => `${b}/api/libraries/data-room/documents?ids=${ids.join(',')}`,
103
+ policy_doc: (ids, b) => `${b}/api/libraries/company-policies/documents?ids=${ids.join(',')}`,
103
104
  markdown: (ids, b) => `${b}/api/docs/pages?ids=${ids.join(',')}`,
104
105
  financial_kpi: (ids, b) => `${b}/api/financials/kpis?ids=${ids.join(',')}`,
105
106
  cap_table: (ids, b) => `${b}/api/financials/cap-table?ids=${ids.join(',')}`,
@@ -27,13 +27,13 @@ import { defaultDocumentTypeForTableId, getSourceLabel } from './source-icons';
27
27
 
28
28
  /**
29
29
  * Doc-table documentTypes: whole documents with their own viewer (markdown =
30
- * product docs, data_room_doc = data room). They carry an in-app `path` (handed
30
+ * product docs, data_room_doc = data room, policy_doc = company policies). They carry an in-app `path` (handed
31
31
  * to the host's composer as the slug), and a server never folds them
32
32
  * into one citation (`groupsByTable`); the strip still draws them as one chip
33
33
  * per table. The hub's per-source contract test pins this list to its
34
34
  * doc-table configs.
35
35
  */
36
- export const DOC_TABLE_TYPES = ['markdown', 'data_room_doc'] as const;
36
+ export const DOC_TABLE_TYPES = ['markdown', 'data_room_doc', 'policy_doc'] as const;
37
37
 
38
38
  /**
39
39
  * Which tables a SERVER folds into one citation: rows of a knowledge table
@@ -29,6 +29,7 @@ export const SOURCE_ICON_NAMES: Record<string, string> = {
29
29
  // Doc tables
30
30
  'openframe-docs': 'openframe',
31
31
  'data-room-docs': 'shield',
32
+ 'company-policies': 'book-open',
32
33
 
33
34
  // CMS / programs
34
35
  'blog-posts': 'newspaper',
@@ -136,6 +137,7 @@ export const SOURCE_LABELS_BY_TABLE: Record<string, string> = {
136
137
  // Doc tables
137
138
  'openframe-docs': 'OpenFrame Docs',
138
139
  'data-room-docs': 'Data Room',
140
+ 'company-policies': 'Company Policies',
139
141
 
140
142
  // CMS / programs
141
143
  'blog-posts': 'Blog Posts',
@@ -242,6 +244,7 @@ export const DEFAULT_DOCUMENT_TYPE_TO_TABLE_ID: Record<string, string> = {
242
244
  // Doc tables
243
245
  markdown: 'openframe-docs',
244
246
  data_room_doc: 'data-room-docs',
247
+ policy_doc: 'company-policies',
245
248
 
246
249
  // CMS / programs
247
250
  blog_post: 'blog-posts',
@@ -1,25 +0,0 @@
1
- export declare function MarkdownSkeleton({ region, }?: {
2
- /** The loading state announces itself (`LoadingRegion`). `false` inside another loading region. Default `true`. */
3
- region?: boolean;
4
- }): import("react").JSX.Element;
5
- /**
6
- * Embed-style skeleton — matches the iframe loading state for `pdf`,
7
- * `google_sheet`, `figma`, and `file` document types. Used by
8
- * `<DocsHubPage>` as the default for non-markdown documentTypes.
9
- *
10
- * The skeleton is documentType-aware so its layout matches the actual
11
- * viewer that will replace it:
12
- * - `pdf` → header with title + TWO buttons (Preview, Download)
13
- * - `google_sheet`/`figma` → header with title + ONE button/toggle
14
- * - `file` → centered FileDownloadCard-style box
15
- * - undefined / others → generic (1-button header)
16
- */
17
- export interface EmbedSkeletonProps {
18
- /** When provided, the header layout matches the eventual viewer's
19
- * button count + arrangement, so the layout doesn't shift on load. */
20
- documentType?: 'pdf' | 'google_sheet' | 'figma' | 'file' | string;
21
- /** The loading state announces itself (`LoadingRegion`). `false` inside another loading region. Default `true`. */
22
- region?: boolean;
23
- }
24
- export declare function EmbedSkeleton({ documentType, region }?: EmbedSkeletonProps): import("react").JSX.Element;
25
- //# sourceMappingURL=skeletons.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"skeletons.d.ts","sourceRoot":"","sources":["../../../src/components/docs/skeletons.tsx"],"names":[],"mappings":"AA2BA,wBAAgB,gBAAgB,CAAC,EAC/B,MAAa,GACd,GAAE;IACD,mHAAmH;IACnH,MAAM,CAAC,EAAE,OAAO,CAAC;CACb,+BA2BL;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,kBAAkB;IACjC;2EACuE;IACvE,YAAY,CAAC,EAAE,KAAK,GAAG,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAClE,mHAAmH;IACnH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,aAAa,CAAC,EAAE,YAAY,EAAE,MAAa,EAAE,GAAE,kBAAuB,+BAiDrF"}
@@ -1,83 +0,0 @@
1
- "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
- import { cn } from "../../utils/cn.js";
4
- import { EmbedLoadingSkeleton } from "../embeds/embed-iframe.js";
5
- import { LoadingRegion } from "../loading/loading-region.js";
6
- import { TextLineSkeleton, UnifiedSkeleton } from "../loading/unified-skeleton.js";
7
- import { MARKDOWN_H2_CLASS, MARKDOWN_PARAGRAPH_CLASS } from "../ui/markdown/base-components.js";
8
- import { MARKDOWN_RENDERER_CLASS } from "../ui/markdown/engine.js";
9
- import { TEXT_SIZE_PRESETS } from "../ui/markdown/text-size.js";
10
- const MARKDOWN_SKELETON_BLOCKS = [
11
- { kind: "p", lines: 4 },
12
- { kind: "p", lines: 4 },
13
- { kind: "p", lines: 5 },
14
- { kind: "h2" },
15
- { kind: "p", lines: 4 },
16
- { kind: "p", lines: 5 },
17
- { kind: "h2" },
18
- { kind: "p", lines: 3 },
19
- { kind: "p", lines: 4 }
20
- ];
21
- const MARKDOWN_SKELETON_H2_CLASS = cn(MARKDOWN_H2_CLASS, TEXT_SIZE_PRESETS.default.h2);
22
- const MARKDOWN_SKELETON_P_CLASS = cn(MARKDOWN_PARAGRAPH_CLASS, TEXT_SIZE_PRESETS.default.p);
23
- function MarkdownSkeleton({
24
- region = true
25
- } = {}) {
26
- return (
27
- // The renderer's root class, and its box (no margin of its own, like the rendered body): the document's first fold.
28
- /* @__PURE__ */ jsx(LoadingRegion, { label: "Loading the document", announce: region, className: MARKDOWN_RENDERER_CLASS, children: MARKDOWN_SKELETON_BLOCKS.map(
29
- (block, i) => block.kind === "h2" ? (
30
- // biome-ignore lint/suspicious/noArrayIndexKey: skeleton blocks never reorder
31
- /* @__PURE__ */ jsx("h2", { className: MARKDOWN_SKELETON_H2_CLASS, "aria-hidden": true, children: /* @__PURE__ */ jsx(TextLineSkeleton, { type: "inherit", as: "span", className: "w-1/3" }) }, i)
32
- ) : (
33
- // The last block ends the body with no margin, like the rendered one. Its own `last:mb-0` does not apply here:
34
- // the region's status line follows the blocks, so the paragraph is not the last child.
35
- // biome-ignore lint/suspicious/noArrayIndexKey: skeleton blocks never reorder
36
- /* @__PURE__ */ jsx(
37
- "p",
38
- {
39
- className: cn(MARKDOWN_SKELETON_P_CLASS, i === MARKDOWN_SKELETON_BLOCKS.length - 1 && "mb-0"),
40
- "aria-hidden": true,
41
- children: /* @__PURE__ */ jsx(TextLineSkeleton, { type: "inherit", as: "span", lines: block.lines, className: "w-full" })
42
- },
43
- i
44
- )
45
- )
46
- ) })
47
- );
48
- }
49
- function EmbedSkeleton({ documentType, region = true } = {}) {
50
- if (documentType === "file") {
51
- return /* @__PURE__ */ jsx(
52
- LoadingRegion,
53
- {
54
- label: "Loading the document",
55
- announce: region,
56
- className: "flex flex-col items-center justify-center py-16",
57
- children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-md space-y-4 rounded-xl border border-ods-border bg-ods-card p-8 text-center", children: [
58
- /* @__PURE__ */ jsx(UnifiedSkeleton, { className: "mx-auto h-16 w-16 rounded" }),
59
- /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
60
- /* @__PURE__ */ jsx(UnifiedSkeleton, { className: "mx-auto h-5 w-2/3 rounded" }),
61
- /* @__PURE__ */ jsx(UnifiedSkeleton, { className: "mx-auto h-4 w-1/2 rounded" })
62
- ] }),
63
- /* @__PURE__ */ jsx(UnifiedSkeleton, { className: "h-10 w-full rounded" })
64
- ] })
65
- }
66
- );
67
- }
68
- const buttonCount = documentType === "pdf" ? 2 : 1;
69
- return /* @__PURE__ */ jsxs(LoadingRegion, { label: "Loading the document", announce: region, className: "space-y-4", children: [
70
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 content-sm:flex-row content-sm:items-center content-sm:justify-between", children: [
71
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
72
- /* @__PURE__ */ jsx(UnifiedSkeleton, { className: "h-5 w-5 shrink-0 rounded" }),
73
- /* @__PURE__ */ jsx(UnifiedSkeleton, { className: "h-6 w-2/3 rounded" })
74
- ] }),
75
- /* @__PURE__ */ jsx("div", { className: "flex w-full items-center gap-2 content-sm:w-auto", children: Array.from({ length: buttonCount }).map((_, i) => /* @__PURE__ */ jsx(UnifiedSkeleton, { className: "h-10 w-full flex-1 rounded content-sm:w-32 content-sm:flex-initial" }, i)) })
76
- ] }),
77
- /* @__PURE__ */ jsx(EmbedLoadingSkeleton, { region: false })
78
- ] });
79
- }
80
- export {
81
- EmbedSkeleton,
82
- MarkdownSkeleton
83
- };
@@ -1,131 +0,0 @@
1
- import { cn } from '../../utils/cn';
2
- import { EmbedLoadingSkeleton } from '../embeds/embed-iframe';
3
- import { LoadingRegion } from '../loading/loading-region';
4
- import { TextLineSkeleton, UnifiedSkeleton } from '../loading/unified-skeleton';
5
- import { MARKDOWN_H2_CLASS, MARKDOWN_PARAGRAPH_CLASS } from '../ui/markdown/base-components';
6
- import { MARKDOWN_RENDERER_CLASS } from '../ui/markdown/engine';
7
- import { TEXT_SIZE_PRESETS } from '../ui/markdown/text-size';
8
- /**
9
- * Text-style skeleton — matches a rendered markdown article layout.
10
- * Used by `<DocsHubPage>` as the default for `markdown` (and unknown
11
- * document types). Embedders can override via `renderSkeleton`.
12
- */
13
- /** Paragraphs and headings the markdown skeleton draws (a document's first fold), with each paragraph's lines. */
14
- const MARKDOWN_SKELETON_BLOCKS = [
15
- { kind: 'p', lines: 4 },
16
- { kind: 'p', lines: 4 },
17
- { kind: 'p', lines: 5 },
18
- { kind: 'h2' },
19
- { kind: 'p', lines: 4 },
20
- { kind: 'p', lines: 5 },
21
- { kind: 'h2' },
22
- { kind: 'p', lines: 3 },
23
- { kind: 'p', lines: 4 },
24
- ] as const;
25
- const MARKDOWN_SKELETON_H2_CLASS = cn(MARKDOWN_H2_CLASS, TEXT_SIZE_PRESETS.default.h2);
26
- const MARKDOWN_SKELETON_P_CLASS = cn(MARKDOWN_PARAGRAPH_CLASS, TEXT_SIZE_PRESETS.default.p);
27
-
28
- export function MarkdownSkeleton({
29
- region = true,
30
- }: {
31
- /** The loading state announces itself (`LoadingRegion`). `false` inside another loading region. Default `true`. */
32
- region?: boolean;
33
- } = {}) {
34
- // The rendered document's own heading and paragraph elements (the markdown renderer's default preset), each line a
35
- // bar of the element's line box.
36
- return (
37
- // The renderer's root class, and its box (no margin of its own, like the rendered body): the document's first fold.
38
- <LoadingRegion label="Loading the document" announce={region} className={MARKDOWN_RENDERER_CLASS}>
39
- {MARKDOWN_SKELETON_BLOCKS.map((block, i) =>
40
- block.kind === 'h2' ? (
41
- // biome-ignore lint/suspicious/noArrayIndexKey: skeleton blocks never reorder
42
- <h2 key={i} className={MARKDOWN_SKELETON_H2_CLASS} aria-hidden>
43
- <TextLineSkeleton type="inherit" as="span" className="w-1/3" />
44
- </h2>
45
- ) : (
46
- // The last block ends the body with no margin, like the rendered one. Its own `last:mb-0` does not apply here:
47
- // the region's status line follows the blocks, so the paragraph is not the last child.
48
- // biome-ignore lint/suspicious/noArrayIndexKey: skeleton blocks never reorder
49
- <p
50
- key={i}
51
- className={cn(MARKDOWN_SKELETON_P_CLASS, i === MARKDOWN_SKELETON_BLOCKS.length - 1 && 'mb-0')}
52
- aria-hidden
53
- >
54
- <TextLineSkeleton type="inherit" as="span" lines={block.lines} className="w-full" />
55
- </p>
56
- ),
57
- )}
58
- </LoadingRegion>
59
- );
60
- }
61
-
62
- /**
63
- * Embed-style skeleton — matches the iframe loading state for `pdf`,
64
- * `google_sheet`, `figma`, and `file` document types. Used by
65
- * `<DocsHubPage>` as the default for non-markdown documentTypes.
66
- *
67
- * The skeleton is documentType-aware so its layout matches the actual
68
- * viewer that will replace it:
69
- * - `pdf` → header with title + TWO buttons (Preview, Download)
70
- * - `google_sheet`/`figma` → header with title + ONE button/toggle
71
- * - `file` → centered FileDownloadCard-style box
72
- * - undefined / others → generic (1-button header)
73
- */
74
- export interface EmbedSkeletonProps {
75
- /** When provided, the header layout matches the eventual viewer's
76
- * button count + arrangement, so the layout doesn't shift on load. */
77
- documentType?: 'pdf' | 'google_sheet' | 'figma' | 'file' | string;
78
- /** The loading state announces itself (`LoadingRegion`). `false` inside another loading region. Default `true`. */
79
- region?: boolean;
80
- }
81
-
82
- export function EmbedSkeleton({ documentType, region = true }: EmbedSkeletonProps = {}) {
83
- // Centered card shape for the `file` documentType — matches
84
- // `<FileDownloadCard>`'s `flex flex-col items-center justify-center py-16`
85
- // + bordered card with icon, name, type/size row, Download button.
86
- if (documentType === 'file') {
87
- return (
88
- <LoadingRegion
89
- label="Loading the document"
90
- announce={region}
91
- className="flex flex-col items-center justify-center py-16"
92
- >
93
- <div className="w-full max-w-md space-y-4 rounded-xl border border-ods-border bg-ods-card p-8 text-center">
94
- <UnifiedSkeleton className="mx-auto h-16 w-16 rounded" />
95
- <div className="space-y-2">
96
- <UnifiedSkeleton className="mx-auto h-5 w-2/3 rounded" />
97
- <UnifiedSkeleton className="mx-auto h-4 w-1/2 rounded" />
98
- </div>
99
- <UnifiedSkeleton className="h-10 w-full rounded" />
100
- </div>
101
- </LoadingRegion>
102
- );
103
- }
104
-
105
- // PDF viewer has TWO buttons (Preview + Download); Sheets / Figma
106
- // render ONE (Open / view-toggle). Default to one for unknown types.
107
- const buttonCount = documentType === 'pdf' ? 2 : 1;
108
-
109
- return (
110
- <LoadingRegion label="Loading the document" announce={region} className="space-y-4">
111
- {/* Header — matches the actual viewer's
112
- * `flex flex-col gap-3 content-sm:flex-row content-sm:items-center content-sm:justify-between`
113
- * (mobile-stacked, desktop-row). */}
114
- <div className="flex flex-col gap-3 content-sm:flex-row content-sm:items-center content-sm:justify-between">
115
- {/* Left: icon + title */}
116
- <div className="flex min-w-0 flex-1 items-center gap-2">
117
- <UnifiedSkeleton className="h-5 w-5 shrink-0 rounded" />
118
- <UnifiedSkeleton className="h-6 w-2/3 rounded" />
119
- </div>
120
- {/* Right: 1 or 2 buttons. Mobile = full-width; desktop = auto. */}
121
- <div className="flex w-full items-center gap-2 content-sm:w-auto">
122
- {Array.from({ length: buttonCount }).map((_, i) => (
123
- <UnifiedSkeleton key={i} className="h-10 w-full flex-1 rounded content-sm:w-32 content-sm:flex-initial" />
124
- ))}
125
- </div>
126
- </div>
127
- {/* Body: the iframe viewer's own loading box (its default `calc(100vh - 250px)` height). */}
128
- <EmbedLoadingSkeleton region={false} />
129
- </LoadingRegion>
130
- );
131
- }