@ayasofyazilim/ui 0.0.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 (236) hide show
  1. package/__mocks__/canvas.ts +8 -0
  2. package/components.json +21 -0
  3. package/eslint.config.js +4 -0
  4. package/jest-environment.js +37 -0
  5. package/jest.config.ts +47 -0
  6. package/jest.setup.ts +69 -0
  7. package/package.json +124 -0
  8. package/postcss.config.mjs +6 -0
  9. package/src/aria/index.tsx +1 -0
  10. package/src/aria/number-field.tsx +41 -0
  11. package/src/components/.gitkeep +0 -0
  12. package/src/components/accordion.tsx +66 -0
  13. package/src/components/alert-dialog.tsx +157 -0
  14. package/src/components/alert.tsx +70 -0
  15. package/src/components/aspect-ratio.tsx +11 -0
  16. package/src/components/avatar.tsx +53 -0
  17. package/src/components/badge.tsx +67 -0
  18. package/src/components/breadcrumb.tsx +109 -0
  19. package/src/components/button-group.tsx +83 -0
  20. package/src/components/button.tsx +68 -0
  21. package/src/components/calendar.tsx +219 -0
  22. package/src/components/card.tsx +92 -0
  23. package/src/components/carousel.tsx +241 -0
  24. package/src/components/chart.tsx +363 -0
  25. package/src/components/checkbox.tsx +32 -0
  26. package/src/components/collapsible.tsx +33 -0
  27. package/src/components/command.tsx +184 -0
  28. package/src/components/context-menu.tsx +252 -0
  29. package/src/components/dialog.tsx +144 -0
  30. package/src/components/drawer.tsx +135 -0
  31. package/src/components/dropdown-menu.tsx +258 -0
  32. package/src/components/empty.tsx +100 -0
  33. package/src/components/field.tsx +248 -0
  34. package/src/components/form.tsx +169 -0
  35. package/src/components/hover-card.tsx +44 -0
  36. package/src/components/input-group.tsx +170 -0
  37. package/src/components/input-otp.tsx +77 -0
  38. package/src/components/input.tsx +21 -0
  39. package/src/components/item.tsx +193 -0
  40. package/src/components/kbd.tsx +28 -0
  41. package/src/components/label.tsx +24 -0
  42. package/src/components/menubar.tsx +276 -0
  43. package/src/components/navigation-menu.tsx +168 -0
  44. package/src/components/pagination.tsx +130 -0
  45. package/src/components/popover.tsx +88 -0
  46. package/src/components/progress.tsx +31 -0
  47. package/src/components/radio-group.tsx +45 -0
  48. package/src/components/resizable.tsx +56 -0
  49. package/src/components/scroll-area.tsx +58 -0
  50. package/src/components/select.tsx +189 -0
  51. package/src/components/separator.tsx +28 -0
  52. package/src/components/sheet.tsx +140 -0
  53. package/src/components/sidebar.tsx +862 -0
  54. package/src/components/skeleton.tsx +13 -0
  55. package/src/components/slider.tsx +63 -0
  56. package/src/components/sonner.tsx +40 -0
  57. package/src/components/spinner.tsx +16 -0
  58. package/src/components/stepper.tsx +291 -0
  59. package/src/components/switch.tsx +31 -0
  60. package/src/components/table.tsx +133 -0
  61. package/src/components/tabs.tsx +66 -0
  62. package/src/components/textarea.tsx +18 -0
  63. package/src/components/toggle-group.tsx +83 -0
  64. package/src/components/toggle.tsx +47 -0
  65. package/src/components/tooltip.tsx +66 -0
  66. package/src/custom/action-button.tsx +48 -0
  67. package/src/custom/async-select.tsx +287 -0
  68. package/src/custom/awesome-not-found.tsx +116 -0
  69. package/src/custom/charts/area-chart.tsx +147 -0
  70. package/src/custom/charts/bar-chart.tsx +233 -0
  71. package/src/custom/charts/chart-card.tsx +103 -0
  72. package/src/custom/charts/index.tsx +16 -0
  73. package/src/custom/charts/pie-chart.tsx +168 -0
  74. package/src/custom/charts/radar-chart.tsx +126 -0
  75. package/src/custom/checkbox-tree.tsx +100 -0
  76. package/src/custom/combobox.tsx +296 -0
  77. package/src/custom/confirm-dialog.tsx +102 -0
  78. package/src/custom/country-selector.tsx +204 -0
  79. package/src/custom/date-picker/calendar-rac.tsx +109 -0
  80. package/src/custom/date-picker/datefield-rac.tsx +84 -0
  81. package/src/custom/date-picker/index.tsx +273 -0
  82. package/src/custom/date-picker/types/index.ts +4 -0
  83. package/src/custom/date-picker/utils/index.ts +42 -0
  84. package/src/custom/date-picker-old.tsx +50 -0
  85. package/src/custom/date-tooltip.tsx +98 -0
  86. package/src/custom/document-scanner/consts.ts +5 -0
  87. package/src/custom/document-scanner/corner-adjustment/action-buttons.tsx +33 -0
  88. package/src/custom/document-scanner/corner-adjustment/corner-handle.tsx +43 -0
  89. package/src/custom/document-scanner/corner-adjustment/hooks/use-corner-drag.ts +85 -0
  90. package/src/custom/document-scanner/corner-adjustment/index.tsx +125 -0
  91. package/src/custom/document-scanner/corner-adjustment/types.ts +53 -0
  92. package/src/custom/document-scanner/corner-adjustment/utils/clip-path.ts +22 -0
  93. package/src/custom/document-scanner/corner-adjustment/zoom-magnifier.tsx +115 -0
  94. package/src/custom/document-scanner/hooks/use-document-capture.ts +81 -0
  95. package/src/custom/document-scanner/hooks/use-document-scanner.ts +80 -0
  96. package/src/custom/document-scanner/hooks/use-perspective-crop.ts +38 -0
  97. package/src/custom/document-scanner/index.tsx +255 -0
  98. package/src/custom/document-scanner/lib.ts +407 -0
  99. package/src/custom/document-scanner/types.ts +205 -0
  100. package/src/custom/document-scanner/utils/perspective-correction.ts +139 -0
  101. package/src/custom/document-viewer/controllers.tsx +98 -0
  102. package/src/custom/document-viewer/index.tsx +43 -0
  103. package/src/custom/document-viewer/renderers/image.tsx +37 -0
  104. package/src/custom/document-viewer/renderers/index.tsx +2 -0
  105. package/src/custom/document-viewer/renderers/pdf.tsx +105 -0
  106. package/src/custom/email-input/domains.json +159 -0
  107. package/src/custom/email-input/email.tsx +229 -0
  108. package/src/custom/email-input/index.tsx +4 -0
  109. package/src/custom/email-input/types.ts +104 -0
  110. package/src/custom/file-uploader.tsx +541 -0
  111. package/src/custom/filter-component/fields/async-select.tsx +33 -0
  112. package/src/custom/filter-component/fields/date.tsx +60 -0
  113. package/src/custom/filter-component/fields/multi-select.tsx +30 -0
  114. package/src/custom/filter-component/index.tsx +217 -0
  115. package/src/custom/image-canvas.tsx +260 -0
  116. package/src/custom/json-editor.tsx +22 -0
  117. package/src/custom/master-data-grid/components/dialogs/column-settings-dialog.tsx +100 -0
  118. package/src/custom/master-data-grid/components/dialogs/index.ts +1 -0
  119. package/src/custom/master-data-grid/components/filters/client-filter.tsx +368 -0
  120. package/src/custom/master-data-grid/components/filters/filter-input.tsx +256 -0
  121. package/src/custom/master-data-grid/components/filters/index.ts +3 -0
  122. package/src/custom/master-data-grid/components/filters/inline-column-filter.tsx +233 -0
  123. package/src/custom/master-data-grid/components/filters/multi-filter-dialog.tsx +90 -0
  124. package/src/custom/master-data-grid/components/filters/server-filter.tsx +255 -0
  125. package/src/custom/master-data-grid/components/master-data-grid.tsx +472 -0
  126. package/src/custom/master-data-grid/components/pagination/index.ts +1 -0
  127. package/src/custom/master-data-grid/components/pagination/pagination.tsx +178 -0
  128. package/src/custom/master-data-grid/components/table/cell-renderer.tsx +634 -0
  129. package/src/custom/master-data-grid/components/table/header-cell.tsx +162 -0
  130. package/src/custom/master-data-grid/components/table/index.ts +4 -0
  131. package/src/custom/master-data-grid/components/table/table-body-renderer.tsx +113 -0
  132. package/src/custom/master-data-grid/components/table/virtual-body.tsx +138 -0
  133. package/src/custom/master-data-grid/components/toolbar/index.ts +1 -0
  134. package/src/custom/master-data-grid/components/toolbar/toolbar.tsx +314 -0
  135. package/src/custom/master-data-grid/hooks/index.ts +3 -0
  136. package/src/custom/master-data-grid/hooks/use-columns.tsx +332 -0
  137. package/src/custom/master-data-grid/hooks/use-editing.ts +106 -0
  138. package/src/custom/master-data-grid/hooks/use-table-state-reducer.ts +157 -0
  139. package/src/custom/master-data-grid/hooks/use-table-state.ts +31 -0
  140. package/src/custom/master-data-grid/index.ts +16 -0
  141. package/src/custom/master-data-grid/types.ts +466 -0
  142. package/src/custom/master-data-grid/utils/column-generator.tsx +306 -0
  143. package/src/custom/master-data-grid/utils/export-utils.ts +67 -0
  144. package/src/custom/master-data-grid/utils/filter-fns.ts +290 -0
  145. package/src/custom/master-data-grid/utils/index.ts +8 -0
  146. package/src/custom/master-data-grid/utils/pinning-utils.ts +88 -0
  147. package/src/custom/master-data-grid/utils/translation-utils.ts +42 -0
  148. package/src/custom/multi-select.tsx +432 -0
  149. package/src/custom/password-input.tsx +194 -0
  150. package/src/custom/phone-input.tsx +172 -0
  151. package/src/custom/schema-form/custom/index.tsx +1 -0
  152. package/src/custom/schema-form/custom/label.tsx +53 -0
  153. package/src/custom/schema-form/fields/base-input-field.tsx +82 -0
  154. package/src/custom/schema-form/fields/field.tsx +67 -0
  155. package/src/custom/schema-form/fields/index.tsx +5 -0
  156. package/src/custom/schema-form/fields/object.tsx +12 -0
  157. package/src/custom/schema-form/fields/table-array/array-field-item.tsx +90 -0
  158. package/src/custom/schema-form/fields/table-array/array-field-template.tsx +115 -0
  159. package/src/custom/schema-form/index.tsx +259 -0
  160. package/src/custom/schema-form/templates/description.tsx +20 -0
  161. package/src/custom/schema-form/templates/index.tsx +2 -0
  162. package/src/custom/schema-form/templates/submit.tsx +32 -0
  163. package/src/custom/schema-form/types.ts +64 -0
  164. package/src/custom/schema-form/utils/index.ts +4 -0
  165. package/src/custom/schema-form/utils/schema-dependency.ts +655 -0
  166. package/src/custom/schema-form/utils/schemas.ts +289 -0
  167. package/src/custom/schema-form/utils/validation.ts +23 -0
  168. package/src/custom/schema-form/widgets/boolean.tsx +77 -0
  169. package/src/custom/schema-form/widgets/combobox.tsx +274 -0
  170. package/src/custom/schema-form/widgets/date.tsx +59 -0
  171. package/src/custom/schema-form/widgets/email.tsx +34 -0
  172. package/src/custom/schema-form/widgets/index.tsx +10 -0
  173. package/src/custom/schema-form/widgets/password.tsx +40 -0
  174. package/src/custom/schema-form/widgets/phone.tsx +40 -0
  175. package/src/custom/schema-form/widgets/select.tsx +105 -0
  176. package/src/custom/schema-form/widgets/selectable.tsx +25 -0
  177. package/src/custom/schema-form/widgets/string-array.tsx +296 -0
  178. package/src/custom/schema-form/widgets/url.tsx +56 -0
  179. package/src/custom/section-layout-v2.tsx +212 -0
  180. package/src/custom/select-tabs.tsx +109 -0
  181. package/src/custom/selectable.tsx +316 -0
  182. package/src/custom/stepper.tsx +236 -0
  183. package/src/custom/tab-layout.tsx +213 -0
  184. package/src/custom/tanstack-table/fields/index.tsx +12 -0
  185. package/src/custom/tanstack-table/fields/tanstack-table-action-dialogs.tsx +89 -0
  186. package/src/custom/tanstack-table/fields/tanstack-table-column-header.tsx +66 -0
  187. package/src/custom/tanstack-table/fields/tanstack-table-filter-date.tsx +180 -0
  188. package/src/custom/tanstack-table/fields/tanstack-table-filter-faceted.tsx +158 -0
  189. package/src/custom/tanstack-table/fields/tanstack-table-filter-text.tsx +76 -0
  190. package/src/custom/tanstack-table/fields/tanstack-table-pagination.tsx +136 -0
  191. package/src/custom/tanstack-table/fields/tanstack-table-plain-table.tsx +142 -0
  192. package/src/custom/tanstack-table/fields/tanstack-table-row-actions-confirmation.tsx +77 -0
  193. package/src/custom/tanstack-table/fields/tanstack-table-row-actions-custom-dialog.tsx +87 -0
  194. package/src/custom/tanstack-table/fields/tanstack-table-row-actions.tsx +151 -0
  195. package/src/custom/tanstack-table/fields/tanstack-table-table-actions-custom-dialog.tsx +88 -0
  196. package/src/custom/tanstack-table/fields/tanstack-table-table-actions-schemaform-dialog.tsx +47 -0
  197. package/src/custom/tanstack-table/fields/tanstack-table-toolbar.tsx +143 -0
  198. package/src/custom/tanstack-table/fields/tanstack-table-view-options.tsx +171 -0
  199. package/src/custom/tanstack-table/index.tsx +244 -0
  200. package/src/custom/tanstack-table/types/index.ts +328 -0
  201. package/src/custom/tanstack-table/utils/cell-with-actions.tsx +21 -0
  202. package/src/custom/tanstack-table/utils/column-names.ts +26 -0
  203. package/src/custom/tanstack-table/utils/columns-by-row-data.tsx +312 -0
  204. package/src/custom/tanstack-table/utils/editable-columns-by-row-data.tsx +219 -0
  205. package/src/custom/tanstack-table/utils/faceted-boolean-options.tsx +22 -0
  206. package/src/custom/tanstack-table/utils/index.tsx +10 -0
  207. package/src/custom/tanstack-table/utils/pinning-styles.ts +57 -0
  208. package/src/custom/tanstack-table/utils/table.tsx +83 -0
  209. package/src/custom/tanstack-table/utils/test-conditions.ts +17 -0
  210. package/src/custom/timeline.tsx +208 -0
  211. package/src/custom/tree.tsx +200 -0
  212. package/src/custom/tscanify/browser.ts +66 -0
  213. package/src/custom/tscanify/index.ts +51 -0
  214. package/src/custom/tscanify/tscanify-browser.ts +522 -0
  215. package/src/custom/tscanify/tscanify.ts +262 -0
  216. package/src/custom/tscanify/types.ts +22 -0
  217. package/src/custom/webcam.tsx +737 -0
  218. package/src/hooks/.gitkeep +0 -0
  219. package/src/hooks/use-callback-ref.ts +27 -0
  220. package/src/hooks/use-controllable-state.ts +67 -0
  221. package/src/hooks/use-debounce.ts +19 -0
  222. package/src/hooks/use-is-visible.ts +23 -0
  223. package/src/hooks/use-media-query.ts +21 -0
  224. package/src/hooks/use-mobile.ts +21 -0
  225. package/src/hooks/use-on-window-resize.ts +15 -0
  226. package/src/hooks/use-scroll.tsx +22 -0
  227. package/src/lib/utils.ts +61 -0
  228. package/src/lib/zod.ts +2 -0
  229. package/src/styles/core.css +57 -0
  230. package/src/styles/globals.css +130 -0
  231. package/src/test/email-input.test.tsx +217 -0
  232. package/src/test/password-input.test.tsx +92 -0
  233. package/src/test/select-tabs.test.tsx +302 -0
  234. package/src/test/selectable.test.tsx +1093 -0
  235. package/tsconfig.json +13 -0
  236. package/tsconfig.lint.json +8 -0
@@ -0,0 +1,139 @@
1
+ import cv from "opencv-ts";
2
+ import type { Mat } from "opencv-ts";
3
+ import { DocumentCorners } from "../types";
4
+
5
+ export interface PerspectiveCorrectionOptions {
6
+ imageQuality: number;
7
+ }
8
+
9
+ export function perspectiveCorrection(
10
+ imageBase64: string,
11
+ corners: DocumentCorners,
12
+ videoDimensions: { width: number; height: number },
13
+ options: PerspectiveCorrectionOptions
14
+ ): Promise<string> {
15
+ return new Promise<string>((resolve, reject) => {
16
+ try {
17
+ const img = new Image();
18
+ img.onload = () => {
19
+ try {
20
+ // Create canvas and get image data
21
+ const canvas = document.createElement("canvas");
22
+ canvas.width = img.width;
23
+ canvas.height = img.height;
24
+ const ctx = canvas.getContext("2d");
25
+ if (!ctx) {
26
+ reject(new Error("Failed to get canvas context"));
27
+ return;
28
+ }
29
+ ctx.drawImage(img, 0, 0);
30
+
31
+ // Create OpenCV matrices
32
+ const src = cv.imread(canvas);
33
+
34
+ // Scale corners from video dimensions to actual image dimensions
35
+ const scaleX = img.width / videoDimensions.width;
36
+ const scaleY = img.height / videoDimensions.height;
37
+
38
+ // Source points (detected corners scaled to image size)
39
+ const srcPoints = cv.matFromArray(4, 1, cv.CV_32FC2, [
40
+ corners.topLeftCorner.x * scaleX,
41
+ corners.topLeftCorner.y * scaleY,
42
+ corners.topRightCorner.x * scaleX,
43
+ corners.topRightCorner.y * scaleY,
44
+ corners.bottomRightCorner.x * scaleX,
45
+ corners.bottomRightCorner.y * scaleY,
46
+ corners.bottomLeftCorner.x * scaleX,
47
+ corners.bottomLeftCorner.y * scaleY,
48
+ ]);
49
+
50
+ // Calculate output dimensions
51
+ const { outputWidth, outputHeight } = calculateOutputDimensions(
52
+ corners,
53
+ scaleX,
54
+ scaleY
55
+ );
56
+
57
+ // Destination points (rectangle)
58
+ const dstPoints = cv.matFromArray(4, 1, cv.CV_32FC2, [
59
+ 0,
60
+ 0,
61
+ outputWidth,
62
+ 0,
63
+ outputWidth,
64
+ outputHeight,
65
+ 0,
66
+ outputHeight,
67
+ ]);
68
+
69
+ // Get perspective transform matrix
70
+ const transformMatrix = cv.getPerspectiveTransform(
71
+ srcPoints,
72
+ dstPoints
73
+ );
74
+
75
+ // Apply perspective transformation
76
+ const dst = new cv.Mat();
77
+ cv.warpPerspective(
78
+ src,
79
+ dst,
80
+ transformMatrix,
81
+ new cv.Size(outputWidth, outputHeight)
82
+ );
83
+
84
+ // Convert back to canvas and get base64
85
+ const outputCanvas = document.createElement("canvas");
86
+ cv.imshow(outputCanvas, dst);
87
+ const croppedBase64 = outputCanvas.toDataURL(
88
+ "image/jpeg",
89
+ options.imageQuality
90
+ );
91
+
92
+ // Cleanup OpenCV matrices
93
+ cleanupMatrices([src, dst, srcPoints, dstPoints, transformMatrix]);
94
+
95
+ resolve(croppedBase64);
96
+ } catch (error) {
97
+ reject(error);
98
+ }
99
+ };
100
+ img.onerror = () => reject(new Error("Failed to load image"));
101
+ img.src = imageBase64;
102
+ } catch (error) {
103
+ reject(error);
104
+ }
105
+ });
106
+ }
107
+
108
+ function calculateOutputDimensions(
109
+ corners: DocumentCorners,
110
+ scaleX: number,
111
+ scaleY: number
112
+ ): { outputWidth: number; outputHeight: number } {
113
+ const distance = (
114
+ p1: { x: number; y: number },
115
+ p2: { x: number; y: number }
116
+ ) => Math.sqrt(((p2.x - p1.x) * scaleX) ** 2 + ((p2.y - p1.y) * scaleY) ** 2);
117
+
118
+ const topWidth = distance(corners.topLeftCorner, corners.topRightCorner);
119
+ const bottomWidth = distance(
120
+ corners.bottomLeftCorner,
121
+ corners.bottomRightCorner
122
+ );
123
+ const leftHeight = distance(corners.topLeftCorner, corners.bottomLeftCorner);
124
+ const rightHeight = distance(
125
+ corners.topRightCorner,
126
+ corners.bottomRightCorner
127
+ );
128
+
129
+ return {
130
+ outputWidth: Math.max(topWidth, bottomWidth),
131
+ outputHeight: Math.max(leftHeight, rightHeight),
132
+ };
133
+ }
134
+
135
+ function cleanupMatrices(matrices: Mat[]): void {
136
+ matrices.forEach((matrix) => {
137
+ matrix.delete();
138
+ });
139
+ }
@@ -0,0 +1,98 @@
1
+ import {
2
+ DownloadIcon,
3
+ EyeIcon,
4
+ EyeOffIcon,
5
+ SearchIcon,
6
+ ZoomIn,
7
+ ZoomOut,
8
+ } from "lucide-react";
9
+ import Link from "next/link";
10
+ import { useEffect, useState } from "react";
11
+ import { Button } from "@repo/ayasofyazilim-ui/components/button";
12
+ import {
13
+ Popover,
14
+ PopoverContent,
15
+ PopoverTrigger,
16
+ } from "@repo/ayasofyazilim-ui/components/popover";
17
+ import { Input } from "@repo/ayasofyazilim-ui/components/input";
18
+
19
+ export function Controllers({
20
+ documentUri,
21
+ zoom,
22
+ setZoom,
23
+ showThumbnail,
24
+ setShowThumbnail,
25
+ searchValue,
26
+ setSearchValue,
27
+ }: {
28
+ documentUri: string;
29
+ zoom: number;
30
+ setZoom: (zoom: number) => void;
31
+ showThumbnail?: boolean;
32
+ setShowThumbnail?: (show: boolean) => void;
33
+ searchValue?: string;
34
+ setSearchValue?: (value: string) => void;
35
+ }) {
36
+ const [open, setOpen] = useState(false);
37
+ useEffect(() => {
38
+ if (!open) {
39
+ if (setSearchValue) {
40
+ setSearchValue("");
41
+ }
42
+ }
43
+ }, [open]);
44
+
45
+ return (
46
+ <div className="absolute top-4 right-6 flex gap-2 z-10 flex-col">
47
+ {setShowThumbnail && (
48
+ <Button
49
+ variant="outline"
50
+ size="icon"
51
+ onClick={() => setShowThumbnail(!showThumbnail)}
52
+ >
53
+ {showThumbnail ? (
54
+ <EyeIcon className="size-4" />
55
+ ) : (
56
+ <EyeOffIcon className="size-4" />
57
+ )}
58
+ </Button>
59
+ )}
60
+ <Button variant="outline" size="icon" onClick={() => setZoom(zoom - 0.1)}>
61
+ <ZoomOut className="size-4" />
62
+ </Button>
63
+ <Button variant="outline" size="icon" onClick={() => setZoom(zoom + 0.1)}>
64
+ <ZoomIn className="size-4" />
65
+ </Button>
66
+ <Button asChild variant="outline" size="icon">
67
+ <Link href={documentUri} download target="_blank">
68
+ <DownloadIcon className="size-4" />
69
+ </Link>
70
+ </Button>
71
+ {setSearchValue && (
72
+ <Popover open={open} onOpenChange={setOpen}>
73
+ <PopoverTrigger asChild>
74
+ <Button
75
+ variant="outline"
76
+ size="icon"
77
+ onClick={() => setOpen(!open)}
78
+ >
79
+ <SearchIcon className="size-4" />
80
+ </Button>
81
+ </PopoverTrigger>
82
+ <PopoverContent className="w-80 p-0" side="left">
83
+ <div className="grid gap-4">
84
+ <Input
85
+ id="search"
86
+ defaultValue={searchValue}
87
+ onChange={(e) => {
88
+ setSearchValue(e.target.value);
89
+ }}
90
+ className="col-span-2 h-8"
91
+ />
92
+ </div>
93
+ </PopoverContent>
94
+ </Popover>
95
+ )}
96
+ </div>
97
+ );
98
+ }
@@ -0,0 +1,43 @@
1
+ "use client";
2
+
3
+ import { cn } from "@repo/ayasofyazilim-ui/lib/utils";
4
+ import DocViewer, { DocRenderer, DocViewerRenderers } from "react-doc-viewer";
5
+ import CustomImageRenderer from "./renderers/image";
6
+ import CustomPDFRenderer from "./renderers/pdf";
7
+
8
+ export * from "react-doc-viewer";
9
+
10
+ export type DocumentType = {
11
+ uri: string;
12
+ fileType?: string;
13
+ fileName?: string;
14
+ fileData?: string | ArrayBuffer;
15
+ };
16
+ export default function DocumentViewer({
17
+ document,
18
+ className,
19
+ renderers = [],
20
+ }: {
21
+ document: DocumentType;
22
+ className?: string;
23
+ renderers?: DocRenderer[];
24
+ }) {
25
+ return (
26
+ <DocViewer
27
+ config={{
28
+ header: {
29
+ disableHeader: true,
30
+ disableFileName: true,
31
+ },
32
+ }}
33
+ className={cn("h-full rounded-md border relative", className)}
34
+ pluginRenderers={[
35
+ ...DocViewerRenderers,
36
+ CustomPDFRenderer,
37
+ CustomImageRenderer,
38
+ ...renderers,
39
+ ]}
40
+ documents={[document]}
41
+ />
42
+ );
43
+ }
@@ -0,0 +1,37 @@
1
+ import { useState } from "react";
2
+ import { DocRendererProps } from "react-doc-viewer";
3
+ import { Controllers } from "../controllers";
4
+ import ImageCanvas from "../../image-canvas";
5
+
6
+ const CustomImageRenderer = (props: DocRendererProps) => {
7
+ const { mainState } = props;
8
+ const { currentDocument } = mainState;
9
+ if (!currentDocument) return null;
10
+ const [zoom, setZoom] = useState(1);
11
+ return (
12
+ <div className="flex w-full items-center justify-center p-4">
13
+ <Controllers
14
+ documentUri={currentDocument.uri}
15
+ zoom={zoom}
16
+ setZoom={setZoom}
17
+ />
18
+ <div className="relative size-full flex items-center justify-center">
19
+ <ImageCanvas
20
+ classNames={{
21
+ canvas: "border rounded-md",
22
+ }}
23
+ imageUrl={currentDocument.uri}
24
+ zoom={zoom}
25
+ minZoom={0.5}
26
+ maxZoom={2}
27
+ onZoomChange={setZoom}
28
+ />
29
+ </div>
30
+ </div>
31
+ );
32
+ };
33
+
34
+ CustomImageRenderer.fileTypes = ["image/jpeg", "image/png", "image/gif"];
35
+ CustomImageRenderer.weight = 1;
36
+
37
+ export default CustomImageRenderer;
@@ -0,0 +1,2 @@
1
+ export * from "./pdf";
2
+ export * from "./image";
@@ -0,0 +1,105 @@
1
+ import { useMemo, useState } from "react";
2
+ import { DocRenderer, DocRendererProps } from "react-doc-viewer";
3
+ import { Document, Page, pdfjs, Thumbnail } from "react-pdf";
4
+ import { cn } from "@repo/ayasofyazilim-ui/lib/utils";
5
+ import "react-pdf/dist/Page/AnnotationLayer.css";
6
+ import "react-pdf/dist/Page/TextLayer.css";
7
+ import { Controllers } from "../controllers";
8
+
9
+ pdfjs.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;
10
+
11
+ type CustomDocRendererProps = {} & DocRendererProps;
12
+
13
+ const CustomPDFRenderer = (props: CustomDocRendererProps) => {
14
+ const { mainState } = props;
15
+ const { currentDocument } = mainState;
16
+ const [zoom, setZoom] = useState(1);
17
+ const [showThumbnail, setShowThumbnail] = useState(false);
18
+ const [pageCount, setPageCount] = useState(0);
19
+ const [activePage, setActivePage] = useState(1);
20
+ const [searchValue, setSearchValue] = useState<string>();
21
+
22
+ if (!currentDocument) return null;
23
+ return (
24
+ <Document
25
+ className={cn("p-4 w-full flex")}
26
+ file={currentDocument.uri}
27
+ renderMode="canvas"
28
+ onLoadSuccess={({ numPages }) => {
29
+ setPageCount(numPages);
30
+ }}
31
+ >
32
+ <Controllers
33
+ documentUri={currentDocument.uri}
34
+ zoom={zoom}
35
+ setZoom={setZoom}
36
+ showThumbnail={showThumbnail}
37
+ setShowThumbnail={setShowThumbnail}
38
+ searchValue={searchValue}
39
+ setSearchValue={setSearchValue}
40
+ />
41
+
42
+ <div className="flex gap-2 w-full justify-center">
43
+ {showThumbnail && (
44
+ <div className="flex flex-col gap-2 left-4 absolute top-4 z-10 w-full max-w-[110px]">
45
+ {Array.from(new Array(pageCount), (el, index) => (
46
+ <Thumbnail
47
+ key={"page_" + index}
48
+ onClick={() => {
49
+ setActivePage(index + 1);
50
+ }}
51
+ className={cn(
52
+ "rounded-md border bg-white p-1 flex justify-center",
53
+ activePage === index + 1 && "border-primary"
54
+ )}
55
+ pageNumber={index + 1}
56
+ width={100}
57
+ height={100}
58
+ />
59
+ ))}
60
+ </div>
61
+ )}
62
+ <div className={cn("flex flex-col", showThumbnail && "")}>
63
+ {Array.from(new Array(pageCount), (el, index) => (
64
+ <Page
65
+ customTextRenderer={({ str }) =>
66
+ searchValue
67
+ ? str.replace(
68
+ new RegExp(searchValue, "gi"),
69
+ (value) => `<mark>${value}</mark>`
70
+ )
71
+ : str
72
+ }
73
+ className="border shadow-sm max-w-max overflow-hidden rounded-md mb-2"
74
+ key={`page_${index + 1}`}
75
+ pageNumber={index + 1}
76
+ scale={zoom}
77
+ />
78
+ ))}
79
+ </div>
80
+ </div>
81
+ </Document>
82
+ );
83
+ };
84
+
85
+ CustomPDFRenderer.fileTypes = ["pdf", "application/pdf"];
86
+ CustomPDFRenderer.weight = 1;
87
+
88
+ export default CustomPDFRenderer;
89
+
90
+ export const ExtendCustomPDFRenderer = ({
91
+ searchValue,
92
+ }: {
93
+ searchValue?: string;
94
+ }): DocRenderer => {
95
+ const Renderer = useMemo(() => {
96
+ function RendererComponent(props: DocRendererProps) {
97
+ return <CustomPDFRenderer {...props} />;
98
+ }
99
+ RendererComponent.fileTypes = ["pdf", "application/pdf"];
100
+ RendererComponent.weight = 1;
101
+ return RendererComponent;
102
+ }, [searchValue]);
103
+
104
+ return Renderer;
105
+ };
@@ -0,0 +1,159 @@
1
+ [
2
+ "gmail.com",
3
+ "outlook.com",
4
+ "hotmail.com",
5
+ "icloud.com",
6
+ "yahoo.com",
7
+ "aol.com",
8
+ "att.net",
9
+ "comcast.net",
10
+ "facebook.com",
11
+ "gmx.com",
12
+ "googlemail.com",
13
+ "google.com",
14
+ "hotmail.co.uk",
15
+ "mac.com",
16
+ "me.com",
17
+ "mail.com",
18
+ "msn.com",
19
+ "live.com",
20
+ "sbcglobal.net",
21
+ "verizon.net",
22
+ "yahoo.co.uk",
23
+ "email.com",
24
+ "fastmail.fm",
25
+ "games.com",
26
+ "gmx.net",
27
+ "hush.com",
28
+ "hushmail.com",
29
+ "iname.com",
30
+ "inbox.com",
31
+ "lavabit.com",
32
+ "love.com",
33
+ "pobox.com",
34
+ "protonmail.ch",
35
+ "protonmail.com",
36
+ "tutanota.de",
37
+ "tutanota.com",
38
+ "tutamail.com",
39
+ "tuta.io",
40
+ "keemail.me",
41
+ "rocketmail.com",
42
+ "safe-mail.net",
43
+ "wow.com",
44
+ "ygm.com",
45
+ "ymail.com",
46
+ "zoho.com",
47
+ "bellsouth.net",
48
+ "charter.net",
49
+ "cox.net",
50
+ "earthlink.net",
51
+ "juno.com",
52
+ "btinternet.com",
53
+ "virginmedia.com",
54
+ "blueyonder.co.uk",
55
+ "live.co.uk",
56
+ "ntlworld.com",
57
+ "orange.net",
58
+ "sky.com",
59
+ "talktalk.co.uk",
60
+ "tiscali.co.uk",
61
+ "virgin.net",
62
+ "bt.com",
63
+ "sina.com",
64
+ "sina.cn",
65
+ "qq.com",
66
+ "naver.com",
67
+ "hanmail.net",
68
+ "daum.net",
69
+ "nate.com",
70
+ "yahoo.co.jp",
71
+ "yahoo.co.kr",
72
+ "yahoo.co.id",
73
+ "yahoo.co.in",
74
+ "yahoo.com.sg",
75
+ "yahoo.com.ph",
76
+ "163.com",
77
+ "yeah.net",
78
+ "126.com",
79
+ "21cn.com",
80
+ "aliyun.com",
81
+ "foxmail.com",
82
+ "hotmail.fr",
83
+ "live.fr",
84
+ "laposte.net",
85
+ "yahoo.fr",
86
+ "wanadoo.fr",
87
+ "orange.fr",
88
+ "gmx.fr",
89
+ "sfr.fr",
90
+ "neuf.fr",
91
+ "free.fr",
92
+ "gmx.de",
93
+ "hotmail.de",
94
+ "live.de",
95
+ "online.de",
96
+ "t-online.de",
97
+ "web.de",
98
+ "yahoo.de",
99
+ "libero.it",
100
+ "virgilio.it",
101
+ "hotmail.it",
102
+ "aol.it",
103
+ "tiscali.it",
104
+ "alice.it",
105
+ "live.it",
106
+ "yahoo.it",
107
+ "email.it",
108
+ "tin.it",
109
+ "poste.it",
110
+ "teletu.it",
111
+ "bk.ru",
112
+ "inbox.ru",
113
+ "list.ru",
114
+ "mail.ru",
115
+ "rambler.ru",
116
+ "yandex.by",
117
+ "yandex.com",
118
+ "yandex.kz",
119
+ "yandex.ru",
120
+ "yandex.ua",
121
+ "ya.ru",
122
+ "hotmail.be",
123
+ "live.be",
124
+ "skynet.be",
125
+ "voo.be",
126
+ "tvcablenet.be",
127
+ "telenet.be",
128
+ "hotmail.com.ar",
129
+ "live.com.ar",
130
+ "yahoo.com.ar",
131
+ "fibertel.com.ar",
132
+ "speedy.com.ar",
133
+ "arnet.com.ar",
134
+ "yahoo.com.mx",
135
+ "live.com.mx",
136
+ "hotmail.es",
137
+ "hotmail.com.mx",
138
+ "prodigy.net.mx",
139
+ "yahoo.ca",
140
+ "hotmail.ca",
141
+ "bell.net",
142
+ "shaw.ca",
143
+ "sympatico.ca",
144
+ "rogers.com",
145
+ "yahoo.com.br",
146
+ "hotmail.com.br",
147
+ "outlook.com.br",
148
+ "uol.com.br",
149
+ "bol.com.br",
150
+ "terra.com.br",
151
+ "ig.com.br",
152
+ "r7.com",
153
+ "zipmail.com.br",
154
+ "globo.com",
155
+ "globomail.com",
156
+ "oi.com.br",
157
+ "unirefund.com",
158
+ "clomerce.com"
159
+ ]