@osdk/react-components 0.2.0-beta.23 → 0.2.0-beta.25

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 (115) hide show
  1. package/AGENTS.md +3 -0
  2. package/CHANGELOG.md +29 -0
  3. package/build/browser/action-form/FormFieldApi.js.map +1 -1
  4. package/build/browser/action-form/fields/{TextInputField.module.css → BaseInput.module.css} +2 -2
  5. package/build/browser/action-form/fields/BaseInput.module.css.js +6 -0
  6. package/build/browser/action-form/fields/FormFieldRenderer.js +26 -8
  7. package/build/browser/action-form/fields/FormFieldRenderer.js.map +1 -1
  8. package/build/browser/action-form/fields/RadioButtonsField.js +57 -0
  9. package/build/browser/action-form/fields/RadioButtonsField.js.map +1 -0
  10. package/build/browser/action-form/fields/RadioButtonsField.module.css +83 -0
  11. package/build/browser/action-form/fields/RadioButtonsField.module.css.js +10 -0
  12. package/build/browser/action-form/fields/TextAreaField.js +50 -0
  13. package/build/browser/action-form/fields/TextAreaField.js.map +1 -0
  14. package/build/browser/action-form/fields/TextInputField.js +3 -3
  15. package/build/browser/action-form/fields/TextInputField.js.map +1 -1
  16. package/build/browser/pdf-viewer/PdfViewer.js +40 -4
  17. package/build/browser/pdf-viewer/PdfViewer.js.map +1 -1
  18. package/build/browser/pdf-viewer/components/PdfViewerAnnotationLayer.js +85 -18
  19. package/build/browser/pdf-viewer/components/PdfViewerAnnotationLayer.js.map +1 -1
  20. package/build/browser/pdf-viewer/components/PdfViewerAnnotationLayer.module.css +18 -0
  21. package/build/browser/pdf-viewer/components/PdfViewerAnnotationLayer.module.css.js +1 -0
  22. package/build/browser/pdf-viewer/components/PdfViewerContent.js +15 -3
  23. package/build/browser/pdf-viewer/components/PdfViewerContent.js.map +1 -1
  24. package/build/browser/pdf-viewer/components/PdfViewerOutlineSidebar.module.css +1 -1
  25. package/build/browser/pdf-viewer/components/PdfViewerSidebar.module.css +1 -1
  26. package/build/browser/pdf-viewer/components/PdfViewerSidebarHeader.module.css +1 -1
  27. package/build/browser/pdf-viewer/components/PdfViewerToolbar.js +29 -2
  28. package/build/browser/pdf-viewer/components/PdfViewerToolbar.js.map +1 -1
  29. package/build/browser/pdf-viewer/components/PdfViewerToolbar.module.css +5 -0
  30. package/build/browser/pdf-viewer/components/PdfViewerToolbar.module.css.js +1 -0
  31. package/build/browser/pdf-viewer/constants.js +2 -1
  32. package/build/browser/pdf-viewer/constants.js.map +1 -1
  33. package/build/browser/pdf-viewer/hooks/usePdfAnnotationsByPage.js +30 -0
  34. package/build/browser/pdf-viewer/hooks/usePdfAnnotationsByPage.js.map +1 -0
  35. package/build/browser/pdf-viewer/hooks/usePdfFormFields.js +326 -0
  36. package/build/browser/pdf-viewer/hooks/usePdfFormFields.js.map +1 -0
  37. package/build/browser/pdf-viewer/hooks/usePdfHighlightMode.js +199 -0
  38. package/build/browser/pdf-viewer/hooks/usePdfHighlightMode.js.map +1 -0
  39. package/build/browser/pdf-viewer/hooks/usePdfViewer.js +16 -10
  40. package/build/browser/pdf-viewer/hooks/usePdfViewer.js.map +1 -1
  41. package/build/browser/pdf-viewer/types.js.map +1 -1
  42. package/build/browser/public/experimental.js +3 -0
  43. package/build/browser/public/experimental.js.map +1 -1
  44. package/build/browser/styles.css +144 -35
  45. package/build/cjs/public/experimental.cjs +1735 -1109
  46. package/build/cjs/public/experimental.cjs.map +1 -1
  47. package/build/cjs/public/experimental.css +82 -5
  48. package/build/cjs/public/experimental.css.map +1 -1
  49. package/build/cjs/public/experimental.d.cts +154 -20
  50. package/build/esm/action-form/FormFieldApi.js.map +1 -1
  51. package/build/esm/action-form/fields/{TextInputField.module.css → BaseInput.module.css} +2 -2
  52. package/build/esm/action-form/fields/FormFieldRenderer.js +26 -8
  53. package/build/esm/action-form/fields/FormFieldRenderer.js.map +1 -1
  54. package/build/esm/action-form/fields/RadioButtonsField.js +57 -0
  55. package/build/esm/action-form/fields/RadioButtonsField.js.map +1 -0
  56. package/build/esm/action-form/fields/RadioButtonsField.module.css +83 -0
  57. package/build/esm/action-form/fields/TextAreaField.js +50 -0
  58. package/build/esm/action-form/fields/TextAreaField.js.map +1 -0
  59. package/build/esm/action-form/fields/TextInputField.js +3 -3
  60. package/build/esm/action-form/fields/TextInputField.js.map +1 -1
  61. package/build/esm/pdf-viewer/PdfViewer.js +40 -4
  62. package/build/esm/pdf-viewer/PdfViewer.js.map +1 -1
  63. package/build/esm/pdf-viewer/components/PdfViewerAnnotationLayer.js +85 -18
  64. package/build/esm/pdf-viewer/components/PdfViewerAnnotationLayer.js.map +1 -1
  65. package/build/esm/pdf-viewer/components/PdfViewerAnnotationLayer.module.css +18 -0
  66. package/build/esm/pdf-viewer/components/PdfViewerContent.js +15 -3
  67. package/build/esm/pdf-viewer/components/PdfViewerContent.js.map +1 -1
  68. package/build/esm/pdf-viewer/components/PdfViewerOutlineSidebar.module.css +1 -1
  69. package/build/esm/pdf-viewer/components/PdfViewerSidebar.module.css +1 -1
  70. package/build/esm/pdf-viewer/components/PdfViewerSidebarHeader.module.css +1 -1
  71. package/build/esm/pdf-viewer/components/PdfViewerToolbar.js +29 -2
  72. package/build/esm/pdf-viewer/components/PdfViewerToolbar.js.map +1 -1
  73. package/build/esm/pdf-viewer/components/PdfViewerToolbar.module.css +5 -0
  74. package/build/esm/pdf-viewer/constants.js +2 -1
  75. package/build/esm/pdf-viewer/constants.js.map +1 -1
  76. package/build/esm/pdf-viewer/hooks/usePdfAnnotationsByPage.js +30 -0
  77. package/build/esm/pdf-viewer/hooks/usePdfAnnotationsByPage.js.map +1 -0
  78. package/build/esm/pdf-viewer/hooks/usePdfFormFields.js +326 -0
  79. package/build/esm/pdf-viewer/hooks/usePdfFormFields.js.map +1 -0
  80. package/build/esm/pdf-viewer/hooks/usePdfHighlightMode.js +199 -0
  81. package/build/esm/pdf-viewer/hooks/usePdfHighlightMode.js.map +1 -0
  82. package/build/esm/pdf-viewer/hooks/usePdfViewer.js +16 -10
  83. package/build/esm/pdf-viewer/hooks/usePdfViewer.js.map +1 -1
  84. package/build/esm/pdf-viewer/types.js.map +1 -1
  85. package/build/esm/public/experimental.js +3 -0
  86. package/build/esm/public/experimental.js.map +1 -1
  87. package/build/types/action-form/FormFieldApi.d.ts +8 -2
  88. package/build/types/action-form/FormFieldApi.d.ts.map +1 -1
  89. package/build/types/action-form/fields/FormFieldRenderer.d.ts.map +1 -1
  90. package/build/types/action-form/fields/RadioButtonsField.d.ts +3 -0
  91. package/build/types/action-form/fields/RadioButtonsField.d.ts.map +1 -0
  92. package/build/types/action-form/fields/TextAreaField.d.ts +3 -0
  93. package/build/types/action-form/fields/TextAreaField.d.ts.map +1 -0
  94. package/build/types/pdf-viewer/PdfViewer.d.ts +1 -1
  95. package/build/types/pdf-viewer/PdfViewer.d.ts.map +1 -1
  96. package/build/types/pdf-viewer/components/PdfViewerAnnotationLayer.d.ts.map +1 -1
  97. package/build/types/pdf-viewer/components/PdfViewerContent.d.ts +8 -4
  98. package/build/types/pdf-viewer/components/PdfViewerContent.d.ts.map +1 -1
  99. package/build/types/pdf-viewer/components/PdfViewerToolbar.d.ts +6 -1
  100. package/build/types/pdf-viewer/components/PdfViewerToolbar.d.ts.map +1 -1
  101. package/build/types/pdf-viewer/constants.d.ts +1 -1
  102. package/build/types/pdf-viewer/constants.d.ts.map +1 -1
  103. package/build/types/pdf-viewer/hooks/usePdfAnnotationsByPage.d.ts +5 -0
  104. package/build/types/pdf-viewer/hooks/usePdfAnnotationsByPage.d.ts.map +1 -0
  105. package/build/types/pdf-viewer/hooks/usePdfFormFields.d.ts +24 -0
  106. package/build/types/pdf-viewer/hooks/usePdfFormFields.d.ts.map +1 -0
  107. package/build/types/pdf-viewer/hooks/usePdfHighlightMode.d.ts +35 -0
  108. package/build/types/pdf-viewer/hooks/usePdfHighlightMode.d.ts.map +1 -0
  109. package/build/types/pdf-viewer/hooks/usePdfViewer.d.ts.map +1 -1
  110. package/build/types/pdf-viewer/types.d.ts +90 -13
  111. package/build/types/pdf-viewer/types.d.ts.map +1 -1
  112. package/build/types/public/experimental.d.ts +4 -1
  113. package/build/types/public/experimental.d.ts.map +1 -1
  114. package/package.json +5 -5
  115. package/build/browser/action-form/fields/TextInputField.module.css.js +0 -6
@@ -16,7 +16,8 @@
16
16
 
17
17
  import { Button } from "@base-ui/react/button";
18
18
  import { Input } from "@base-ui/react/input";
19
- import { ChevronLeft, ChevronRight, Download, Menu, Minus, Plus, RotatePage, Search } from "@blueprintjs/icons";
19
+ import { ChevronLeft, ChevronRight, Download, FloppyDisk, Highlight, Menu, Minus, Plus, RotatePage, Search } from "@blueprintjs/icons";
20
+ import classnames from "classnames";
20
21
  import React, { useCallback, useEffect, useState } from "react";
21
22
  import { MAX_SCALE, MIN_SCALE, SCALE_STEP } from "../constants.js";
22
23
  import styles from "./PdfViewerToolbar.module.css";
@@ -32,7 +33,12 @@ export function PdfViewerToolbar({
32
33
  onDownload,
33
34
  enableDownload,
34
35
  onRotateLeft,
35
- onRotateRight
36
+ onRotateRight,
37
+ enableHighlight,
38
+ highlightModeActive,
39
+ onHighlightToggle,
40
+ enableFormSave = false,
41
+ onFormSave
36
42
  }) {
37
43
  const [pageInputValue, setPageInputValue] = useState(String(currentPage));
38
44
 
@@ -169,6 +175,17 @@ export function PdfViewerToolbar({
169
175
  style: {
170
176
  transform: "scaleX(-1)"
171
177
  }
178
+ }))), enableHighlight && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
179
+ className: styles.separator
180
+ }), /*#__PURE__*/React.createElement(Button, {
181
+ className: classnames(styles.toolbarButton, highlightModeActive && styles.toolbarButtonActive),
182
+ onClick: onHighlightToggle,
183
+ "aria-label": highlightModeActive ? "Disable highlight mode" : "Enable highlight mode",
184
+ title: highlightModeActive ? "Disable highlight mode" : "Enable highlight mode",
185
+ "aria-pressed": highlightModeActive,
186
+ type: "button"
187
+ }, /*#__PURE__*/React.createElement(Highlight, {
188
+ size: 16
172
189
  }))), /*#__PURE__*/React.createElement("div", {
173
190
  className: styles.separator
174
191
  }), /*#__PURE__*/React.createElement(Button, {
@@ -189,6 +206,16 @@ export function PdfViewerToolbar({
189
206
  type: "button"
190
207
  }, /*#__PURE__*/React.createElement(Download, {
191
208
  size: 16
209
+ }))), enableFormSave && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
210
+ className: styles.separator
211
+ }), /*#__PURE__*/React.createElement(Button, {
212
+ className: styles.toolbarButton,
213
+ onClick: onFormSave,
214
+ "aria-label": "Save form",
215
+ title: "Save form",
216
+ type: "button"
217
+ }, /*#__PURE__*/React.createElement(FloppyDisk, {
218
+ size: 16
192
219
  }))));
193
220
  }
194
221
  //# sourceMappingURL=PdfViewerToolbar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PdfViewerToolbar.js","names":["Button","Input","ChevronLeft","ChevronRight","Download","Menu","Minus","Plus","RotatePage","Search","React","useCallback","useEffect","useState","MAX_SCALE","MIN_SCALE","SCALE_STEP","styles","PdfViewerToolbar","currentPage","numPages","scale","sidebarOpen","onPageChange","onScaleChange","onSearchOpen","onSidebarToggle","onDownload","enableDownload","onRotateLeft","onRotateRight","pageInputValue","setPageInputValue","String","handlePrevPage","newPage","handleNextPage","handlePageInputChange","e","target","value","handlePageInputKeyDown","key","page","parseInt","isNaN","handlePageInputBlur","handleZoomIn","newScale","Math","min","handleZoomOut","max","scalePercent","round","createElement","className","toolbar","toolbarButton","onClick","title","type","size","separator","toolbarGroup","disabled","pageInput","onChange","onKeyDown","onBlur","pageCount","scaleDisplay","style","transform","Fragment"],"sources":["PdfViewerToolbar.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Button } from \"@base-ui/react/button\";\nimport { Input } from \"@base-ui/react/input\";\nimport {\n ChevronLeft,\n ChevronRight,\n Download,\n Menu,\n Minus,\n Plus,\n RotatePage,\n Search,\n} from \"@blueprintjs/icons\";\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport { MAX_SCALE, MIN_SCALE, SCALE_STEP } from \"../constants.js\";\nimport styles from \"./PdfViewerToolbar.module.css\";\n\nexport interface PdfViewerToolbarProps {\n currentPage: number;\n numPages: number;\n scale: number;\n sidebarOpen: boolean;\n onPageChange: (page: number) => void;\n onScaleChange: (scale: number) => void;\n onSearchOpen: () => void;\n onSidebarToggle: () => void;\n onDownload: () => void;\n enableDownload: boolean;\n onRotateLeft: () => void;\n onRotateRight: () => void;\n}\n\nexport function PdfViewerToolbar({\n currentPage,\n numPages,\n scale,\n sidebarOpen,\n onPageChange,\n onScaleChange,\n onSearchOpen,\n onSidebarToggle,\n onDownload,\n enableDownload,\n onRotateLeft,\n onRotateRight,\n}: PdfViewerToolbarProps): React.ReactElement {\n const [pageInputValue, setPageInputValue] = useState(String(currentPage));\n\n // Sync input display when currentPage changes from scrolling\n useEffect(function syncPageInput() {\n setPageInputValue(String(currentPage));\n }, [currentPage]);\n\n const handlePrevPage = useCallback(() => {\n if (currentPage > 1) {\n const newPage = currentPage - 1;\n onPageChange(newPage);\n setPageInputValue(String(newPage));\n }\n }, [currentPage, onPageChange]);\n\n const handleNextPage = useCallback(() => {\n if (currentPage < numPages) {\n const newPage = currentPage + 1;\n onPageChange(newPage);\n setPageInputValue(String(newPage));\n }\n }, [currentPage, numPages, onPageChange]);\n\n const handlePageInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n setPageInputValue(e.target.value);\n },\n [],\n );\n\n const handlePageInputKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n const page = parseInt(pageInputValue, 10);\n if (!isNaN(page) && page >= 1 && page <= numPages) {\n onPageChange(page);\n } else {\n setPageInputValue(String(currentPage));\n }\n }\n },\n [pageInputValue, numPages, onPageChange, currentPage],\n );\n\n const handlePageInputBlur = useCallback(() => {\n setPageInputValue(String(currentPage));\n }, [currentPage]);\n\n const handleZoomIn = useCallback(() => {\n const newScale = Math.min(scale + SCALE_STEP, MAX_SCALE);\n onScaleChange(newScale);\n }, [scale, onScaleChange]);\n\n const handleZoomOut = useCallback(() => {\n const newScale = Math.max(scale - SCALE_STEP, MIN_SCALE);\n onScaleChange(newScale);\n }, [scale, onScaleChange]);\n\n const scalePercent = `${Math.round(scale * 100)}%`;\n\n return (\n <div className={styles.toolbar}>\n <Button\n className={styles.toolbarButton}\n onClick={onSidebarToggle}\n aria-label={sidebarOpen ? \"Close sidebar\" : \"Open sidebar\"}\n title={sidebarOpen ? \"Close sidebar\" : \"Open sidebar\"}\n aria-pressed={sidebarOpen}\n type=\"button\"\n >\n <Menu size={16} />\n </Button>\n\n <div className={styles.separator} />\n\n <div className={styles.toolbarGroup}>\n <Button\n className={styles.toolbarButton}\n onClick={handlePrevPage}\n disabled={currentPage <= 1}\n aria-label=\"Previous page\"\n title=\"Previous page\"\n type=\"button\"\n >\n <ChevronLeft size={16} />\n </Button>\n <Input\n className={styles.pageInput}\n type=\"text\"\n value={pageInputValue}\n onChange={handlePageInputChange}\n onKeyDown={handlePageInputKeyDown}\n onBlur={handlePageInputBlur}\n aria-label=\"Page number\"\n />\n <span className={styles.pageCount}>of {numPages}</span>\n <Button\n className={styles.toolbarButton}\n onClick={handleNextPage}\n disabled={currentPage >= numPages}\n aria-label=\"Next page\"\n title=\"Next page\"\n type=\"button\"\n >\n <ChevronRight size={16} />\n </Button>\n </div>\n\n <div className={styles.separator} />\n\n <div className={styles.toolbarGroup}>\n <Button\n className={styles.toolbarButton}\n onClick={handleZoomOut}\n disabled={scale <= MIN_SCALE}\n aria-label=\"Zoom out\"\n title=\"Zoom out\"\n type=\"button\"\n >\n <Minus size={16} />\n </Button>\n <span className={styles.scaleDisplay}>{scalePercent}</span>\n <Button\n className={styles.toolbarButton}\n onClick={handleZoomIn}\n disabled={scale >= MAX_SCALE}\n aria-label=\"Zoom in\"\n title=\"Zoom in\"\n type=\"button\"\n >\n <Plus size={16} />\n </Button>\n </div>\n\n <div className={styles.separator} />\n\n <div className={styles.toolbarGroup}>\n <Button\n className={styles.toolbarButton}\n onClick={onRotateLeft}\n aria-label=\"Rotate left\"\n title=\"Rotate left\"\n type=\"button\"\n >\n <RotatePage size={16} />\n </Button>\n <Button\n className={styles.toolbarButton}\n onClick={onRotateRight}\n aria-label=\"Rotate right\"\n title=\"Rotate right\"\n type=\"button\"\n >\n <RotatePage size={16} style={{ transform: \"scaleX(-1)\" }} />\n </Button>\n </div>\n\n <div className={styles.separator} />\n\n <Button\n className={styles.toolbarButton}\n onClick={onSearchOpen}\n aria-label=\"Search\"\n title=\"Search\"\n type=\"button\"\n >\n <Search size={16} />\n </Button>\n\n {enableDownload && (\n <>\n <div className={styles.separator} />\n\n <Button\n className={styles.toolbarButton}\n onClick={onDownload}\n aria-label=\"Download\"\n title=\"Download\"\n type=\"button\"\n >\n <Download size={16} />\n </Button>\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"PdfViewerToolbar.js","names":["Button","Input","ChevronLeft","ChevronRight","Download","FloppyDisk","Highlight","Menu","Minus","Plus","RotatePage","Search","classnames","React","useCallback","useEffect","useState","MAX_SCALE","MIN_SCALE","SCALE_STEP","styles","PdfViewerToolbar","currentPage","numPages","scale","sidebarOpen","onPageChange","onScaleChange","onSearchOpen","onSidebarToggle","onDownload","enableDownload","onRotateLeft","onRotateRight","enableHighlight","highlightModeActive","onHighlightToggle","enableFormSave","onFormSave","pageInputValue","setPageInputValue","String","handlePrevPage","newPage","handleNextPage","handlePageInputChange","e","target","value","handlePageInputKeyDown","key","page","parseInt","isNaN","handlePageInputBlur","handleZoomIn","newScale","Math","min","handleZoomOut","max","scalePercent","round","createElement","className","toolbar","toolbarButton","onClick","title","type","size","separator","toolbarGroup","disabled","pageInput","onChange","onKeyDown","onBlur","pageCount","scaleDisplay","style","transform","Fragment","toolbarButtonActive"],"sources":["PdfViewerToolbar.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Button } from \"@base-ui/react/button\";\nimport { Input } from \"@base-ui/react/input\";\nimport {\n ChevronLeft,\n ChevronRight,\n Download,\n FloppyDisk,\n Highlight,\n Menu,\n Minus,\n Plus,\n RotatePage,\n Search,\n} from \"@blueprintjs/icons\";\nimport classnames from \"classnames\";\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport { MAX_SCALE, MIN_SCALE, SCALE_STEP } from \"../constants.js\";\nimport styles from \"./PdfViewerToolbar.module.css\";\n\nexport interface PdfViewerToolbarProps {\n currentPage: number;\n numPages: number;\n scale: number;\n sidebarOpen: boolean;\n onPageChange: (page: number) => void;\n onScaleChange: (scale: number) => void;\n onSearchOpen: () => void;\n onSidebarToggle: () => void;\n onDownload: () => void;\n enableDownload: boolean;\n onRotateLeft: () => void;\n onRotateRight: () => void;\n enableHighlight: boolean;\n highlightModeActive: boolean;\n onHighlightToggle: () => void;\n enableFormSave?: boolean;\n onFormSave?: () => void;\n}\n\nexport function PdfViewerToolbar({\n currentPage,\n numPages,\n scale,\n sidebarOpen,\n onPageChange,\n onScaleChange,\n onSearchOpen,\n onSidebarToggle,\n onDownload,\n enableDownload,\n onRotateLeft,\n onRotateRight,\n enableHighlight,\n highlightModeActive,\n onHighlightToggle,\n enableFormSave = false,\n onFormSave,\n}: PdfViewerToolbarProps): React.ReactElement {\n const [pageInputValue, setPageInputValue] = useState(String(currentPage));\n\n // Sync input display when currentPage changes from scrolling\n useEffect(function syncPageInput() {\n setPageInputValue(String(currentPage));\n }, [currentPage]);\n\n const handlePrevPage = useCallback(() => {\n if (currentPage > 1) {\n const newPage = currentPage - 1;\n onPageChange(newPage);\n setPageInputValue(String(newPage));\n }\n }, [currentPage, onPageChange]);\n\n const handleNextPage = useCallback(() => {\n if (currentPage < numPages) {\n const newPage = currentPage + 1;\n onPageChange(newPage);\n setPageInputValue(String(newPage));\n }\n }, [currentPage, numPages, onPageChange]);\n\n const handlePageInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n setPageInputValue(e.target.value);\n },\n [],\n );\n\n const handlePageInputKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n const page = parseInt(pageInputValue, 10);\n if (!isNaN(page) && page >= 1 && page <= numPages) {\n onPageChange(page);\n } else {\n setPageInputValue(String(currentPage));\n }\n }\n },\n [pageInputValue, numPages, onPageChange, currentPage],\n );\n\n const handlePageInputBlur = useCallback(() => {\n setPageInputValue(String(currentPage));\n }, [currentPage]);\n\n const handleZoomIn = useCallback(() => {\n const newScale = Math.min(scale + SCALE_STEP, MAX_SCALE);\n onScaleChange(newScale);\n }, [scale, onScaleChange]);\n\n const handleZoomOut = useCallback(() => {\n const newScale = Math.max(scale - SCALE_STEP, MIN_SCALE);\n onScaleChange(newScale);\n }, [scale, onScaleChange]);\n\n const scalePercent = `${Math.round(scale * 100)}%`;\n\n return (\n <div className={styles.toolbar}>\n <Button\n className={styles.toolbarButton}\n onClick={onSidebarToggle}\n aria-label={sidebarOpen ? \"Close sidebar\" : \"Open sidebar\"}\n title={sidebarOpen ? \"Close sidebar\" : \"Open sidebar\"}\n aria-pressed={sidebarOpen}\n type=\"button\"\n >\n <Menu size={16} />\n </Button>\n\n <div className={styles.separator} />\n\n <div className={styles.toolbarGroup}>\n <Button\n className={styles.toolbarButton}\n onClick={handlePrevPage}\n disabled={currentPage <= 1}\n aria-label=\"Previous page\"\n title=\"Previous page\"\n type=\"button\"\n >\n <ChevronLeft size={16} />\n </Button>\n <Input\n className={styles.pageInput}\n type=\"text\"\n value={pageInputValue}\n onChange={handlePageInputChange}\n onKeyDown={handlePageInputKeyDown}\n onBlur={handlePageInputBlur}\n aria-label=\"Page number\"\n />\n <span className={styles.pageCount}>of {numPages}</span>\n <Button\n className={styles.toolbarButton}\n onClick={handleNextPage}\n disabled={currentPage >= numPages}\n aria-label=\"Next page\"\n title=\"Next page\"\n type=\"button\"\n >\n <ChevronRight size={16} />\n </Button>\n </div>\n\n <div className={styles.separator} />\n\n <div className={styles.toolbarGroup}>\n <Button\n className={styles.toolbarButton}\n onClick={handleZoomOut}\n disabled={scale <= MIN_SCALE}\n aria-label=\"Zoom out\"\n title=\"Zoom out\"\n type=\"button\"\n >\n <Minus size={16} />\n </Button>\n <span className={styles.scaleDisplay}>{scalePercent}</span>\n <Button\n className={styles.toolbarButton}\n onClick={handleZoomIn}\n disabled={scale >= MAX_SCALE}\n aria-label=\"Zoom in\"\n title=\"Zoom in\"\n type=\"button\"\n >\n <Plus size={16} />\n </Button>\n </div>\n\n <div className={styles.separator} />\n\n <div className={styles.toolbarGroup}>\n <Button\n className={styles.toolbarButton}\n onClick={onRotateLeft}\n aria-label=\"Rotate left\"\n title=\"Rotate left\"\n type=\"button\"\n >\n <RotatePage size={16} />\n </Button>\n <Button\n className={styles.toolbarButton}\n onClick={onRotateRight}\n aria-label=\"Rotate right\"\n title=\"Rotate right\"\n type=\"button\"\n >\n <RotatePage size={16} style={{ transform: \"scaleX(-1)\" }} />\n </Button>\n </div>\n\n {enableHighlight && (\n <>\n <div className={styles.separator} />\n\n <Button\n className={classnames(\n styles.toolbarButton,\n highlightModeActive && styles.toolbarButtonActive,\n )}\n onClick={onHighlightToggle}\n aria-label={highlightModeActive\n ? \"Disable highlight mode\"\n : \"Enable highlight mode\"}\n title={highlightModeActive\n ? \"Disable highlight mode\"\n : \"Enable highlight mode\"}\n aria-pressed={highlightModeActive}\n type=\"button\"\n >\n <Highlight size={16} />\n </Button>\n </>\n )}\n\n <div className={styles.separator} />\n\n <Button\n className={styles.toolbarButton}\n onClick={onSearchOpen}\n aria-label=\"Search\"\n title=\"Search\"\n type=\"button\"\n >\n <Search size={16} />\n </Button>\n\n {enableDownload && (\n <>\n <div className={styles.separator} />\n\n <Button\n className={styles.toolbarButton}\n onClick={onDownload}\n aria-label=\"Download\"\n title=\"Download\"\n type=\"button\"\n >\n <Download size={16} />\n </Button>\n </>\n )}\n\n {enableFormSave && (\n <>\n <div className={styles.separator} />\n\n <Button\n className={styles.toolbarButton}\n onClick={onFormSave}\n aria-label=\"Save form\"\n title=\"Save form\"\n type=\"button\"\n >\n <FloppyDisk size={16} />\n </Button>\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -57,6 +57,11 @@
57
57
  cursor: default;
58
58
  }
59
59
 
60
+ .toolbarButtonActive {
61
+ background-color: var(--osdk-surface-background-color-default-active);
62
+ color: var(--osdk-typography-color-default-rest);
63
+ }
64
+
60
65
  .pageInput {
61
66
  width: 48px;
62
67
  text-align: center;
@@ -15,7 +15,6 @@
15
15
  */
16
16
 
17
17
  // Default empty values (stable references to avoid re-renders)
18
- export const EMPTY_ANNOTATIONS = {};
19
18
  export const EMPTY_ANNOTATION_ARRAY = [];
20
19
  export const EMPTY_STRING = "";
21
20
 
@@ -42,4 +41,6 @@ export const PAGE_CHANGING_EVENT = "pagechanging";
42
41
  export const SCALE_CHANGING_EVENT = "scalechanging";
43
42
  export const PAGE_RENDERED_EVENT = "pagerendered";
44
43
  export const PAGES_LOADED_EVENT = "pagesloaded";
44
+ // cspell:disable-next-line -- pdfjs EventBus event name
45
+ export const ANNOTATION_LAYER_RENDERED_EVENT = "annotationlayerrendered";
45
46
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","names":["EMPTY_ANNOTATIONS","EMPTY_ANNOTATION_ARRAY","EMPTY_STRING","SCALE_STEP","MIN_SCALE","MAX_SCALE","DEFAULT_PAGE_HEIGHT","THUMBNAIL_GAP","THUMBNAIL_SCALE","DEVICE_PIXEL_RATIO","window","devicePixelRatio","OUTLINE_HEADING_SIZE_RATIO","OUTLINE_MAX_HEADING_LENGTH","FIND_EVENT","UPDATE_FIND_CONTROL_STATE_EVENT","UPDATE_FIND_MATCHES_COUNT_EVENT","PAGE_CHANGING_EVENT","SCALE_CHANGING_EVENT","PAGE_RENDERED_EVENT","PAGES_LOADED_EVENT"],"sources":["constants.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { PdfAnnotation } from \"./types.js\";\n\n// Default empty values (stable references to avoid re-renders)\nexport const EMPTY_ANNOTATIONS: Record<number, PdfAnnotation[]> = {};\nexport const EMPTY_ANNOTATION_ARRAY: PdfAnnotation[] = [];\nexport const EMPTY_STRING = \"\";\n\n// Scale and dimension configuration\nexport const SCALE_STEP = 0.25;\nexport const MIN_SCALE = 0.25;\nexport const MAX_SCALE = 5.0;\nexport const DEFAULT_PAGE_HEIGHT = 792;\nexport const THUMBNAIL_GAP = 12;\nexport const THUMBNAIL_SCALE = 0.2;\nexport const DEVICE_PIXEL_RATIO: number = typeof window !== \"undefined\"\n ? window.devicePixelRatio || 1\n : 1;\n\n// Outline heading extraction\n/** Text must be at least 15% larger than the most common font size to be considered a heading. */\nexport const OUTLINE_HEADING_SIZE_RATIO = 1.15;\n/** Headings longer than this are likely paragraphs and are filtered out. */\nexport const OUTLINE_MAX_HEADING_LENGTH = 200;\n\n// pdfjs EventBus event names\nexport const FIND_EVENT = \"find\";\nexport const UPDATE_FIND_CONTROL_STATE_EVENT = \"updatefindcontrolstate\";\nexport const UPDATE_FIND_MATCHES_COUNT_EVENT = \"updatefindmatchescount\";\nexport const PAGE_CHANGING_EVENT = \"pagechanging\";\nexport const SCALE_CHANGING_EVENT = \"scalechanging\";\nexport const PAGE_RENDERED_EVENT = \"pagerendered\";\nexport const PAGES_LOADED_EVENT = \"pagesloaded\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA,OAAO,MAAMA,iBAAkD,GAAG,CAAC,CAAC;AACpE,OAAO,MAAMC,sBAAuC,GAAG,EAAE;AACzD,OAAO,MAAMC,YAAY,GAAG,EAAE;;AAE9B;AACA,OAAO,MAAMC,UAAU,GAAG,IAAI;AAC9B,OAAO,MAAMC,SAAS,GAAG,IAAI;AAC7B,OAAO,MAAMC,SAAS,GAAG,GAAG;AAC5B,OAAO,MAAMC,mBAAmB,GAAG,GAAG;AACtC,OAAO,MAAMC,aAAa,GAAG,EAAE;AAC/B,OAAO,MAAMC,eAAe,GAAG,GAAG;AAClC,OAAO,MAAMC,kBAA0B,GAAG,OAAOC,MAAM,KAAK,WAAW,GACnEA,MAAM,CAACC,gBAAgB,IAAI,CAAC,GAC5B,CAAC;;AAEL;AACA;AACA,OAAO,MAAMC,0BAA0B,GAAG,IAAI;AAC9C;AACA,OAAO,MAAMC,0BAA0B,GAAG,GAAG;;AAE7C;AACA,OAAO,MAAMC,UAAU,GAAG,MAAM;AAChC,OAAO,MAAMC,+BAA+B,GAAG,wBAAwB;AACvE,OAAO,MAAMC,+BAA+B,GAAG,wBAAwB;AACvE,OAAO,MAAMC,mBAAmB,GAAG,cAAc;AACjD,OAAO,MAAMC,oBAAoB,GAAG,eAAe;AACnD,OAAO,MAAMC,mBAAmB,GAAG,cAAc;AACjD,OAAO,MAAMC,kBAAkB,GAAG,aAAa","ignoreList":[]}
1
+ {"version":3,"file":"constants.js","names":["EMPTY_ANNOTATION_ARRAY","EMPTY_STRING","SCALE_STEP","MIN_SCALE","MAX_SCALE","DEFAULT_PAGE_HEIGHT","THUMBNAIL_GAP","THUMBNAIL_SCALE","DEVICE_PIXEL_RATIO","window","devicePixelRatio","OUTLINE_HEADING_SIZE_RATIO","OUTLINE_MAX_HEADING_LENGTH","FIND_EVENT","UPDATE_FIND_CONTROL_STATE_EVENT","UPDATE_FIND_MATCHES_COUNT_EVENT","PAGE_CHANGING_EVENT","SCALE_CHANGING_EVENT","PAGE_RENDERED_EVENT","PAGES_LOADED_EVENT","ANNOTATION_LAYER_RENDERED_EVENT"],"sources":["constants.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { PdfAnnotation } from \"./types.js\";\n\n// Default empty values (stable references to avoid re-renders)\nexport const EMPTY_ANNOTATION_ARRAY: PdfAnnotation[] = [];\nexport const EMPTY_STRING = \"\";\n\n// Scale and dimension configuration\nexport const SCALE_STEP = 0.25;\nexport const MIN_SCALE = 0.25;\nexport const MAX_SCALE = 5.0;\nexport const DEFAULT_PAGE_HEIGHT = 792;\nexport const THUMBNAIL_GAP = 12;\nexport const THUMBNAIL_SCALE = 0.2;\nexport const DEVICE_PIXEL_RATIO: number = typeof window !== \"undefined\"\n ? window.devicePixelRatio || 1\n : 1;\n\n// Outline heading extraction\n/** Text must be at least 15% larger than the most common font size to be considered a heading. */\nexport const OUTLINE_HEADING_SIZE_RATIO = 1.15;\n/** Headings longer than this are likely paragraphs and are filtered out. */\nexport const OUTLINE_MAX_HEADING_LENGTH = 200;\n\n// pdfjs EventBus event names\nexport const FIND_EVENT = \"find\";\nexport const UPDATE_FIND_CONTROL_STATE_EVENT = \"updatefindcontrolstate\";\nexport const UPDATE_FIND_MATCHES_COUNT_EVENT = \"updatefindmatchescount\";\nexport const PAGE_CHANGING_EVENT = \"pagechanging\";\nexport const SCALE_CHANGING_EVENT = \"scalechanging\";\nexport const PAGE_RENDERED_EVENT = \"pagerendered\";\nexport const PAGES_LOADED_EVENT = \"pagesloaded\";\n// cspell:disable-next-line -- pdfjs EventBus event name\nexport const ANNOTATION_LAYER_RENDERED_EVENT = \"annotationlayerrendered\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA,OAAO,MAAMA,sBAAuC,GAAG,EAAE;AACzD,OAAO,MAAMC,YAAY,GAAG,EAAE;;AAE9B;AACA,OAAO,MAAMC,UAAU,GAAG,IAAI;AAC9B,OAAO,MAAMC,SAAS,GAAG,IAAI;AAC7B,OAAO,MAAMC,SAAS,GAAG,GAAG;AAC5B,OAAO,MAAMC,mBAAmB,GAAG,GAAG;AACtC,OAAO,MAAMC,aAAa,GAAG,EAAE;AAC/B,OAAO,MAAMC,eAAe,GAAG,GAAG;AAClC,OAAO,MAAMC,kBAA0B,GAAG,OAAOC,MAAM,KAAK,WAAW,GACnEA,MAAM,CAACC,gBAAgB,IAAI,CAAC,GAC5B,CAAC;;AAEL;AACA;AACA,OAAO,MAAMC,0BAA0B,GAAG,IAAI;AAC9C;AACA,OAAO,MAAMC,0BAA0B,GAAG,GAAG;;AAE7C;AACA,OAAO,MAAMC,UAAU,GAAG,MAAM;AAChC,OAAO,MAAMC,+BAA+B,GAAG,wBAAwB;AACvE,OAAO,MAAMC,+BAA+B,GAAG,wBAAwB;AACvE,OAAO,MAAMC,mBAAmB,GAAG,cAAc;AACjD,OAAO,MAAMC,oBAAoB,GAAG,eAAe;AACnD,OAAO,MAAMC,mBAAmB,GAAG,cAAc;AACjD,OAAO,MAAMC,kBAAkB,GAAG,aAAa;AAC/C;AACA,OAAO,MAAMC,+BAA+B,GAAG,yBAAyB","ignoreList":[]}
@@ -0,0 +1,30 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { useMemo } from "react";
18
+ /**
19
+ * Groups a flat array of annotations by page number for efficient per-page lookup.
20
+ */
21
+ export function usePdfAnnotationsByPage(annotations) {
22
+ return useMemo(() => {
23
+ const result = {};
24
+ for (const ann of annotations) {
25
+ (result[ann.page] ??= []).push(ann);
26
+ }
27
+ return result;
28
+ }, [annotations]);
29
+ }
30
+ //# sourceMappingURL=usePdfAnnotationsByPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePdfAnnotationsByPage.js","names":["useMemo","usePdfAnnotationsByPage","annotations","result","ann","page","push"],"sources":["usePdfAnnotationsByPage.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useMemo } from \"react\";\nimport type { PdfAnnotation } from \"../types.js\";\n\n/**\n * Groups a flat array of annotations by page number for efficient per-page lookup.\n */\nexport function usePdfAnnotationsByPage(\n annotations: PdfAnnotation[],\n): Record<number, PdfAnnotation[]> {\n return useMemo(() => {\n const result: Record<number, PdfAnnotation[]> = {};\n for (const ann of annotations) {\n (result[ann.page] ??= []).push(ann);\n }\n return result;\n }, [annotations]);\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,OAAO,QAAQ,OAAO;AAG/B;AACA;AACA;AACA,OAAO,SAASC,uBAAuBA,CACrCC,WAA4B,EACK;EACjC,OAAOF,OAAO,CAAC,MAAM;IACnB,MAAMG,MAAuC,GAAG,CAAC,CAAC;IAClD,KAAK,MAAMC,GAAG,IAAIF,WAAW,EAAE;MAC7B,CAACC,MAAM,CAACC,GAAG,CAACC,IAAI,CAAC,KAAK,EAAE,EAAEC,IAAI,CAACF,GAAG,CAAC;IACrC;IACA,OAAOD,MAAM;EACf,CAAC,EAAE,CAACD,WAAW,CAAC,CAAC;AACnB","ignoreList":[]}
@@ -0,0 +1,326 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { useCallback, useEffect, useRef, useState } from "react";
18
+ import { ANNOTATION_LAYER_RENDERED_EVENT } from "../constants.js";
19
+ /** Get the viewer's container element (typed loosely by pdf.js). */
20
+ function getViewerContainer(viewer) {
21
+ return viewer.container;
22
+ }
23
+
24
+ /** Internal metadata for a single form field annotation. */
25
+
26
+ /**
27
+ * Normalizes a pdf.js field object type string to a simplified form type.
28
+ * @internal Exported for testing.
29
+ */
30
+ export function normalizeFieldType(type) {
31
+ switch (type) {
32
+ case "checkbox":
33
+ case "radiobutton":
34
+ case "combobox":
35
+ case "listbox":
36
+ return type;
37
+ default:
38
+ return "text";
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Converts a pdf.js annotationStorage value to a consumer-friendly PdfFormFieldValue.
44
+ * @internal Exported for testing.
45
+ */
46
+ export function toFormFieldValue(storageValue, fieldType) {
47
+ if (fieldType === "checkbox") {
48
+ if (typeof storageValue === "boolean") {
49
+ return storageValue;
50
+ }
51
+ // pdf.js stores checkbox as the export value when checked, "Off" when unchecked
52
+ return storageValue !== "Off" && storageValue !== false;
53
+ }
54
+ if (fieldType === "radiobutton") {
55
+ return typeof storageValue === "string" ? storageValue : "";
56
+ }
57
+ if (typeof storageValue === "string") {
58
+ return storageValue;
59
+ }
60
+ if (Array.isArray(storageValue)) {
61
+ return storageValue.map(String);
62
+ }
63
+ return "";
64
+ }
65
+
66
+ /**
67
+ * Converts a consumer PdfFormFieldValue to a pdf.js annotationStorage value.
68
+ * @internal Exported for testing.
69
+ */
70
+ export function toStorageValue(formValue, fieldType) {
71
+ if (fieldType === "checkbox") {
72
+ if (typeof formValue === "boolean") {
73
+ return formValue;
74
+ }
75
+ return formValue !== "Off" && formValue !== "";
76
+ }
77
+ return formValue;
78
+ }
79
+
80
+ /**
81
+ * Hook that manages interactive PDF form fields.
82
+ * Builds a field metadata map, pre-populates initial values,
83
+ * listens for field changes, and collects values on submit.
84
+ */
85
+ export function usePdfFormFields({
86
+ pdfViewerRef,
87
+ eventBusRef,
88
+ document,
89
+ formData,
90
+ onFormSubmit,
91
+ onFormChange
92
+ }) {
93
+ const [hasFormFields, setHasFormFields] = useState(false);
94
+
95
+ // Stable refs for callbacks
96
+ const onFormSubmitRef = useRef(onFormSubmit);
97
+ const onFormChangeRef = useRef(onFormChange);
98
+ const formDataRef = useRef(formData);
99
+ useEffect(function () {
100
+ onFormSubmitRef.current = onFormSubmit;
101
+ onFormChangeRef.current = onFormChange;
102
+ formDataRef.current = formData;
103
+ }, [onFormSubmit, onFormChange, formData]);
104
+
105
+ // Map from annotation ID -> field metadata
106
+ const fieldMapRef = useRef(new Map());
107
+ // Reverse map from field name -> annotation IDs
108
+ const nameToIdsRef = useRef(new Map());
109
+
110
+ // Effect 1: Build field metadata map when document loads
111
+ useEffect(function () {
112
+ const doc = document;
113
+ if (doc == null) {
114
+ fieldMapRef.current.clear();
115
+ nameToIdsRef.current.clear();
116
+ setHasFormFields(false);
117
+ return;
118
+ }
119
+ let cancelled = false;
120
+ void doc.getFieldObjects().then(fieldObjects => {
121
+ if (cancelled || fieldObjects == null) {
122
+ setHasFormFields(false);
123
+ return;
124
+ }
125
+ const fieldMap = new Map();
126
+ const nameToIds = new Map();
127
+ for (const [fieldName, objects] of Object.entries(fieldObjects)) {
128
+ const ids = [];
129
+ for (const obj of objects) {
130
+ const typedObj = obj;
131
+ if (typedObj.id == null) continue;
132
+ const fieldType = normalizeFieldType(typedObj.type ?? "text");
133
+ fieldMap.set(typedObj.id, {
134
+ fieldName,
135
+ fieldType,
136
+ exportValues: typedObj.exportValues,
137
+ page: typedObj.page ?? 0
138
+ });
139
+ ids.push(typedObj.id);
140
+ }
141
+ if (ids.length > 0) {
142
+ nameToIds.set(fieldName, ids);
143
+ }
144
+ }
145
+ fieldMapRef.current = fieldMap;
146
+ nameToIdsRef.current = nameToIds;
147
+ setHasFormFields(fieldMap.size > 0);
148
+ });
149
+ return () => {
150
+ cancelled = true;
151
+ };
152
+ }, [document]);
153
+
154
+ // Populates form fields from formData into both annotation storage and DOM elements.
155
+ // Scoped to the viewer container to avoid conflicts with multiple viewer instances.
156
+ const populateFields = useCallback(() => {
157
+ const data = formDataRef.current;
158
+ const doc = document;
159
+ const pdfViewer = pdfViewerRef.current;
160
+ if (data == null || doc == null || pdfViewer == null) return;
161
+ if (fieldMapRef.current.size === 0) return;
162
+ const storage = doc.annotationStorage;
163
+ const container = getViewerContainer(pdfViewer);
164
+ for (const [fieldName, value] of Object.entries(data)) {
165
+ const ids = nameToIdsRef.current.get(fieldName);
166
+ if (ids == null) continue;
167
+ for (const id of ids) {
168
+ const entry = fieldMapRef.current.get(id);
169
+ if (entry == null) continue;
170
+ const storageVal = toStorageValue(value, entry.fieldType);
171
+ storage.setValue(id, {
172
+ value: storageVal
173
+ });
174
+
175
+ // Also update the DOM element directly (scoped to viewer container)
176
+ const el = container?.querySelector(`[data-element-id="${CSS.escape(id)}"]`);
177
+ if (el == null) continue;
178
+ if (entry.fieldType === "checkbox" && el instanceof HTMLInputElement) {
179
+ el.checked = typeof storageVal === "boolean" ? storageVal : storageVal !== "Off";
180
+ } else if (el instanceof HTMLSelectElement) {
181
+ el.value = String(value);
182
+ } else if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
183
+ el.value = String(value);
184
+ }
185
+ }
186
+ }
187
+ }, [document, pdfViewerRef]);
188
+
189
+ // Effect 2: Populate initial form data when annotation layers render
190
+ useEffect(function () {
191
+ const eventBus = eventBusRef.current;
192
+ if (eventBus == null || document == null || formDataRef.current == null) {
193
+ return;
194
+ }
195
+
196
+ // Attempt population immediately in case the field map was built
197
+ // after the annotation layer already rendered (race condition fix).
198
+ populateFields();
199
+ const onAnnotationLayerRendered = () => {
200
+ populateFields();
201
+ };
202
+ eventBus.on(ANNOTATION_LAYER_RENDERED_EVENT, onAnnotationLayerRendered);
203
+ return () => {
204
+ eventBus.off(ANNOTATION_LAYER_RENDERED_EVENT, onAnnotationLayerRendered);
205
+ };
206
+ }, [eventBusRef, document, hasFormFields, populateFields]);
207
+
208
+ // Effect 3: Listen for field changes via MutationObserver + event listeners
209
+ useEffect(function () {
210
+ const pdfViewer = pdfViewerRef.current;
211
+ if (pdfViewer == null || document == null) {
212
+ return;
213
+ }
214
+
215
+ // Get the viewer's container element
216
+ const container = getViewerContainer(pdfViewer);
217
+ if (container == null) return;
218
+ const listeners = new Map();
219
+ function handleFieldChange(el) {
220
+ const id = el.getAttribute("data-element-id");
221
+ if (id == null) return;
222
+ const entry = fieldMapRef.current.get(id);
223
+ if (entry == null) return;
224
+ let value;
225
+ if (entry.fieldType === "checkbox" && el instanceof HTMLInputElement) {
226
+ value = el.checked;
227
+ } else if (entry.fieldType === "radiobutton" && el instanceof HTMLInputElement) {
228
+ // For radio buttons, the value is the button's export value when selected
229
+ value = el.checked ? entry.exportValues ?? el.value : "";
230
+ } else {
231
+ value = el.value;
232
+ }
233
+ onFormChangeRef.current?.(entry.fieldName, value);
234
+ }
235
+ function attachListeners(root) {
236
+ const elements = root.querySelectorAll?.(".annotationLayer input, .annotationLayer select, .annotationLayer textarea");
237
+ if (elements == null) return;
238
+ for (const el of elements) {
239
+ if (listeners.has(el)) continue;
240
+ const handler = () => {
241
+ handleFieldChange(el);
242
+ };
243
+ el.addEventListener("input", handler);
244
+ el.addEventListener("change", handler);
245
+ listeners.set(el, handler);
246
+ }
247
+ }
248
+
249
+ // Attach to any elements already in the DOM
250
+ attachListeners(container);
251
+
252
+ // Watch for new form elements being added (pages render lazily)
253
+ const observer = new MutationObserver(mutations => {
254
+ for (const mutation of mutations) {
255
+ for (const node of mutation.addedNodes) {
256
+ if (node instanceof Element) {
257
+ attachListeners(node);
258
+ }
259
+ }
260
+ }
261
+ });
262
+ observer.observe(container, {
263
+ childList: true,
264
+ subtree: true
265
+ });
266
+ return () => {
267
+ observer.disconnect();
268
+ for (const [el, handler] of listeners) {
269
+ el.removeEventListener("input", handler);
270
+ el.removeEventListener("change", handler);
271
+ }
272
+ listeners.clear();
273
+ };
274
+ }, [pdfViewerRef, document]);
275
+
276
+ // Callback: collect all form data and invoke onFormSubmit
277
+ const submitFormData = useCallback(() => {
278
+ const doc = document;
279
+ if (doc == null) return;
280
+ const storage = doc.annotationStorage;
281
+ const allValues = storage.getAll();
282
+ const result = {};
283
+
284
+ // Track which radio group has been resolved
285
+ const resolvedRadios = new Set();
286
+ for (const [id, entry] of fieldMapRef.current) {
287
+ const {
288
+ fieldName,
289
+ fieldType
290
+ } = entry;
291
+
292
+ // For radio buttons, only process each group once
293
+ if (fieldType === "radiobutton") {
294
+ if (resolvedRadios.has(fieldName)) continue;
295
+ resolvedRadios.add(fieldName);
296
+
297
+ // Find the selected radio in the group
298
+ const groupIds = nameToIdsRef.current.get(fieldName) ?? [];
299
+ let selectedValue = "";
300
+ for (const radioId of groupIds) {
301
+ const stored = allValues?.[radioId];
302
+ const val = stored != null && typeof stored === "object" && "value" in stored ? stored.value : stored;
303
+ if (val === true || typeof val === "string" && val !== "Off") {
304
+ const radioEntry = fieldMapRef.current.get(radioId);
305
+ selectedValue = radioEntry?.exportValues ?? String(val);
306
+ break;
307
+ }
308
+ }
309
+ result[fieldName] = selectedValue;
310
+ continue;
311
+ }
312
+ const stored = allValues?.[id];
313
+ const rawValue = stored != null && typeof stored === "object" && "value" in stored ? stored.value : stored;
314
+
315
+ // Skip if we already have a value for this field name (e.g. duplicate IDs)
316
+ if (fieldName in result) continue;
317
+ result[fieldName] = toFormFieldValue(rawValue, fieldType);
318
+ }
319
+ onFormSubmitRef.current?.(result);
320
+ }, [document]);
321
+ return {
322
+ hasFormFields,
323
+ submitFormData
324
+ };
325
+ }
326
+ //# sourceMappingURL=usePdfFormFields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePdfFormFields.js","names":["useCallback","useEffect","useRef","useState","ANNOTATION_LAYER_RENDERED_EVENT","getViewerContainer","viewer","container","normalizeFieldType","type","toFormFieldValue","storageValue","fieldType","Array","isArray","map","String","toStorageValue","formValue","usePdfFormFields","pdfViewerRef","eventBusRef","document","formData","onFormSubmit","onFormChange","hasFormFields","setHasFormFields","onFormSubmitRef","onFormChangeRef","formDataRef","current","fieldMapRef","Map","nameToIdsRef","doc","clear","cancelled","getFieldObjects","then","fieldObjects","fieldMap","nameToIds","fieldName","objects","Object","entries","ids","obj","typedObj","id","set","exportValues","page","push","length","size","populateFields","data","pdfViewer","storage","annotationStorage","value","get","entry","storageVal","setValue","el","querySelector","CSS","escape","HTMLInputElement","checked","HTMLSelectElement","HTMLTextAreaElement","eventBus","onAnnotationLayerRendered","on","off","listeners","handleFieldChange","getAttribute","attachListeners","root","elements","querySelectorAll","has","handler","addEventListener","observer","MutationObserver","mutations","mutation","node","addedNodes","Element","observe","childList","subtree","disconnect","removeEventListener","submitFormData","allValues","getAll","result","resolvedRadios","Set","add","groupIds","selectedValue","radioId","stored","val","radioEntry","rawValue"],"sources":["usePdfFormFields.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { PDFDocumentProxy } from \"pdfjs-dist\";\nimport type { EventBus, PDFViewer } from \"pdfjs-dist/web/pdf_viewer.mjs\";\nimport type { RefObject } from \"react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { ANNOTATION_LAYER_RENDERED_EVENT } from \"../constants.js\";\nimport type { PdfFormFieldValue } from \"../types.js\";\n\n/** Get the viewer's container element (typed loosely by pdf.js). */\nfunction getViewerContainer(viewer: PDFViewer): HTMLElement | undefined {\n return (viewer as { container?: HTMLElement }).container;\n}\n\n/** Internal metadata for a single form field annotation. */\ninterface FieldEntry {\n fieldName: string;\n fieldType: \"text\" | \"checkbox\" | \"radiobutton\" | \"combobox\" | \"listbox\";\n exportValues: string | undefined;\n page: number;\n}\n\nexport interface UsePdfFormFieldsOptions {\n pdfViewerRef: RefObject<PDFViewer | null>;\n eventBusRef: RefObject<EventBus | null>;\n document: PDFDocumentProxy | undefined;\n formData?: Record<string, PdfFormFieldValue>;\n onFormSubmit?: (data: Record<string, PdfFormFieldValue>) => void;\n onFormChange?: (fieldName: string, value: PdfFormFieldValue) => void;\n}\n\nexport interface UsePdfFormFieldsResult {\n /** Whether the loaded PDF contains interactive form fields. */\n hasFormFields: boolean;\n /** Collect all current form field values and invoke onFormSubmit. */\n submitFormData: () => void;\n}\n\n/**\n * Normalizes a pdf.js field object type string to a simplified form type.\n * @internal Exported for testing.\n */\nexport function normalizeFieldType(\n type: string,\n): \"text\" | \"checkbox\" | \"radiobutton\" | \"combobox\" | \"listbox\" {\n switch (type) {\n case \"checkbox\":\n case \"radiobutton\":\n case \"combobox\":\n case \"listbox\":\n return type;\n default:\n return \"text\";\n }\n}\n\n/**\n * Converts a pdf.js annotationStorage value to a consumer-friendly PdfFormFieldValue.\n * @internal Exported for testing.\n */\nexport function toFormFieldValue(\n storageValue: unknown,\n fieldType: \"text\" | \"checkbox\" | \"radiobutton\" | \"combobox\" | \"listbox\",\n): PdfFormFieldValue {\n if (fieldType === \"checkbox\") {\n if (typeof storageValue === \"boolean\") {\n return storageValue;\n }\n // pdf.js stores checkbox as the export value when checked, \"Off\" when unchecked\n return storageValue !== \"Off\" && storageValue !== false;\n }\n if (fieldType === \"radiobutton\") {\n return typeof storageValue === \"string\" ? storageValue : \"\";\n }\n if (typeof storageValue === \"string\") {\n return storageValue;\n }\n if (Array.isArray(storageValue)) {\n return storageValue.map(String);\n }\n return \"\";\n}\n\n/**\n * Converts a consumer PdfFormFieldValue to a pdf.js annotationStorage value.\n * @internal Exported for testing.\n */\nexport function toStorageValue(\n formValue: PdfFormFieldValue,\n fieldType: \"text\" | \"checkbox\" | \"radiobutton\" | \"combobox\" | \"listbox\",\n): unknown {\n if (fieldType === \"checkbox\") {\n if (typeof formValue === \"boolean\") {\n return formValue;\n }\n return formValue !== \"Off\" && formValue !== \"\";\n }\n return formValue;\n}\n\n/**\n * Hook that manages interactive PDF form fields.\n * Builds a field metadata map, pre-populates initial values,\n * listens for field changes, and collects values on submit.\n */\nexport function usePdfFormFields({\n pdfViewerRef,\n eventBusRef,\n document,\n formData,\n onFormSubmit,\n onFormChange,\n}: UsePdfFormFieldsOptions): UsePdfFormFieldsResult {\n const [hasFormFields, setHasFormFields] = useState(false);\n\n // Stable refs for callbacks\n const onFormSubmitRef = useRef(onFormSubmit);\n const onFormChangeRef = useRef(onFormChange);\n const formDataRef = useRef(formData);\n\n useEffect(function syncCallbackRefs() {\n onFormSubmitRef.current = onFormSubmit;\n onFormChangeRef.current = onFormChange;\n formDataRef.current = formData;\n }, [onFormSubmit, onFormChange, formData]);\n\n // Map from annotation ID -> field metadata\n const fieldMapRef = useRef<Map<string, FieldEntry>>(new Map());\n // Reverse map from field name -> annotation IDs\n const nameToIdsRef = useRef<Map<string, string[]>>(new Map());\n\n // Effect 1: Build field metadata map when document loads\n useEffect(function buildFieldMap() {\n const doc = document;\n if (doc == null) {\n fieldMapRef.current.clear();\n nameToIdsRef.current.clear();\n setHasFormFields(false);\n return;\n }\n\n let cancelled = false;\n\n void doc.getFieldObjects().then((fieldObjects) => {\n if (cancelled || fieldObjects == null) {\n setHasFormFields(false);\n return;\n }\n\n const fieldMap = new Map<string, FieldEntry>();\n const nameToIds = new Map<string, string[]>();\n\n for (const [fieldName, objects] of Object.entries(fieldObjects)) {\n const ids: string[] = [];\n for (const obj of objects) {\n const typedObj = obj as {\n id?: string;\n type?: string;\n exportValues?: string;\n page?: number;\n };\n if (typedObj.id == null) continue;\n\n const fieldType = normalizeFieldType(typedObj.type ?? \"text\");\n fieldMap.set(typedObj.id, {\n fieldName,\n fieldType,\n exportValues: typedObj.exportValues,\n page: typedObj.page ?? 0,\n });\n ids.push(typedObj.id);\n }\n if (ids.length > 0) {\n nameToIds.set(fieldName, ids);\n }\n }\n\n fieldMapRef.current = fieldMap;\n nameToIdsRef.current = nameToIds;\n setHasFormFields(fieldMap.size > 0);\n });\n\n return () => {\n cancelled = true;\n };\n }, [document]);\n\n // Populates form fields from formData into both annotation storage and DOM elements.\n // Scoped to the viewer container to avoid conflicts with multiple viewer instances.\n const populateFields = useCallback(() => {\n const data = formDataRef.current;\n const doc = document;\n const pdfViewer = pdfViewerRef.current;\n if (data == null || doc == null || pdfViewer == null) return;\n if (fieldMapRef.current.size === 0) return;\n\n const storage = doc.annotationStorage;\n const container = getViewerContainer(pdfViewer);\n\n for (const [fieldName, value] of Object.entries(data)) {\n const ids = nameToIdsRef.current.get(fieldName);\n if (ids == null) continue;\n\n for (const id of ids) {\n const entry = fieldMapRef.current.get(id);\n if (entry == null) continue;\n\n const storageVal = toStorageValue(\n value,\n entry.fieldType,\n );\n storage.setValue(id, { value: storageVal });\n\n // Also update the DOM element directly (scoped to viewer container)\n const el = container?.querySelector(\n `[data-element-id=\"${CSS.escape(id)}\"]`,\n );\n if (el == null) continue;\n\n if (\n entry.fieldType === \"checkbox\" && el instanceof HTMLInputElement\n ) {\n el.checked = typeof storageVal === \"boolean\"\n ? storageVal\n : storageVal !== \"Off\";\n } else if (el instanceof HTMLSelectElement) {\n el.value = String(value);\n } else if (\n el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement\n ) {\n el.value = String(value);\n }\n }\n }\n }, [document, pdfViewerRef]);\n\n // Effect 2: Populate initial form data when annotation layers render\n useEffect(function populateFormData() {\n const eventBus = eventBusRef.current;\n if (eventBus == null || document == null || formDataRef.current == null) {\n return;\n }\n\n // Attempt population immediately in case the field map was built\n // after the annotation layer already rendered (race condition fix).\n populateFields();\n\n const onAnnotationLayerRendered = () => {\n populateFields();\n };\n\n eventBus.on(ANNOTATION_LAYER_RENDERED_EVENT, onAnnotationLayerRendered);\n\n return () => {\n eventBus.off(ANNOTATION_LAYER_RENDERED_EVENT, onAnnotationLayerRendered);\n };\n }, [eventBusRef, document, hasFormFields, populateFields]);\n\n // Effect 3: Listen for field changes via MutationObserver + event listeners\n useEffect(function listenForFieldChanges() {\n const pdfViewer = pdfViewerRef.current;\n if (pdfViewer == null || document == null) {\n return;\n }\n\n // Get the viewer's container element\n const container = getViewerContainer(pdfViewer);\n if (container == null) return;\n\n const listeners = new Map<Element, () => void>();\n\n function handleFieldChange(\n el: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement,\n ) {\n const id = el.getAttribute(\"data-element-id\");\n if (id == null) return;\n\n const entry = fieldMapRef.current.get(id);\n if (entry == null) return;\n\n let value: PdfFormFieldValue;\n if (entry.fieldType === \"checkbox\" && el instanceof HTMLInputElement) {\n value = el.checked;\n } else if (\n entry.fieldType === \"radiobutton\" && el instanceof HTMLInputElement\n ) {\n // For radio buttons, the value is the button's export value when selected\n value = el.checked ? (entry.exportValues ?? el.value) : \"\";\n } else {\n value = el.value;\n }\n\n onFormChangeRef.current?.(entry.fieldName, value);\n }\n\n function attachListeners(root: Node) {\n const elements = (root as Element).querySelectorAll?.(\n \".annotationLayer input, .annotationLayer select, .annotationLayer textarea\",\n );\n if (elements == null) return;\n\n for (const el of elements) {\n if (listeners.has(el)) continue;\n\n const handler = () => {\n handleFieldChange(\n el as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement,\n );\n };\n el.addEventListener(\"input\", handler);\n el.addEventListener(\"change\", handler);\n listeners.set(el, handler);\n }\n }\n\n // Attach to any elements already in the DOM\n attachListeners(container);\n\n // Watch for new form elements being added (pages render lazily)\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const node of mutation.addedNodes) {\n if (node instanceof Element) {\n attachListeners(node);\n }\n }\n }\n });\n\n observer.observe(container, { childList: true, subtree: true });\n\n return () => {\n observer.disconnect();\n for (const [el, handler] of listeners) {\n el.removeEventListener(\"input\", handler);\n el.removeEventListener(\"change\", handler);\n }\n listeners.clear();\n };\n }, [pdfViewerRef, document]);\n\n // Callback: collect all form data and invoke onFormSubmit\n const submitFormData = useCallback(() => {\n const doc = document;\n if (doc == null) return;\n\n const storage = doc.annotationStorage;\n const allValues = storage.getAll() as Record<string, unknown> | null;\n const result: Record<string, PdfFormFieldValue> = {};\n\n // Track which radio group has been resolved\n const resolvedRadios = new Set<string>();\n\n for (const [id, entry] of fieldMapRef.current) {\n const { fieldName, fieldType } = entry;\n\n // For radio buttons, only process each group once\n if (fieldType === \"radiobutton\") {\n if (resolvedRadios.has(fieldName)) continue;\n resolvedRadios.add(fieldName);\n\n // Find the selected radio in the group\n const groupIds = nameToIdsRef.current.get(fieldName) ?? [];\n let selectedValue = \"\";\n for (const radioId of groupIds) {\n const stored = allValues?.[radioId];\n const val =\n stored != null && typeof stored === \"object\" && \"value\" in stored\n ? (stored as { value: unknown }).value\n : stored;\n if (val === true || (typeof val === \"string\" && val !== \"Off\")) {\n const radioEntry = fieldMapRef.current.get(radioId);\n selectedValue = radioEntry?.exportValues ?? String(val);\n break;\n }\n }\n result[fieldName] = selectedValue;\n continue;\n }\n\n const stored = allValues?.[id];\n const rawValue =\n stored != null && typeof stored === \"object\" && \"value\" in stored\n ? (stored as { value: unknown }).value\n : stored;\n\n // Skip if we already have a value for this field name (e.g. duplicate IDs)\n if (fieldName in result) continue;\n\n result[fieldName] = toFormFieldValue(rawValue, fieldType);\n }\n\n onFormSubmitRef.current?.(result);\n }, [document]);\n\n return {\n hasFormFields,\n submitFormData,\n };\n}\n"],"mappings":"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","ignoreList":[]}