@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,77 @@
1
+ "use client";
2
+
3
+ import { Loader } from "lucide-react";
4
+ import * as React from "react";
5
+
6
+ import { Button } from "@repo/ayasofyazilim-ui/components/button";
7
+ import {
8
+ Dialog,
9
+ DialogClose,
10
+ DialogContent,
11
+ DialogDescription,
12
+ DialogFooter,
13
+ DialogHeader,
14
+ DialogTitle,
15
+ } from "@repo/ayasofyazilim-ui/components/dialog";
16
+ import { TanstackTableRowActionsConfirmationDialog } from "../types";
17
+
18
+ type TanstackTableConfirmationDialogProps<TData> = {
19
+ row: TData;
20
+ setDialogOpen: () => void;
21
+ } & TanstackTableRowActionsConfirmationDialog<TData>;
22
+ export function TanstackTableConfirmationDialog<TData>({
23
+ row,
24
+ title,
25
+ confirmationText,
26
+ onCancel,
27
+ onConfirm,
28
+ cancelText,
29
+ description,
30
+ setDialogOpen,
31
+ }: TanstackTableConfirmationDialogProps<TData>) {
32
+ const dialogTitle = typeof title === "function" ? title(row) : title;
33
+
34
+ const [isDeletePending, startDeleteTransition] = React.useTransition();
35
+
36
+ const handleOnConfirmClick = () => {
37
+ startDeleteTransition(() => {
38
+ onConfirm(row);
39
+ setDialogOpen();
40
+ });
41
+ };
42
+ const handleOnCancelClick = () => {
43
+ startDeleteTransition(() => {
44
+ onCancel?.(row);
45
+ setDialogOpen();
46
+ });
47
+ };
48
+
49
+ return (
50
+ <Dialog open onOpenChange={setDialogOpen}>
51
+ <DialogContent>
52
+ <DialogHeader>
53
+ <DialogTitle>{dialogTitle}</DialogTitle>
54
+ <DialogDescription>{description}</DialogDescription>
55
+ </DialogHeader>
56
+ <DialogFooter className="gap-2 sm:space-x-0">
57
+ <DialogClose asChild>
58
+ <Button variant="outline" onClick={handleOnCancelClick}>
59
+ {cancelText}
60
+ </Button>
61
+ </DialogClose>
62
+ <Button
63
+ aria-label={confirmationText}
64
+ variant="destructive"
65
+ onClick={handleOnConfirmClick}
66
+ disabled={isDeletePending}
67
+ >
68
+ {isDeletePending && (
69
+ <Loader className="mr-2 size-4 animate-spin" aria-hidden="true" />
70
+ )}
71
+ {confirmationText}
72
+ </Button>
73
+ </DialogFooter>
74
+ </DialogContent>
75
+ </Dialog>
76
+ );
77
+ }
@@ -0,0 +1,87 @@
1
+ "use client";
2
+
3
+ import { Loader } from "lucide-react";
4
+ import * as React from "react";
5
+
6
+ import { Button } from "@repo/ayasofyazilim-ui/components/button";
7
+ import {
8
+ Dialog,
9
+ DialogClose,
10
+ DialogContent,
11
+ DialogFooter,
12
+ DialogHeader,
13
+ DialogTitle,
14
+ } from "@repo/ayasofyazilim-ui/components/dialog";
15
+ import { TanstackTableRowActionsCustomDialog } from "../types";
16
+
17
+ type TanstackTableCustomDialogProps<TData> = {
18
+ row: TData;
19
+ setDialogOpen: () => void;
20
+ } & TanstackTableRowActionsCustomDialog<TData>;
21
+ export function TanstackTableCustomDialog<TData>({
22
+ row,
23
+ title,
24
+ confirmationText,
25
+ onCancel,
26
+ onConfirm,
27
+ cancelText,
28
+ content,
29
+ setDialogOpen,
30
+ }: TanstackTableCustomDialogProps<TData>) {
31
+ const [isDeletePending, startDeleteTransition] = React.useTransition();
32
+
33
+ const dialogTitle = typeof title === "function" ? title(row) : title;
34
+ const jsxContent =
35
+ typeof content === "function" ? content(row, setDialogOpen) : content;
36
+
37
+ const handleOnConfirmClick = () => {
38
+ startDeleteTransition(() => {
39
+ onConfirm?.(row);
40
+ setDialogOpen();
41
+ });
42
+ };
43
+ const handleOnCancelClick = () => {
44
+ startDeleteTransition(() => {
45
+ onCancel?.(row);
46
+ setDialogOpen();
47
+ });
48
+ };
49
+
50
+ return (
51
+ <Dialog open onOpenChange={setDialogOpen}>
52
+ <DialogContent>
53
+ <DialogHeader>
54
+ <DialogTitle>{dialogTitle}</DialogTitle>
55
+ </DialogHeader>
56
+ {jsxContent}
57
+ {(cancelText || confirmationText) && (
58
+ <DialogFooter className="gap-2 sm:space-x-0">
59
+ {cancelText && (
60
+ <DialogClose asChild>
61
+ <Button variant="outline" onClick={handleOnCancelClick}>
62
+ {cancelText}
63
+ </Button>
64
+ </DialogClose>
65
+ )}
66
+ {confirmationText && (
67
+ <Button
68
+ aria-label={confirmationText}
69
+ variant="destructive"
70
+ onClick={handleOnConfirmClick}
71
+ disabled={isDeletePending}
72
+ >
73
+ {isDeletePending && (
74
+ <Loader
75
+ className="mr-2 size-4 animate-spin"
76
+ aria-hidden="true"
77
+ />
78
+ )}
79
+ {confirmationText}
80
+ </Button>
81
+ )}
82
+ </DialogFooter>
83
+ )}
84
+ </DialogContent>
85
+ </Dialog>
86
+ );
87
+ }
@@ -0,0 +1,151 @@
1
+ "use client";
2
+
3
+ import { ArrowDown, ArrowUp, Copy, Trash2 } from "lucide-react";
4
+ import { Row, Table } from "@tanstack/react-table";
5
+ import { Button } from "@repo/ayasofyazilim-ui/components/button";
6
+ import {
7
+ DropdownMenu,
8
+ DropdownMenuContent,
9
+ DropdownMenuItem,
10
+ DropdownMenuTrigger,
11
+ } from "@repo/ayasofyazilim-ui/components/dropdown-menu";
12
+ import { cn } from "@repo/ayasofyazilim-ui/lib/utils";
13
+ import { TanstackTableRowActionsType } from "../types";
14
+
15
+ interface TanstackTableRowActionsProps<TData> {
16
+ actions: TanstackTableRowActionsType<TData>[];
17
+ row: Row<TData>;
18
+ setRowAction: (
19
+ actions: TanstackTableRowActionsType<TData> & { row: TData }
20
+ ) => void;
21
+ table: Table<TData>;
22
+ }
23
+
24
+ export const TanstackTableRowActions = <TData,>({
25
+ row,
26
+ setRowAction,
27
+ actions,
28
+ table,
29
+ }: TanstackTableRowActionsProps<TData>) => {
30
+ const availableActions = actions.filter(
31
+ (i) => !i.condition || (i.condition && i.condition?.(row.original))
32
+ );
33
+ if (availableActions.length === 0) return null;
34
+
35
+ if (availableActions.length === 1) {
36
+ return (
37
+ <ActionButton
38
+ action={availableActions[0] as TanstackTableRowActionsType<TData>}
39
+ className="h-9 justify-center rounded-none"
40
+ setRowAction={setRowAction}
41
+ table={table}
42
+ row={row}
43
+ />
44
+ );
45
+ }
46
+ return (
47
+ <DropdownMenu>
48
+ <DropdownMenuTrigger className="w-full justify-start" asChild>
49
+ <Button
50
+ variant="ghost"
51
+ type="button"
52
+ className="flex bg-background rounded-none"
53
+ >
54
+ Actions
55
+ <span className="sr-only">Open Menu</span>
56
+ </Button>
57
+ </DropdownMenuTrigger>
58
+ <DropdownMenuContent align="end">
59
+ {availableActions.map((action) => {
60
+ if (action.condition && !action.condition?.(row.original))
61
+ return null;
62
+ if (
63
+ (action.type === "move-row-down" &&
64
+ row.index === table.getRowCount() - 1) ||
65
+ (action.type === "move-row-up" && row.index === 0)
66
+ )
67
+ return null;
68
+ return (
69
+ <DropdownMenuItem key={action.cta}>
70
+ <ActionButton
71
+ action={action}
72
+ table={table}
73
+ row={row}
74
+ setRowAction={setRowAction}
75
+ />
76
+ </DropdownMenuItem>
77
+ );
78
+ })}
79
+ </DropdownMenuContent>
80
+ </DropdownMenu>
81
+ );
82
+ };
83
+
84
+ function ActionButton<TData>({
85
+ row,
86
+ setRowAction,
87
+ table,
88
+ action,
89
+ className,
90
+ }: {
91
+ action: TanstackTableRowActionsType<TData>;
92
+ className?: string;
93
+ row: Row<TData>;
94
+ setRowAction: (
95
+ actions: TanstackTableRowActionsType<TData> & { row: TData }
96
+ ) => void;
97
+ table: Table<TData>;
98
+ }) {
99
+ function handleOnActionClick(action: TanstackTableRowActionsType<TData>) {
100
+ if (action.type === "simple") {
101
+ action.onClick(row.original);
102
+ return;
103
+ }
104
+ if (action.type === "delete-row") {
105
+ table.options.meta?.removeRow(row.index, "", null);
106
+ return;
107
+ }
108
+ if (action.type === "duplicate-row") {
109
+ table.options.meta?.duplicateRow(row.index + 1, row.original);
110
+ return;
111
+ }
112
+ if (action.type === "move-row-up") {
113
+ table.options.meta?.orderRow(row.index, row.index - 1);
114
+ return;
115
+ }
116
+ if (action.type === "move-row-down") {
117
+ table.options.meta?.orderRow(row.index, row.index + 1);
118
+ return;
119
+ }
120
+ setRowAction({ ...action, row: row.original });
121
+ }
122
+ if (action.type === "move-row-down" && row.index === table.getRowCount() - 1)
123
+ return null;
124
+ if (action.type === "move-row-up" && row.index === 0) return null;
125
+ return (
126
+ <Button
127
+ variant="ghost"
128
+ size="sm"
129
+ type="button"
130
+ className={cn("justify-start w-full", className)}
131
+ onClick={() => handleOnActionClick(action)}
132
+ >
133
+ {action.icon && <action.icon className="w-4 h-4" />}
134
+ {!action.icon && action.type === "move-row-down" && (
135
+ <ArrowDown className="w-4 h-4" />
136
+ )}
137
+ {!action.icon && action.type === "move-row-up" && (
138
+ <ArrowUp className="w-4 h-4" />
139
+ )}
140
+ {!action.icon && action.type === "duplicate-row" && (
141
+ <Copy className="w-4 h-4" />
142
+ )}
143
+ {!action.icon && action.type === "delete-row" && (
144
+ <Trash2 className="w-4 h-4" />
145
+ )}
146
+ <span className="md:ml-2 in-data-[slot=dropdown-menu-item]:block hidden md:block">
147
+ {action.cta}
148
+ </span>
149
+ </Button>
150
+ );
151
+ }
@@ -0,0 +1,88 @@
1
+ "use client";
2
+
3
+ import { Loader } from "lucide-react";
4
+ import * as React from "react";
5
+
6
+ import { Button } from "@repo/ayasofyazilim-ui/components/button";
7
+ import {
8
+ Dialog,
9
+ DialogClose,
10
+ DialogContent,
11
+ DialogFooter,
12
+ DialogHeader,
13
+ DialogTitle,
14
+ } from "@repo/ayasofyazilim-ui/components/dialog";
15
+ import { TanstackTableActionsCustomDialog } from "../types";
16
+ import { cn } from "@repo/ayasofyazilim-ui/lib/utils";
17
+
18
+ type TanstackTableCustomDialogProps = {
19
+ setDialogOpen: () => void;
20
+ } & TanstackTableActionsCustomDialog;
21
+ export function TanstackTableTableCustomDialog({
22
+ title,
23
+ confirmationText,
24
+ onCancel,
25
+ onConfirm,
26
+ cancelText,
27
+ content,
28
+ setDialogOpen,
29
+ dialogClassNames,
30
+ }: TanstackTableCustomDialogProps) {
31
+ const [isDeletePending, startDeleteTransition] = React.useTransition();
32
+
33
+ const jsxContent =
34
+ typeof content === "function" ? content(setDialogOpen) : content;
35
+
36
+ const handleOnConfirmClick = () => {
37
+ startDeleteTransition(() => {
38
+ onConfirm?.();
39
+ setDialogOpen();
40
+ });
41
+ };
42
+ const handleOnCancelClick = () => {
43
+ startDeleteTransition(() => {
44
+ onCancel?.();
45
+ setDialogOpen();
46
+ });
47
+ };
48
+
49
+ return (
50
+ <Dialog open onOpenChange={setDialogOpen}>
51
+ <DialogContent className={dialogClassNames?.content}>
52
+ <DialogHeader className={dialogClassNames?.header}>
53
+ <DialogTitle className={dialogClassNames?.title}>{title}</DialogTitle>
54
+ </DialogHeader>
55
+ {jsxContent}
56
+ {(confirmationText || cancelText) && (
57
+ <DialogFooter
58
+ className={cn("gap-2 sm:space-x-0", dialogClassNames?.footer)}
59
+ >
60
+ {cancelText && (
61
+ <DialogClose asChild>
62
+ <Button variant="outline" onClick={handleOnCancelClick}>
63
+ {cancelText}
64
+ </Button>
65
+ </DialogClose>
66
+ )}
67
+ {confirmationText && (
68
+ <Button
69
+ aria-label={confirmationText}
70
+ variant="destructive"
71
+ onClick={handleOnConfirmClick}
72
+ disabled={isDeletePending}
73
+ >
74
+ {isDeletePending && (
75
+ <Loader
76
+ className="mr-2 size-4 animate-spin"
77
+ aria-hidden="true"
78
+ />
79
+ )}
80
+ {confirmationText}
81
+ </Button>
82
+ )}
83
+ </DialogFooter>
84
+ )}
85
+ </DialogContent>
86
+ </Dialog>
87
+ );
88
+ }
@@ -0,0 +1,47 @@
1
+ "use client";
2
+
3
+ import {
4
+ Dialog,
5
+ DialogContent,
6
+ DialogHeader,
7
+ DialogTitle,
8
+ } from "@repo/ayasofyazilim-ui/components/dialog";
9
+ import { SchemaForm } from "@repo/ayasofyazilim-ui/custom/schema-form";
10
+ import { TanstackTableActionsSchemaFormDialog } from "../types";
11
+ import { useCallback, useState } from "react";
12
+
13
+ type TanstackTableSchemaFormDialogProps<TData> = {
14
+ setDialogOpen: () => void;
15
+ } & TanstackTableActionsSchemaFormDialog<TData>;
16
+ export function TanstackTableTableSchemaFormDialog<TData>(
17
+ props: TanstackTableSchemaFormDialogProps<TData>
18
+ ) {
19
+ const { title, setDialogOpen, onSubmit } = props;
20
+ const [formData, setFormData] = useState<TData>(props.formData as TData);
21
+ const handleFormChange = useCallback(
22
+ ({ formData: editedFormData }: { formData?: TData }) => {
23
+ if (editedFormData) {
24
+ setFormData(editedFormData);
25
+ }
26
+ },
27
+ []
28
+ );
29
+ return (
30
+ <Dialog open onOpenChange={setDialogOpen}>
31
+ <DialogContent>
32
+ <DialogHeader>
33
+ <DialogTitle>{title}</DialogTitle>
34
+ </DialogHeader>
35
+ <SchemaForm<TData>
36
+ {...props}
37
+ formData={formData}
38
+ onChange={handleFormChange}
39
+ onSubmit={({ formData: editedFormData }) => {
40
+ onSubmit(editedFormData);
41
+ setDialogOpen();
42
+ }}
43
+ />
44
+ </DialogContent>
45
+ </Dialog>
46
+ );
47
+ }
@@ -0,0 +1,143 @@
1
+ "use client";
2
+
3
+ import { Table } from "@tanstack/react-table";
4
+ import { usePathname, useRouter, useSearchParams } from "next/navigation";
5
+ import {
6
+ TanstackTableFiltersType,
7
+ TanstackTableSelectedRowActionType,
8
+ TanstackTableTableActionsType,
9
+ } from "../types";
10
+ import { TanstackTableDateFilter } from "./tanstack-table-filter-date";
11
+ import { TanstackTableFacetedFilter } from "./tanstack-table-filter-faceted";
12
+ import { TanstackTableTextFilter } from "./tanstack-table-filter-text";
13
+ import { TanstackTableViewOptions } from "./tanstack-table-view-options";
14
+ import { Label } from "@repo/ayasofyazilim-ui/components/label";
15
+
16
+ interface TanstackTableToolbarProps<TData> {
17
+ title?: string;
18
+ editable?: boolean;
19
+ filters?: TanstackTableFiltersType;
20
+ selectedRowAction?: TanstackTableSelectedRowActionType<TData>;
21
+ setTableAction: (actions: TanstackTableTableActionsType<TData>) => void;
22
+ table: Table<TData>;
23
+ tableActions?: TanstackTableTableActionsType<TData>[];
24
+ tableData: TData[];
25
+ }
26
+
27
+ export const TanstackTableToolbar = <TData,>({
28
+ title,
29
+ table,
30
+ filters,
31
+ tableData,
32
+ selectedRowAction,
33
+ tableActions,
34
+ setTableAction,
35
+ editable,
36
+ }: TanstackTableToolbarProps<TData>) => {
37
+ const router = useRouter();
38
+ const pathname = usePathname();
39
+ const searchParams = useSearchParams();
40
+ const params = new URLSearchParams(searchParams.toString());
41
+ const columnNames = table.getAllColumns().map((column) => column.id);
42
+ function onFilter(accessorKey: string, selectedValues: string) {
43
+ const newParams = new URLSearchParams(searchParams.toString());
44
+ if (selectedValues) {
45
+ newParams.set(accessorKey, selectedValues);
46
+ } else {
47
+ newParams.delete(accessorKey);
48
+ }
49
+ if (newParams.get(accessorKey) !== searchParams.get(accessorKey)) {
50
+ router.replace(`${pathname}?${newParams.toString()}`);
51
+ }
52
+ }
53
+ function onFilterMultiple(
54
+ filter: { accessorKey: string; selectedValues: string }[]
55
+ ) {
56
+ const newParams = new URLSearchParams(searchParams.toString());
57
+ filter.forEach(({ accessorKey, selectedValues }) => {
58
+ if (selectedValues) {
59
+ newParams.set(accessorKey, selectedValues);
60
+ } else {
61
+ newParams.delete(accessorKey);
62
+ }
63
+ });
64
+ if (newParams.toString() !== searchParams.toString()) {
65
+ router.replace(`${pathname}?${newParams.toString()}`);
66
+ }
67
+ }
68
+ if (!editable && !tableActions && !title && !filters) return null;
69
+ return (
70
+ <div className="flex w-full items-center justify-between p-px">
71
+ <div className="flex flex-1 h-full flex-wrap items-center gap-x-2">
72
+ {title && (
73
+ <Label className="mt-auto text-slate-600" asChild>
74
+ <p>{title}</p>
75
+ </Label>
76
+ )}
77
+ {filters?.textFilters &&
78
+ filters.textFilters.map((accessorKey) => (
79
+ <TanstackTableTextFilter
80
+ title={filters?.filterTitles?.[accessorKey]}
81
+ key={accessorKey}
82
+ column={
83
+ columnNames.includes(accessorKey)
84
+ ? table.getColumn(accessorKey)
85
+ : undefined
86
+ }
87
+ accessorKey={accessorKey}
88
+ params={params}
89
+ onFilter={(accessorKey, selectedValues) =>
90
+ onFilter(accessorKey, selectedValues)
91
+ }
92
+ />
93
+ ))}
94
+
95
+ {filters?.dateFilters &&
96
+ filters.dateFilters.map((dateItem) => (
97
+ <TanstackTableDateFilter
98
+ key={dateItem.label}
99
+ accessorKey={dateItem.label}
100
+ column={
101
+ columnNames.includes(dateItem.label)
102
+ ? table.getColumn(dateItem.label)
103
+ : undefined
104
+ }
105
+ dateItem={dateItem}
106
+ params={params}
107
+ onFilter={(accessorKey, selectedValues) =>
108
+ onFilter(accessorKey, selectedValues)
109
+ }
110
+ onFilterMultiple={(filter) => onFilterMultiple(filter)}
111
+ />
112
+ ))}
113
+
114
+ {filters?.facetedFilters &&
115
+ Object.keys(filters.facetedFilters)?.map((column) => (
116
+ <TanstackTableFacetedFilter
117
+ key={column}
118
+ column={
119
+ columnNames.includes(column)
120
+ ? table.getColumn(column)
121
+ : undefined
122
+ }
123
+ accessorKey={column}
124
+ params={params}
125
+ onFilter={(accessorKey, selectedValues) => {
126
+ onFilter(accessorKey, selectedValues);
127
+ }}
128
+ title={filters?.facetedFilters?.[column]?.title ?? column}
129
+ options={filters?.facetedFilters?.[column]?.options ?? []}
130
+ />
131
+ ))}
132
+ </div>
133
+ <TanstackTableViewOptions
134
+ table={table}
135
+ selectedRowAction={selectedRowAction}
136
+ tableActions={tableActions}
137
+ setTableAction={setTableAction}
138
+ tableData={tableData}
139
+ editable={editable}
140
+ />
141
+ </div>
142
+ );
143
+ };