@k2b/ui 0.17.0 → 0.19.0

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 (228) hide show
  1. package/README.md +3 -2
  2. package/dist/browser/actions/ContextMenu.js +3 -1
  3. package/dist/browser/actions/ContextMenu.js.map +1 -1
  4. package/dist/browser/actions/Dropdown.js +91 -46
  5. package/dist/browser/actions/Dropdown.js.map +1 -1
  6. package/dist/browser/actions/FilterChip.js +4 -1
  7. package/dist/browser/actions/FilterChip.js.map +1 -1
  8. package/dist/browser/chat/ChatComposer.js +1311 -565
  9. package/dist/browser/chat/ChatComposer.js.map +1 -1
  10. package/dist/browser/chat/ChatPrimitives.js +9 -6
  11. package/dist/browser/chat/ChatPrimitives.js.map +1 -1
  12. package/dist/browser/chat/chat-behavior.js +9 -0
  13. package/dist/browser/chat/chat-behavior.js.map +1 -1
  14. package/dist/browser/chat/index.js.map +1 -1
  15. package/dist/browser/chat/types.js.map +1 -1
  16. package/dist/browser/content/Calendar.js +579 -533
  17. package/dist/browser/content/Calendar.js.map +1 -1
  18. package/dist/browser/content/FileView.js +62 -36
  19. package/dist/browser/content/FileView.js.map +1 -1
  20. package/dist/browser/content/Lightbox.js +76 -40
  21. package/dist/browser/content/Lightbox.js.map +1 -1
  22. package/dist/browser/content/MarkdownView.js +9 -3
  23. package/dist/browser/content/MarkdownView.js.map +1 -1
  24. package/dist/browser/content/PdfPreview.js +146 -79
  25. package/dist/browser/content/PdfPreview.js.map +1 -1
  26. package/dist/browser/content/Timeline.js +1038 -0
  27. package/dist/browser/content/Timeline.js.map +1 -0
  28. package/dist/browser/content/VideoPlayer.js +299 -0
  29. package/dist/browser/content/VideoPlayer.js.map +1 -0
  30. package/dist/browser/content/chart-inspection.js +7 -2
  31. package/dist/browser/content/chart-inspection.js.map +1 -1
  32. package/dist/browser/content/file-view-preview.js +2 -2
  33. package/dist/browser/content/file-view-preview.js.map +1 -1
  34. package/dist/browser/content/index.js +3 -0
  35. package/dist/browser/content/index.js.map +1 -1
  36. package/dist/browser/content/markdown-links.js +178 -0
  37. package/dist/browser/content/markdown-links.js.map +1 -0
  38. package/dist/browser/content/timeline-model.js +579 -0
  39. package/dist/browser/content/timeline-model.js.map +1 -0
  40. package/dist/browser/feedback/dialog-core.js +26 -14
  41. package/dist/browser/feedback/dialog-core.js.map +1 -1
  42. package/dist/browser/inputs/ChoiceChips.js +66 -0
  43. package/dist/browser/inputs/ChoiceChips.js.map +1 -0
  44. package/dist/browser/inputs/ChoiceGroups.js +53 -12
  45. package/dist/browser/inputs/ChoiceGroups.js.map +1 -1
  46. package/dist/browser/inputs/FileDropTarget.js +129 -0
  47. package/dist/browser/inputs/FileDropTarget.js.map +1 -0
  48. package/dist/browser/inputs/FileInputs.js +84 -43
  49. package/dist/browser/inputs/FileInputs.js.map +1 -1
  50. package/dist/browser/inputs/SignatureInput.js +558 -0
  51. package/dist/browser/inputs/SignatureInput.js.map +1 -0
  52. package/dist/browser/inputs/emoji/EmojiPicker.js +841 -0
  53. package/dist/browser/inputs/emoji/EmojiPicker.js.map +1 -0
  54. package/dist/browser/inputs/emoji/emoji-data.js +1903 -0
  55. package/dist/browser/inputs/emoji/emoji-data.js.map +1 -0
  56. package/dist/browser/inputs/emoji/emoji-index.js +209 -0
  57. package/dist/browser/inputs/emoji/emoji-index.js.map +1 -0
  58. package/dist/browser/inputs/emoji/emoji-messages.js +64 -0
  59. package/dist/browser/inputs/emoji/emoji-messages.js.map +1 -0
  60. package/dist/browser/inputs/file-drop.js +338 -0
  61. package/dist/browser/inputs/file-drop.js.map +1 -0
  62. package/dist/browser/inputs/index.js +6 -0
  63. package/dist/browser/inputs/index.js.map +1 -1
  64. package/dist/browser/inputs/markdown/MarkdownEditor.js +72 -78
  65. package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -1
  66. package/dist/browser/inputs/markdown/actions.js +48 -2
  67. package/dist/browser/inputs/markdown/actions.js.map +1 -1
  68. package/dist/browser/inputs/markdown/code-zone.js +38 -2
  69. package/dist/browser/inputs/markdown/code-zone.js.map +1 -1
  70. package/dist/browser/inputs/signature-messages.js +39 -0
  71. package/dist/browser/inputs/signature-messages.js.map +1 -0
  72. package/dist/browser/inputs/signature.js +208 -0
  73. package/dist/browser/inputs/signature.js.map +1 -0
  74. package/dist/browser/internal/render-error.js +49 -0
  75. package/dist/browser/internal/render-error.js.map +1 -0
  76. package/dist/browser/intl/messages.js +205 -4
  77. package/dist/browser/intl/messages.js.map +1 -1
  78. package/dist/browser/layout/AppWorkspace.js +483 -218
  79. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  80. package/dist/browser/layout/FloatingWindow.js +4 -1
  81. package/dist/browser/layout/FloatingWindow.js.map +1 -1
  82. package/dist/browser/layout/Navigation.js +274 -197
  83. package/dist/browser/layout/Navigation.js.map +1 -1
  84. package/dist/browser/layout/SidebarItemPreview.js +5 -1
  85. package/dist/browser/layout/SidebarItemPreview.js.map +1 -1
  86. package/dist/browser/layout/index.js.map +1 -1
  87. package/dist/browser/layout/navigation-model.js +2 -0
  88. package/dist/browser/layout/navigation-model.js.map +1 -1
  89. package/dist/browser/surfaces/NoticeCard.js +47 -44
  90. package/dist/browser/surfaces/NoticeCard.js.map +1 -1
  91. package/dist/browser/surfaces/ResourceCard.js +212 -0
  92. package/dist/browser/surfaces/ResourceCard.js.map +1 -0
  93. package/dist/browser/surfaces/index.js +1 -0
  94. package/dist/browser/surfaces/index.js.map +1 -1
  95. package/dist/licenses/emojibase-data.txt +21 -0
  96. package/dist/ssr/actions/ContextMenu.js +3 -1
  97. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  98. package/dist/ssr/actions/Dropdown.js +49 -12
  99. package/dist/ssr/actions/Dropdown.js.map +1 -1
  100. package/dist/ssr/actions/FilterChip.js +4 -1
  101. package/dist/ssr/actions/FilterChip.js.map +1 -1
  102. package/dist/ssr/chat/ChatComposer.js +823 -221
  103. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  104. package/dist/ssr/chat/ChatPrimitives.js +9 -6
  105. package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
  106. package/dist/ssr/chat/chat-behavior.js +9 -0
  107. package/dist/ssr/chat/chat-behavior.js.map +1 -1
  108. package/dist/ssr/chat/index.js.map +1 -1
  109. package/dist/ssr/chat/types.js.map +1 -1
  110. package/dist/ssr/content/Calendar.js +183 -142
  111. package/dist/ssr/content/Calendar.js.map +1 -1
  112. package/dist/ssr/content/FileView.js +30 -6
  113. package/dist/ssr/content/FileView.js.map +1 -1
  114. package/dist/ssr/content/Lightbox.js +19 -5
  115. package/dist/ssr/content/Lightbox.js.map +1 -1
  116. package/dist/ssr/content/MarkdownView.js +9 -3
  117. package/dist/ssr/content/MarkdownView.js.map +1 -1
  118. package/dist/ssr/content/PdfPreview.js +77 -36
  119. package/dist/ssr/content/PdfPreview.js.map +1 -1
  120. package/dist/ssr/content/Timeline.js +804 -0
  121. package/dist/ssr/content/Timeline.js.map +1 -0
  122. package/dist/ssr/content/VideoPlayer.js +228 -0
  123. package/dist/ssr/content/VideoPlayer.js.map +1 -0
  124. package/dist/ssr/content/chart-inspection.js +7 -2
  125. package/dist/ssr/content/chart-inspection.js.map +1 -1
  126. package/dist/ssr/content/file-view-preview.js +2 -2
  127. package/dist/ssr/content/file-view-preview.js.map +1 -1
  128. package/dist/ssr/content/index.js +3 -0
  129. package/dist/ssr/content/index.js.map +1 -1
  130. package/dist/ssr/content/markdown-links.js +178 -0
  131. package/dist/ssr/content/markdown-links.js.map +1 -0
  132. package/dist/ssr/content/timeline-model.js +579 -0
  133. package/dist/ssr/content/timeline-model.js.map +1 -0
  134. package/dist/ssr/feedback/dialog-core.js +26 -14
  135. package/dist/ssr/feedback/dialog-core.js.map +1 -1
  136. package/dist/ssr/inputs/ChoiceChips.js +66 -0
  137. package/dist/ssr/inputs/ChoiceChips.js.map +1 -0
  138. package/dist/ssr/inputs/ChoiceGroups.js +12 -4
  139. package/dist/ssr/inputs/ChoiceGroups.js.map +1 -1
  140. package/dist/ssr/inputs/FileDropTarget.js +103 -0
  141. package/dist/ssr/inputs/FileDropTarget.js.map +1 -0
  142. package/dist/ssr/inputs/FileInputs.js +49 -12
  143. package/dist/ssr/inputs/FileInputs.js.map +1 -1
  144. package/dist/ssr/inputs/SignatureInput.js +404 -0
  145. package/dist/ssr/inputs/SignatureInput.js.map +1 -0
  146. package/dist/ssr/inputs/emoji/EmojiPicker.js +551 -0
  147. package/dist/ssr/inputs/emoji/EmojiPicker.js.map +1 -0
  148. package/dist/ssr/inputs/emoji/emoji-data.js +1903 -0
  149. package/dist/ssr/inputs/emoji/emoji-data.js.map +1 -0
  150. package/dist/ssr/inputs/emoji/emoji-index.js +209 -0
  151. package/dist/ssr/inputs/emoji/emoji-index.js.map +1 -0
  152. package/dist/ssr/inputs/emoji/emoji-messages.js +64 -0
  153. package/dist/ssr/inputs/emoji/emoji-messages.js.map +1 -0
  154. package/dist/ssr/inputs/file-drop.js +338 -0
  155. package/dist/ssr/inputs/file-drop.js.map +1 -0
  156. package/dist/ssr/inputs/index.js +6 -0
  157. package/dist/ssr/inputs/index.js.map +1 -1
  158. package/dist/ssr/inputs/markdown/MarkdownEditor.js +14 -2
  159. package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -1
  160. package/dist/ssr/inputs/markdown/actions.js +48 -2
  161. package/dist/ssr/inputs/markdown/actions.js.map +1 -1
  162. package/dist/ssr/inputs/markdown/code-zone.js +38 -2
  163. package/dist/ssr/inputs/markdown/code-zone.js.map +1 -1
  164. package/dist/ssr/inputs/signature-messages.js +39 -0
  165. package/dist/ssr/inputs/signature-messages.js.map +1 -0
  166. package/dist/ssr/inputs/signature.js +208 -0
  167. package/dist/ssr/inputs/signature.js.map +1 -0
  168. package/dist/ssr/internal/render-error.js +49 -0
  169. package/dist/ssr/internal/render-error.js.map +1 -0
  170. package/dist/ssr/intl/messages.js +205 -4
  171. package/dist/ssr/intl/messages.js.map +1 -1
  172. package/dist/ssr/layout/AppWorkspace.js +264 -47
  173. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  174. package/dist/ssr/layout/FloatingWindow.js +4 -1
  175. package/dist/ssr/layout/FloatingWindow.js.map +1 -1
  176. package/dist/ssr/layout/Navigation.js +169 -122
  177. package/dist/ssr/layout/Navigation.js.map +1 -1
  178. package/dist/ssr/layout/SidebarItemPreview.js +5 -1
  179. package/dist/ssr/layout/SidebarItemPreview.js.map +1 -1
  180. package/dist/ssr/layout/index.js.map +1 -1
  181. package/dist/ssr/layout/navigation-model.js +2 -0
  182. package/dist/ssr/layout/navigation-model.js.map +1 -1
  183. package/dist/ssr/surfaces/NoticeCard.js +17 -12
  184. package/dist/ssr/surfaces/NoticeCard.js.map +1 -1
  185. package/dist/ssr/surfaces/ResourceCard.js +115 -0
  186. package/dist/ssr/surfaces/ResourceCard.js.map +1 -0
  187. package/dist/ssr/surfaces/index.js +1 -0
  188. package/dist/ssr/surfaces/index.js.map +1 -1
  189. package/dist/styles.css +1 -1
  190. package/dist/types/actions/Dropdown.d.ts +13 -1
  191. package/dist/types/actions/FilterChip.d.ts +5 -0
  192. package/dist/types/chat/ChatComposer.d.ts +24 -1
  193. package/dist/types/chat/ChatPrimitives.d.ts +1 -1
  194. package/dist/types/chat/chat-behavior.d.ts +15 -0
  195. package/dist/types/chat/index.d.ts +1 -1
  196. package/dist/types/chat/types.d.ts +34 -0
  197. package/dist/types/content/Calendar.d.ts +28 -8
  198. package/dist/types/content/Lightbox.d.ts +8 -0
  199. package/dist/types/content/Timeline.d.ts +49 -0
  200. package/dist/types/content/VideoPlayer.d.ts +41 -0
  201. package/dist/types/content/index.d.ts +6 -2
  202. package/dist/types/content/markdown-links.d.ts +66 -0
  203. package/dist/types/content/timeline-model.d.ts +148 -0
  204. package/dist/types/feedback/dialog-core.d.ts +1 -1
  205. package/dist/types/inputs/ChoiceChips.d.ts +20 -0
  206. package/dist/types/inputs/ChoiceGroups.d.ts +11 -2
  207. package/dist/types/inputs/FileDropTarget.d.ts +23 -0
  208. package/dist/types/inputs/FileInputs.d.ts +8 -0
  209. package/dist/types/inputs/SignatureInput.d.ts +22 -0
  210. package/dist/types/inputs/emoji/EmojiPicker.d.ts +42 -0
  211. package/dist/types/inputs/emoji/emoji-data.d.ts +2 -0
  212. package/dist/types/inputs/emoji/emoji-index.d.ts +109 -0
  213. package/dist/types/inputs/emoji/emoji-messages.d.ts +30 -0
  214. package/dist/types/inputs/file-drop.d.ts +80 -0
  215. package/dist/types/inputs/index.d.ts +12 -0
  216. package/dist/types/inputs/markdown/actions.d.ts +4 -0
  217. package/dist/types/inputs/markdown/code-zone.d.ts +7 -0
  218. package/dist/types/inputs/signature-messages.d.ts +11 -0
  219. package/dist/types/inputs/signature.d.ts +72 -0
  220. package/dist/types/internal/render-error.d.ts +13 -0
  221. package/dist/types/intl/messages.d.ts +101 -0
  222. package/dist/types/layout/AppWorkspace.d.ts +38 -0
  223. package/dist/types/layout/SidebarItemPreview.d.ts +2 -0
  224. package/dist/types/layout/index.d.ts +2 -2
  225. package/dist/types/layout/navigation-model.d.ts +18 -0
  226. package/dist/types/surfaces/ResourceCard.d.ts +31 -0
  227. package/dist/types/surfaces/index.d.ts +2 -0
  228. package/package.json +5 -4
@@ -16,11 +16,13 @@ var _tmpl$ = /*#__PURE__*/_$template(`<button type=button class=k2b-button data-
16
16
  _tmpl$3 = /*#__PURE__*/_$template(`<span role=alert class=k2b-content-pdf-preview__notice>`),
17
17
  _tmpl$4 = /*#__PURE__*/_$template(`<div class=k2b-content-pdf-preview__actions><!$><!/><!$><!/><!$><!/><!$><!/>`),
18
18
  _tmpl$5 = /*#__PURE__*/_$template(`<a class=k2b-button data-variant=secondary data-size=sm target=_blank rel=noopener><i class="ti ti-external-link"aria-hidden=true></i><!$><!/>`),
19
- _tmpl$6 = /*#__PURE__*/_$template(`<iframe class=k2b-content-pdf-preview__frame>`),
20
- _tmpl$7 = /*#__PURE__*/_$template(`<button type=button class=k2b-button data-variant=secondary data-size=sm>`),
21
- _tmpl$8 = /*#__PURE__*/_$template(`<h2 class=k2b-content-pdf-preview__title>`),
22
- _tmpl$9 = /*#__PURE__*/_$template(`<section><div class=k2b-content-pdf-preview__toolbar><div class=k2b-content-pdf-preview__heading></div><!$><!/></div><!$><!/>`);
19
+ _tmpl$6 = /*#__PURE__*/_$template(`<div class=k2b-content-pdf-preview__viewer><!$><!/><!$><!/>`),
20
+ _tmpl$7 = /*#__PURE__*/_$template(`<iframe class=k2b-content-pdf-preview__frame>`),
21
+ _tmpl$8 = /*#__PURE__*/_$template(`<button type=button class=k2b-button data-variant=secondary data-size=sm>`),
22
+ _tmpl$9 = /*#__PURE__*/_$template(`<h2 class=k2b-content-pdf-preview__title>`),
23
+ _tmpl$0 = /*#__PURE__*/_$template(`<section><div class=k2b-content-pdf-preview__toolbar><div class=k2b-content-pdf-preview__heading></div><!$><!/></div><!$><!/>`);
23
24
  import { createSignal, onCleanup, onMount, Show } from "solid-js";
25
+ import { announce } from "../feedback/announce";
24
26
  import { resolveUiMessages, useUiMessages } from "../intl/messages";
25
27
  import Placeholder from "../surfaces/Placeholder";
26
28
  const readErrorMessage = async response => {
@@ -44,15 +46,26 @@ export default function PdfPreview(props) {
44
46
  const [error, setError] = createSignal(null);
45
47
  const [failed, setFailed] = createSignal(false);
46
48
  const [tabBlocked, setTabBlocked] = createSignal(false);
49
+ // The frame has its document only once it fires `load`; until then the loading state covers it.
50
+ const [drawn, setDrawn] = createSignal(false);
47
51
  // An automatic preview shows one fixed document; the open action reuses it instead of requesting it again.
48
52
  let shownBlob = null;
49
53
  let openButton;
50
54
  let frame;
55
+ let viewer;
51
56
  let renderButton;
52
57
  let errorRetryButton;
53
58
  let disposed = false;
54
59
  let loadGeneration = 0;
55
60
  let openGeneration = 0;
61
+
62
+ // Without an inline PDF viewer (`navigator.pdfViewerEnabled === false`, as in Chrome on Android) a frame stays empty
63
+ // or downloads the file, so the viewer explains that instead and leaves the document to the open and download actions.
64
+ const inlineViewer = () => typeof navigator === "undefined" || navigator.pdfViewerEnabled !== false;
65
+ // There an automatic preview could show only that hint, so it requests nothing: the open action fetches the document
66
+ // when someone asks for it, and is also the retry after it fails. An on-demand preview still renders, because its
67
+ // request also checks the caller's input.
68
+ const openOnly = () => Boolean(props.autoLoad) && !inlineViewer();
56
69
  const revokeCurrent = () => {
57
70
  const current = url();
58
71
  if (current) URL.revokeObjectURL(current);
@@ -88,12 +101,18 @@ export default function PdfPreview(props) {
88
101
  const previousUrl = url();
89
102
  shownBlob = blob;
90
103
  setFailed(false);
104
+ setDrawn(false);
91
105
  setUrl(nextUrl);
92
106
  setLoading(false);
93
107
  if (previousUrl) URL.revokeObjectURL(previousUrl);
94
- // The shown document removes the retry action; keep keyboard focus in the actions instead of the page, or on the
95
- // document itself when the host shows only the content.
96
- if (retryFocused && document.activeElement === document.body) (openButton?.isConnected ? openButton : frame)?.focus();
108
+ // The loading status turns into the missing-viewer hint in place and stops being a live region, so say it here.
109
+ if (!inlineViewer()) {
110
+ announce(messages().pdfPreviewNoViewer);
111
+ announce(messages().pdfPreviewNoViewerDescription);
112
+ }
113
+ // The shown document removes the retry action; keep keyboard focus in the actions instead of the page, or, when
114
+ // the host shows only the content, in the viewer, which hands it on to the document once the frame has loaded it.
115
+ if (retryFocused && document.activeElement === document.body) (openButton?.isConnected ? openButton : viewer)?.focus();
97
116
  } catch (e) {
98
117
  if (disposed || generation !== loadGeneration) return;
99
118
  shownBlob = null;
@@ -105,9 +124,10 @@ export default function PdfPreview(props) {
105
124
  }
106
125
  };
107
126
  onMount(() => {
108
- // Hand the initial loading state to the request itself, which also covers a preview disabled by now.
127
+ // Hand the initial loading state to the request itself, which also covers a preview disabled by now or one that
128
+ // leaves the document to the open action.
109
129
  setLoading(false);
110
- if (props.autoLoad) void load();
130
+ if (props.autoLoad && !openOnly()) void load();
111
131
  });
112
132
  const openInNewTab = async () => {
113
133
  if (loading() || opening() || props.disabled?.()) return;
@@ -140,7 +160,7 @@ export default function PdfPreview(props) {
140
160
 
141
161
  // With autoLoad, rendering again would show the same document: offer it only until one is shown. After a failure the
142
162
  // default error state carries it as the retry; beside a caller's error content it stays in place while a retry loads.
143
- const renderable = () => !props.autoLoad || (failed() ? Boolean(props.renderError) : !url() && !loading());
163
+ const renderable = () => !openOnly() && (!props.autoLoad || (failed() ? Boolean(props.renderError) : !url() && !loading()));
144
164
  const actions = () => (() => {
145
165
  var _el$ = _$getNextElement(_tmpl$4),
146
166
  _el$1 = _el$.firstChild,
@@ -245,71 +265,118 @@ export default function PdfPreview(props) {
245
265
  }), _el$16, _co$6);
246
266
  return _el$;
247
267
  })();
248
- // Every state before a document is shown uses one placeholder in the viewer's box, so loading changes no layout.
249
- const content = () => _$createComponent(Show, {
250
- get when() {
251
- return error();
252
- },
253
- get fallback() {
254
- return _$createComponent(Show, {
255
- get when() {
256
- return url();
257
- },
258
- get fallback() {
259
- return _$createComponent(Placeholder, {
268
+ // Every state uses one placeholder in the viewer's box, so loading changes no layout: idle and loading before a
269
+ // document arrives, loading over the frame until it has loaded the document, and the hint where no frame can.
270
+ const status = () => {
271
+ if (error()) return null;
272
+ if (!inlineViewer() && (url() || openOnly() && !loading())) return "no-viewer";
273
+ if (!url()) return loading() ? "loading" : "idle";
274
+ return drawn() ? null : "loading";
275
+ };
276
+ const viewerBox = () => // While it shows a placeholder, the viewer itself holds keyboard focus that has nowhere else to go.
277
+ (() => {
278
+ var _el$25 = _$getNextElement(_tmpl$6),
279
+ _el$26 = _el$25.firstChild,
280
+ [_el$27, _co$9] = _$getNextMarker(_el$26.nextSibling),
281
+ _el$28 = _el$27.nextSibling,
282
+ [_el$29, _co$0] = _$getNextMarker(_el$28.nextSibling);
283
+ _$use(element => viewer = element, _el$25);
284
+ _$insert(_el$25, _$createComponent(Show, {
285
+ get when() {
286
+ return _$memo(() => !!(!error() && inlineViewer()))() && url();
287
+ },
288
+ children: currentUrl => (() => {
289
+ var _el$30 = _$getNextElement(_tmpl$7);
290
+ _el$30.addEventListener("load", () => {
291
+ const waiting = document.activeElement === viewer;
292
+ setDrawn(true);
293
+ if (waiting) frame?.focus();
294
+ });
295
+ _$use(element => {
296
+ frame = element;
297
+ // A new frame loads its document again, also one that was shown before a failed reload.
298
+ setDrawn(false);
299
+ }, _el$30);
300
+ _$effect(_p$ => {
301
+ var _v$5 = drawn() ? "" : undefined,
302
+ _v$6 = !drawn(),
303
+ _v$7 = currentUrl(),
304
+ _v$8 = props.title ?? messages().pdfPreview;
305
+ _v$5 !== _p$.e && _$setAttribute(_el$30, "data-drawn", _p$.e = _v$5);
306
+ _v$6 !== _p$.t && _$setProperty(_el$30, "inert", _p$.t = _v$6);
307
+ _v$7 !== _p$.a && _$setAttribute(_el$30, "src", _p$.a = _v$7);
308
+ _v$8 !== _p$.o && _$setAttribute(_el$30, "title", _p$.o = _v$8);
309
+ return _p$;
310
+ }, {
311
+ e: undefined,
312
+ t: undefined,
313
+ a: undefined,
314
+ o: undefined
315
+ });
316
+ return _el$30;
317
+ })()
318
+ }), _el$27, _co$9);
319
+ _$insert(_el$25, _$createComponent(Show, {
320
+ get when() {
321
+ return error();
322
+ },
323
+ get fallback() {
324
+ return _$createComponent(Show, {
325
+ get when() {
326
+ return status();
327
+ },
328
+ children: state => _$createComponent(Placeholder, {
260
329
  "class": "k2b-content-pdf-preview__placeholder",
261
330
  get state() {
262
- return loading() ? "loading" : "empty";
331
+ return state() === "loading" ? "loading" : "empty";
263
332
  },
264
333
  get icon() {
265
- return loading() ? undefined : "ti ti-file-type-pdf";
334
+ return state() === "loading" ? undefined : "ti ti-file-type-pdf";
266
335
  },
267
336
  get title() {
268
- return _$memo(() => !!loading())() ? messages().loading : undefined;
337
+ return _$memo(() => state() === "loading")() ? messages().loading : _$memo(() => state() === "no-viewer")() ? messages().pdfPreviewNoViewer : undefined;
269
338
  },
270
339
  get description() {
271
- return _$memo(() => !!loading())() ? undefined : props.emptyText ?? messages().renderPdfPreview;
340
+ return _$memo(() => state() === "idle")() ? props.emptyText ?? messages().renderPdfPreview : _$memo(() => state() === "no-viewer")() ? messages().pdfPreviewNoViewerDescription : undefined;
272
341
  }
273
- });
342
+ })
343
+ });
344
+ },
345
+ children: message => _$createComponent(Placeholder, {
346
+ "class": "k2b-content-pdf-preview__placeholder",
347
+ state: "error",
348
+ get description() {
349
+ return message();
274
350
  },
275
- children: currentUrl => (() => {
276
- var _el$25 = _$getNextElement(_tmpl$6);
277
- _$use(element => frame = element, _el$25);
278
- _$effect(_p$ => {
279
- var _v$5 = currentUrl(),
280
- _v$6 = props.title ?? messages().pdfPreview;
281
- _v$5 !== _p$.e && _$setAttribute(_el$25, "src", _p$.e = _v$5);
282
- _v$6 !== _p$.t && _$setAttribute(_el$25, "title", _p$.t = _v$6);
283
- return _p$;
284
- }, {
285
- e: undefined,
286
- t: undefined
287
- });
288
- return _el$25;
289
- })()
290
- });
351
+ get action() {
352
+ return (
353
+ // One retry at a time: the render action moves here only where the toolbar no longer offers it, and the
354
+ // open action is the retry of a preview that leaves the document to it.
355
+ _$memo(() => !!(renderable() || openOnly()))() ? undefined : (() => {
356
+ var _el$31 = _$getNextElement(_tmpl$8);
357
+ _el$31.$$click = () => void load();
358
+ _$use(element => errorRetryButton = element, _el$31);
359
+ _$insert(_el$31, () => props.buttonLabel ?? messages().retry);
360
+ _$effect(() => _$setProperty(_el$31, "disabled", opening() || props.disabled?.()));
361
+ _$runHydrationEvents();
362
+ return _el$31;
363
+ })()
364
+ );
365
+ }
366
+ })
367
+ }), _el$29, _co$0);
368
+ _$effect(() => _$setAttribute(_el$25, "tabindex", status() ? -1 : undefined));
369
+ return _el$25;
370
+ })();
371
+ // A caller's error content replaces the whole viewer, as it brings its own layout.
372
+ const content = () => _$createComponent(Show, {
373
+ get when() {
374
+ return _$memo(() => !!props.renderError)() ? error() : null;
291
375
  },
292
- children: message => props.renderError?.(message()) ?? _$createComponent(Placeholder, {
293
- "class": "k2b-content-pdf-preview__placeholder",
294
- state: "error",
295
- get description() {
296
- return message();
297
- },
298
- get action() {
299
- return (
300
- // One retry at a time: the render action moves here only where the toolbar no longer offers it.
301
- _$memo(() => !!renderable())() ? undefined : (() => {
302
- var _el$26 = _$getNextElement(_tmpl$7);
303
- _el$26.$$click = () => void load();
304
- _$use(element => errorRetryButton = element, _el$26);
305
- _$insert(_el$26, () => props.buttonLabel ?? messages().retry);
306
- _$effect(() => _$setProperty(_el$26, "disabled", opening() || props.disabled?.()));
307
- _$runHydrationEvents();
308
- return _el$26;
309
- })()
310
- );
311
- }
312
- })
376
+ get fallback() {
377
+ return viewerBox();
378
+ },
379
+ children: message => props.renderError?.(message())
313
380
  });
314
381
  if (props.children) return props.children({
315
382
  get actions() {
@@ -320,27 +387,27 @@ export default function PdfPreview(props) {
320
387
  }
321
388
  });
322
389
  return (() => {
323
- var _el$27 = _$getNextElement(_tmpl$9),
324
- _el$28 = _el$27.firstChild,
325
- _el$29 = _el$28.firstChild,
326
- _el$31 = _el$29.nextSibling,
327
- [_el$32, _co$9] = _$getNextMarker(_el$31.nextSibling),
328
- _el$33 = _el$28.nextSibling,
329
- [_el$34, _co$0] = _$getNextMarker(_el$33.nextSibling);
330
- _$insert(_el$29, _$createComponent(Show, {
390
+ var _el$32 = _$getNextElement(_tmpl$0),
391
+ _el$33 = _el$32.firstChild,
392
+ _el$34 = _el$33.firstChild,
393
+ _el$36 = _el$34.nextSibling,
394
+ [_el$37, _co$1] = _$getNextMarker(_el$36.nextSibling),
395
+ _el$38 = _el$33.nextSibling,
396
+ [_el$39, _co$10] = _$getNextMarker(_el$38.nextSibling);
397
+ _$insert(_el$34, _$createComponent(Show, {
331
398
  get when() {
332
399
  return props.title;
333
400
  },
334
401
  get children() {
335
- var _el$30 = _$getNextElement(_tmpl$8);
336
- _$insert(_el$30, () => props.title);
337
- return _el$30;
402
+ var _el$35 = _$getNextElement(_tmpl$9);
403
+ _$insert(_el$35, () => props.title);
404
+ return _el$35;
338
405
  }
339
406
  }));
340
- _$insert(_el$28, actions, _el$32, _co$9);
341
- _$insert(_el$27, content, _el$34, _co$0);
342
- _$effect(() => _$className(_el$27, `k2b-content-pdf-preview ${props.class ?? ""}`));
343
- return _el$27;
407
+ _$insert(_el$33, actions, _el$37, _co$1);
408
+ _$insert(_el$32, content, _el$39, _co$10);
409
+ _$effect(() => _$className(_el$32, `k2b-content-pdf-preview ${props.class ?? ""}`));
410
+ return _el$32;
344
411
  })();
345
412
  }
346
413
  _$delegateEvents(["click"]);
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/PdfPreview.tsx"],"sourcesContent":["import { createSignal, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { resolveUiMessages, useUiMessages } from \"../intl/messages\";\nimport Placeholder from \"../surfaces/Placeholder\";\n\nexport type PdfPreviewRequest = () => Promise<Response | Blob>;\n\nexport type PdfPreviewProps = {\n request: PdfPreviewRequest;\n autoLoad?: boolean;\n disabled?: () => boolean;\n title?: string;\n buttonLabel?: string;\n openButtonLabel?: string;\n /**\n * Opens the document at this address in a new tab instead of a local copy. Pass a stable same-origin URL that\n * serves the PDF inline, so reloading and the viewer's file name keep working. Without it, the open action shows\n * a temporary copy of the requested document.\n */\n openHref?: string;\n /** Adds a Download action. The host owns the download, for example a fresh attachment URL. */\n onDownload?: () => void;\n emptyText?: string;\n class?: string;\n children?: (parts: { actions: JSX.Element; content: JSX.Element }) => JSX.Element;\n renderError?: (message: string) => JSX.Element;\n};\n\nconst readErrorMessage = async (response: Response): Promise<string> => {\n try {\n const data = (await response.json()) as unknown;\n if (data && typeof data === \"object\" && \"message\" in data && typeof data.message === \"string\") return data.message;\n } catch {\n // Fall through to the HTTP status fallback.\n }\n return resolveUiMessages().pdfPreviewHttpError({ status: response.status });\n};\n\nexport default function PdfPreview(props: PdfPreviewProps) {\n const messages = useUiMessages();\n const [url, setUrl] = createSignal<string | null>(null);\n // An automatic preview starts loading once mounted. The server and the page before hydration already show that\n // state, so they offer neither a retry nor an invitation to render while nothing has failed.\n const [loading, setLoading] = createSignal(Boolean(props.autoLoad) && !props.disabled?.());\n const [opening, setOpening] = createSignal(false);\n const [error, setError] = createSignal<string | null>(null);\n const [failed, setFailed] = createSignal(false);\n const [tabBlocked, setTabBlocked] = createSignal(false);\n // An automatic preview shows one fixed document; the open action reuses it instead of requesting it again.\n let shownBlob: Blob | null = null;\n let openButton: HTMLElement | undefined;\n let frame: HTMLIFrameElement | undefined;\n let renderButton: HTMLButtonElement | undefined;\n let errorRetryButton: HTMLButtonElement | undefined;\n let disposed = false;\n let loadGeneration = 0;\n let openGeneration = 0;\n\n const revokeCurrent = () => {\n const current = url();\n if (current) URL.revokeObjectURL(current);\n setUrl(null);\n };\n\n onCleanup(() => {\n disposed = true;\n loadGeneration += 1;\n openGeneration += 1;\n revokeCurrent();\n });\n\n const readPdfBlob = async () => {\n const response = await props.request();\n const blob = response instanceof Response ? (response.ok ? await response.blob() : null) : response;\n if (!blob) throw new Error(await readErrorMessage(response as Response));\n if (blob.type && blob.type !== \"application/pdf\") throw new Error(`PDF preview returned ${blob.type} instead of application/pdf`);\n return blob;\n };\n\n const load = async () => {\n if (loading() || opening() || props.disabled?.()) return;\n const generation = ++loadGeneration;\n // A retry the shown document or the loading state removes hands keyboard focus on instead of dropping it.\n const retryFocused =\n (props.autoLoad && document.activeElement === renderButton) ||\n (errorRetryButton?.isConnected && document.activeElement === errorRetryButton);\n setLoading(true);\n setError(null);\n try {\n const blob = await readPdfBlob();\n const nextUrl = URL.createObjectURL(blob);\n if (disposed || generation !== loadGeneration) {\n URL.revokeObjectURL(nextUrl);\n return;\n }\n const previousUrl = url();\n shownBlob = blob;\n setFailed(false);\n setUrl(nextUrl);\n setLoading(false);\n if (previousUrl) URL.revokeObjectURL(previousUrl);\n // The shown document removes the retry action; keep keyboard focus in the actions instead of the page, or on the\n // document itself when the host shows only the content.\n if (retryFocused && document.activeElement === document.body) (openButton?.isConnected ? openButton : frame)?.focus();\n } catch (e) {\n if (disposed || generation !== loadGeneration) return;\n shownBlob = null;\n setFailed(true);\n setError(e instanceof Error ? e.message : \"PDF preview failed\");\n if (retryFocused && document.activeElement === document.body) errorRetryButton?.focus();\n } finally {\n if (!disposed && generation === loadGeneration) setLoading(false);\n }\n };\n\n onMount(() => {\n // Hand the initial loading state to the request itself, which also covers a preview disabled by now.\n setLoading(false);\n if (props.autoLoad) void load();\n });\n\n const openInNewTab = async () => {\n if (loading() || opening() || props.disabled?.()) return;\n const generation = ++openGeneration;\n const tab = window.open(\"\", \"_blank\");\n // A blocked tab is not a document error: keep the shown document and report it beside the actions.\n setTabBlocked(!tab);\n if (!tab) return;\n tab.opener = null;\n tab.document.title = props.title ?? messages().pdfPreview;\n tab.document.body.textContent = messages().pdfPreviewRendering;\n setOpening(true);\n setError(null);\n try {\n const blob = (props.autoLoad ? shownBlob : null) ?? (await readPdfBlob());\n if (disposed || generation !== openGeneration) {\n tab.close();\n return;\n }\n const objectUrl = URL.createObjectURL(blob);\n tab.location.href = objectUrl;\n window.setTimeout(() => URL.revokeObjectURL(objectUrl), 60_000);\n } catch (e) {\n tab.close();\n if (!disposed && generation === openGeneration) setError(e instanceof Error ? e.message : \"PDF preview failed\");\n } finally {\n if (!disposed && generation === openGeneration) setOpening(false);\n }\n };\n\n // With autoLoad, rendering again would show the same document: offer it only until one is shown. After a failure the\n // default error state carries it as the retry; beside a caller's error content it stays in place while a retry loads.\n const renderable = () => !props.autoLoad || (failed() ? Boolean(props.renderError) : !url() && !loading());\n const actions = () => (\n <div class=\"k2b-content-pdf-preview__actions\">\n <Show\n when={!props.disabled?.() && props.openHref}\n fallback={\n <button\n ref={(element) => (openButton = element)}\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void openInNewTab()}\n disabled={loading() || opening() || props.disabled?.()}\n >\n <i class={opening() ? \"ti ti-loader-2 k2b-spin\" : \"ti ti-external-link\"} aria-hidden=\"true\" />\n {props.openButtonLabel ?? messages().openPreview}\n </button>\n }\n >\n {(href) => (\n // A plain link to a real address: the browser opens it on the user's own click, and the tab can reload it.\n <a\n ref={(element) => (openButton = element)}\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n href={href()}\n target=\"_blank\"\n rel=\"noopener\"\n >\n <i class=\"ti ti-external-link\" aria-hidden=\"true\" />\n {props.openButtonLabel ?? messages().openPreview}\n </a>\n )}\n </Show>\n <Show when={props.onDownload}>\n <button\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => props.onDownload?.()}\n disabled={props.disabled?.()}\n >\n <i class=\"ti ti-download\" aria-hidden=\"true\" />\n {messages().download}\n </button>\n </Show>\n <Show when={renderable()}>\n <button\n ref={renderButton}\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void load()}\n disabled={loading() || opening() || props.disabled?.()}\n >\n <i class={loading() ? \"ti ti-loader-2 k2b-spin\" : \"ti ti-file-type-pdf\"} aria-hidden=\"true\" />\n {props.buttonLabel ?? messages().previewPdf}\n </button>\n </Show>\n <Show when={tabBlocked()}>\n <span role=\"alert\" class=\"k2b-content-pdf-preview__notice\">\n {messages().pdfPreviewTabBlocked}\n </span>\n </Show>\n </div>\n );\n // Every state before a document is shown uses one placeholder in the viewer's box, so loading changes no layout.\n const content = () => (\n <Show\n when={error()}\n fallback={\n <Show\n when={url()}\n fallback={\n <Placeholder\n class=\"k2b-content-pdf-preview__placeholder\"\n state={loading() ? \"loading\" : \"empty\"}\n icon={loading() ? undefined : \"ti ti-file-type-pdf\"}\n title={loading() ? messages().loading : undefined}\n description={loading() ? undefined : (props.emptyText ?? messages().renderPdfPreview)}\n />\n }\n >\n {(currentUrl) => (\n <iframe\n ref={(element) => (frame = element)}\n class=\"k2b-content-pdf-preview__frame\"\n src={currentUrl()}\n title={props.title ?? messages().pdfPreview}\n />\n )}\n </Show>\n }\n >\n {(message) =>\n props.renderError?.(message()) ?? (\n <Placeholder\n class=\"k2b-content-pdf-preview__placeholder\"\n state=\"error\"\n description={message()}\n action={\n // One retry at a time: the render action moves here only where the toolbar no longer offers it.\n renderable() ? undefined : (\n <button\n ref={(element) => (errorRetryButton = element)}\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void load()}\n disabled={opening() || props.disabled?.()}\n >\n {props.buttonLabel ?? messages().retry}\n </button>\n )\n }\n />\n )\n }\n </Show>\n );\n\n if (props.children)\n return props.children({\n get actions() {\n return actions();\n },\n get content() {\n return content();\n },\n });\n return (\n <section class={`k2b-content-pdf-preview ${props.class ?? \"\"}`}>\n <div class=\"k2b-content-pdf-preview__toolbar\">\n <div class=\"k2b-content-pdf-preview__heading\">\n <Show when={props.title}>\n <h2 class=\"k2b-content-pdf-preview__title\">{props.title}</h2>\n </Show>\n </div>\n {actions()}\n </div>\n {content()}\n </section>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/PdfPreview.tsx"],"sourcesContent":["import { createSignal, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { announce } from \"../feedback/announce\";\nimport { resolveUiMessages, useUiMessages } from \"../intl/messages\";\nimport Placeholder from \"../surfaces/Placeholder\";\n\nexport type PdfPreviewRequest = () => Promise<Response | Blob>;\n\nexport type PdfPreviewProps = {\n request: PdfPreviewRequest;\n autoLoad?: boolean;\n disabled?: () => boolean;\n title?: string;\n buttonLabel?: string;\n openButtonLabel?: string;\n /**\n * Opens the document at this address in a new tab instead of a local copy. Pass a stable same-origin URL that\n * serves the PDF inline, so reloading and the viewer's file name keep working. Without it, the open action shows\n * a temporary copy of the requested document.\n */\n openHref?: string;\n /** Adds a Download action. The host owns the download, for example a fresh attachment URL. */\n onDownload?: () => void;\n emptyText?: string;\n class?: string;\n children?: (parts: { actions: JSX.Element; content: JSX.Element }) => JSX.Element;\n renderError?: (message: string) => JSX.Element;\n};\n\nconst readErrorMessage = async (response: Response): Promise<string> => {\n try {\n const data = (await response.json()) as unknown;\n if (data && typeof data === \"object\" && \"message\" in data && typeof data.message === \"string\") return data.message;\n } catch {\n // Fall through to the HTTP status fallback.\n }\n return resolveUiMessages().pdfPreviewHttpError({ status: response.status });\n};\n\nexport default function PdfPreview(props: PdfPreviewProps) {\n const messages = useUiMessages();\n const [url, setUrl] = createSignal<string | null>(null);\n // An automatic preview starts loading once mounted. The server and the page before hydration already show that\n // state, so they offer neither a retry nor an invitation to render while nothing has failed.\n const [loading, setLoading] = createSignal(Boolean(props.autoLoad) && !props.disabled?.());\n const [opening, setOpening] = createSignal(false);\n const [error, setError] = createSignal<string | null>(null);\n const [failed, setFailed] = createSignal(false);\n const [tabBlocked, setTabBlocked] = createSignal(false);\n // The frame has its document only once it fires `load`; until then the loading state covers it.\n const [drawn, setDrawn] = createSignal(false);\n // An automatic preview shows one fixed document; the open action reuses it instead of requesting it again.\n let shownBlob: Blob | null = null;\n let openButton: HTMLElement | undefined;\n let frame: HTMLIFrameElement | undefined;\n let viewer: HTMLDivElement | undefined;\n let renderButton: HTMLButtonElement | undefined;\n let errorRetryButton: HTMLButtonElement | undefined;\n let disposed = false;\n let loadGeneration = 0;\n let openGeneration = 0;\n\n // Without an inline PDF viewer (`navigator.pdfViewerEnabled === false`, as in Chrome on Android) a frame stays empty\n // or downloads the file, so the viewer explains that instead and leaves the document to the open and download actions.\n const inlineViewer = () => typeof navigator === \"undefined\" || navigator.pdfViewerEnabled !== false;\n // There an automatic preview could show only that hint, so it requests nothing: the open action fetches the document\n // when someone asks for it, and is also the retry after it fails. An on-demand preview still renders, because its\n // request also checks the caller's input.\n const openOnly = () => Boolean(props.autoLoad) && !inlineViewer();\n\n const revokeCurrent = () => {\n const current = url();\n if (current) URL.revokeObjectURL(current);\n setUrl(null);\n };\n\n onCleanup(() => {\n disposed = true;\n loadGeneration += 1;\n openGeneration += 1;\n revokeCurrent();\n });\n\n const readPdfBlob = async () => {\n const response = await props.request();\n const blob = response instanceof Response ? (response.ok ? await response.blob() : null) : response;\n if (!blob) throw new Error(await readErrorMessage(response as Response));\n if (blob.type && blob.type !== \"application/pdf\") throw new Error(`PDF preview returned ${blob.type} instead of application/pdf`);\n return blob;\n };\n\n const load = async () => {\n if (loading() || opening() || props.disabled?.()) return;\n const generation = ++loadGeneration;\n // A retry the shown document or the loading state removes hands keyboard focus on instead of dropping it.\n const retryFocused =\n (props.autoLoad && document.activeElement === renderButton) ||\n (errorRetryButton?.isConnected && document.activeElement === errorRetryButton);\n setLoading(true);\n setError(null);\n try {\n const blob = await readPdfBlob();\n const nextUrl = URL.createObjectURL(blob);\n if (disposed || generation !== loadGeneration) {\n URL.revokeObjectURL(nextUrl);\n return;\n }\n const previousUrl = url();\n shownBlob = blob;\n setFailed(false);\n setDrawn(false);\n setUrl(nextUrl);\n setLoading(false);\n if (previousUrl) URL.revokeObjectURL(previousUrl);\n // The loading status turns into the missing-viewer hint in place and stops being a live region, so say it here.\n if (!inlineViewer()) {\n announce(messages().pdfPreviewNoViewer);\n announce(messages().pdfPreviewNoViewerDescription);\n }\n // The shown document removes the retry action; keep keyboard focus in the actions instead of the page, or, when\n // the host shows only the content, in the viewer, which hands it on to the document once the frame has loaded it.\n if (retryFocused && document.activeElement === document.body) (openButton?.isConnected ? openButton : viewer)?.focus();\n } catch (e) {\n if (disposed || generation !== loadGeneration) return;\n shownBlob = null;\n setFailed(true);\n setError(e instanceof Error ? e.message : \"PDF preview failed\");\n if (retryFocused && document.activeElement === document.body) errorRetryButton?.focus();\n } finally {\n if (!disposed && generation === loadGeneration) setLoading(false);\n }\n };\n\n onMount(() => {\n // Hand the initial loading state to the request itself, which also covers a preview disabled by now or one that\n // leaves the document to the open action.\n setLoading(false);\n if (props.autoLoad && !openOnly()) void load();\n });\n\n const openInNewTab = async () => {\n if (loading() || opening() || props.disabled?.()) return;\n const generation = ++openGeneration;\n const tab = window.open(\"\", \"_blank\");\n // A blocked tab is not a document error: keep the shown document and report it beside the actions.\n setTabBlocked(!tab);\n if (!tab) return;\n tab.opener = null;\n tab.document.title = props.title ?? messages().pdfPreview;\n tab.document.body.textContent = messages().pdfPreviewRendering;\n setOpening(true);\n setError(null);\n try {\n const blob = (props.autoLoad ? shownBlob : null) ?? (await readPdfBlob());\n if (disposed || generation !== openGeneration) {\n tab.close();\n return;\n }\n const objectUrl = URL.createObjectURL(blob);\n tab.location.href = objectUrl;\n window.setTimeout(() => URL.revokeObjectURL(objectUrl), 60_000);\n } catch (e) {\n tab.close();\n if (!disposed && generation === openGeneration) setError(e instanceof Error ? e.message : \"PDF preview failed\");\n } finally {\n if (!disposed && generation === openGeneration) setOpening(false);\n }\n };\n\n // With autoLoad, rendering again would show the same document: offer it only until one is shown. After a failure the\n // default error state carries it as the retry; beside a caller's error content it stays in place while a retry loads.\n const renderable = () => !openOnly() && (!props.autoLoad || (failed() ? Boolean(props.renderError) : !url() && !loading()));\n const actions = () => (\n <div class=\"k2b-content-pdf-preview__actions\">\n <Show\n when={!props.disabled?.() && props.openHref}\n fallback={\n <button\n ref={(element) => (openButton = element)}\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void openInNewTab()}\n disabled={loading() || opening() || props.disabled?.()}\n >\n <i class={opening() ? \"ti ti-loader-2 k2b-spin\" : \"ti ti-external-link\"} aria-hidden=\"true\" />\n {props.openButtonLabel ?? messages().openPreview}\n </button>\n }\n >\n {(href) => (\n // A plain link to a real address: the browser opens it on the user's own click, and the tab can reload it.\n <a\n ref={(element) => (openButton = element)}\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n href={href()}\n target=\"_blank\"\n rel=\"noopener\"\n >\n <i class=\"ti ti-external-link\" aria-hidden=\"true\" />\n {props.openButtonLabel ?? messages().openPreview}\n </a>\n )}\n </Show>\n <Show when={props.onDownload}>\n <button\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => props.onDownload?.()}\n disabled={props.disabled?.()}\n >\n <i class=\"ti ti-download\" aria-hidden=\"true\" />\n {messages().download}\n </button>\n </Show>\n <Show when={renderable()}>\n <button\n ref={renderButton}\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void load()}\n disabled={loading() || opening() || props.disabled?.()}\n >\n <i class={loading() ? \"ti ti-loader-2 k2b-spin\" : \"ti ti-file-type-pdf\"} aria-hidden=\"true\" />\n {props.buttonLabel ?? messages().previewPdf}\n </button>\n </Show>\n <Show when={tabBlocked()}>\n <span role=\"alert\" class=\"k2b-content-pdf-preview__notice\">\n {messages().pdfPreviewTabBlocked}\n </span>\n </Show>\n </div>\n );\n // Every state uses one placeholder in the viewer's box, so loading changes no layout: idle and loading before a\n // document arrives, loading over the frame until it has loaded the document, and the hint where no frame can.\n const status = () => {\n if (error()) return null;\n if (!inlineViewer() && (url() || (openOnly() && !loading()))) return \"no-viewer\";\n if (!url()) return loading() ? \"loading\" : \"idle\";\n return drawn() ? null : \"loading\";\n };\n const viewerBox = () => (\n // While it shows a placeholder, the viewer itself holds keyboard focus that has nowhere else to go.\n <div ref={(element) => (viewer = element)} class=\"k2b-content-pdf-preview__viewer\" tabIndex={status() ? -1 : undefined}>\n <Show when={!error() && inlineViewer() && url()}>\n {(currentUrl) => (\n <iframe\n ref={(element) => {\n frame = element;\n // A new frame loads its document again, also one that was shown before a failed reload.\n setDrawn(false);\n }}\n class=\"k2b-content-pdf-preview__frame\"\n data-drawn={drawn() ? \"\" : undefined}\n // Out of reach while the loading state covers it, so keyboard focus never lands on an invisible frame.\n inert={!drawn()}\n src={currentUrl()}\n title={props.title ?? messages().pdfPreview}\n onLoad={() => {\n const waiting = document.activeElement === viewer;\n setDrawn(true);\n if (waiting) frame?.focus();\n }}\n />\n )}\n </Show>\n <Show\n when={error()}\n fallback={\n <Show when={status()}>\n {(state) => (\n <Placeholder\n class=\"k2b-content-pdf-preview__placeholder\"\n state={state() === \"loading\" ? \"loading\" : \"empty\"}\n icon={state() === \"loading\" ? undefined : \"ti ti-file-type-pdf\"}\n title={state() === \"loading\" ? messages().loading : state() === \"no-viewer\" ? messages().pdfPreviewNoViewer : undefined}\n description={\n state() === \"idle\"\n ? (props.emptyText ?? messages().renderPdfPreview)\n : state() === \"no-viewer\"\n ? messages().pdfPreviewNoViewerDescription\n : undefined\n }\n />\n )}\n </Show>\n }\n >\n {(message) => (\n <Placeholder\n class=\"k2b-content-pdf-preview__placeholder\"\n state=\"error\"\n description={message()}\n action={\n // One retry at a time: the render action moves here only where the toolbar no longer offers it, and the\n // open action is the retry of a preview that leaves the document to it.\n renderable() || openOnly() ? undefined : (\n <button\n ref={(element) => (errorRetryButton = element)}\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void load()}\n disabled={opening() || props.disabled?.()}\n >\n {props.buttonLabel ?? messages().retry}\n </button>\n )\n }\n />\n )}\n </Show>\n </div>\n );\n // A caller's error content replaces the whole viewer, as it brings its own layout.\n const content = () => (\n <Show when={props.renderError ? error() : null} fallback={viewerBox()}>\n {(message) => props.renderError?.(message())}\n </Show>\n );\n\n if (props.children)\n return props.children({\n get actions() {\n return actions();\n },\n get content() {\n return content();\n },\n });\n return (\n <section class={`k2b-content-pdf-preview ${props.class ?? \"\"}`}>\n <div class=\"k2b-content-pdf-preview__toolbar\">\n <div class=\"k2b-content-pdf-preview__heading\">\n <Show when={props.title}>\n <h2 class=\"k2b-content-pdf-preview__title\">{props.title}</h2>\n </Show>\n </div>\n {actions()}\n </div>\n {content()}\n </section>\n );\n}\n"],"mappings":"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","ignoreList":[]}