@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,236 @@
1
+ "use client";
2
+
3
+ import React, {
4
+ Children,
5
+ Dispatch,
6
+ SetStateAction,
7
+ createContext,
8
+ useContext,
9
+ useMemo,
10
+ } from "react";
11
+ import { Button } from "@repo/ayasofyazilim-ui/components/button";
12
+ import { cn } from "@repo/ayasofyazilim-ui/lib/utils";
13
+
14
+ export interface ISeparatorProps {
15
+ vertical?: boolean;
16
+ }
17
+ export const Separator = ({ vertical }: ISeparatorProps) => {
18
+ const containerClass = `border-muted items-center justify-center flex ${
19
+ vertical ? "w-1" : "h-8 w-full"
20
+ }`;
21
+ const innerClass = `bg-muted w-full ${vertical ? "h-16" : "h-1"}`;
22
+
23
+ return (
24
+ <div className={containerClass}>
25
+ <div className={innerClass} />
26
+ </div>
27
+ );
28
+ };
29
+
30
+ export interface IStepperContentProps {
31
+ canGoBack?: boolean;
32
+ canGoNext?: boolean;
33
+ children?: React.ReactNode;
34
+ className?: string;
35
+ controlsClassName?: string;
36
+ isBackDisabled?: boolean;
37
+ isNextDisabled?: boolean;
38
+ nextButtonText?: string;
39
+ previousButtonText?: string;
40
+ title?: string;
41
+ }
42
+ export const StepperContent = ({
43
+ children,
44
+ title,
45
+ canGoBack = true,
46
+ canGoNext = true,
47
+ previousButtonText,
48
+ nextButtonText,
49
+ isBackDisabled,
50
+ isNextDisabled,
51
+ className,
52
+ controlsClassName,
53
+ }: IStepperContentProps) => {
54
+ const {
55
+ previousButtonText: defaultPreviousButtonText,
56
+ nextButtonText: defaultNextButtonText,
57
+ onIndexChange,
58
+ vertical,
59
+ stepsLength,
60
+ } = useContext(StepperContext);
61
+ const [isLastStep, setIsLastStep] = React.useState(false);
62
+ return (
63
+ <div id={title} className={cn(vertical ? "w-10/12" : "w-full", className)}>
64
+ {children}
65
+ {onIndexChange && (
66
+ <div className={cn("mt-5 flex justify-between", controlsClassName)}>
67
+ <div>
68
+ {canGoBack && (
69
+ <Button
70
+ variant="outline"
71
+ disabled={isBackDisabled}
72
+ onClick={() =>
73
+ onIndexChange((prev) => {
74
+ if (prev > 0) {
75
+ return prev - 1;
76
+ }
77
+ return prev;
78
+ })
79
+ }
80
+ >
81
+ {previousButtonText || defaultPreviousButtonText}
82
+ </Button>
83
+ )}
84
+ </div>
85
+ <div>
86
+ {canGoNext && (
87
+ <Button
88
+ disabled={isNextDisabled || isLastStep}
89
+ onClick={() =>
90
+ onIndexChange((prev) => {
91
+ if (prev === stepsLength - 1) {
92
+ setIsLastStep(true);
93
+ }
94
+ if (prev < stepsLength - 1) {
95
+ return prev + 1;
96
+ }
97
+ return prev;
98
+ })
99
+ }
100
+ >
101
+ {nextButtonText || defaultNextButtonText}
102
+ </Button>
103
+ )}
104
+ </div>
105
+ </div>
106
+ )}
107
+ </div>
108
+ );
109
+ };
110
+
111
+ export interface IStepperHeaderProps {
112
+ activeItemClassName?: string;
113
+ activeTabIndex: number;
114
+ containerClassName?: string;
115
+ inactiveItemClassName?: string;
116
+ keysWithSeparator:
117
+ | (string | { icon: React.ReactNode; index: number; title: string })[]
118
+ | undefined;
119
+ vertical?: boolean;
120
+ }
121
+
122
+ export const StepperHeader = ({
123
+ keysWithSeparator,
124
+ activeTabIndex,
125
+ vertical,
126
+ containerClassName,
127
+ activeItemClassName,
128
+ inactiveItemClassName,
129
+ }: IStepperHeaderProps) => {
130
+ const containerClass = cn(
131
+ `flex gap-5 justify-between relative mb-10 ${
132
+ vertical ? "flex-col items-center w-2/12" : "w-full"
133
+ }`,
134
+ containerClassName
135
+ );
136
+ const activeItemClass = cn("bg-primary text-white", activeItemClassName);
137
+ const inactiveItemClass = cn("bg-zinc-200 text-black", inactiveItemClassName);
138
+
139
+ return (
140
+ <div className={containerClass}>
141
+ {keysWithSeparator?.map((item, index) => {
142
+ if (typeof item === "string") {
143
+ return (
144
+ <Separator
145
+ key={`separator-${index.toString()}`}
146
+ vertical={vertical}
147
+ />
148
+ );
149
+ }
150
+
151
+ const active = activeTabIndex === item.index;
152
+ const innerClass = `rounded-full w-8 h-8 items-center justify-center flex text-xs ${
153
+ active ? activeItemClass : inactiveItemClass
154
+ }`;
155
+ const titleContainerClass = `text-sm text-center ${
156
+ active ? "text-black" : "text-muted-foreground"
157
+ }`;
158
+ return (
159
+ <div key={item.index} className="flex flex-col items-center gap-2">
160
+ <div className={innerClass}>{item.icon || item.index + 1}</div>
161
+ <div className={titleContainerClass}>{item.title}</div>
162
+ </div>
163
+ );
164
+ })}
165
+ </div>
166
+ );
167
+ };
168
+
169
+ const StepperContext = createContext({
170
+ nextButtonText: "Next",
171
+ previousButtonText: "Previous",
172
+ // eslint-disable-next-line
173
+ onIndexChange: (value: SetStateAction<number>) => {},
174
+ vertical: false,
175
+ stepsLength: 2,
176
+ });
177
+ export interface IStepperProps {
178
+ activeTabIndex: number;
179
+ children?: React.ReactNode[];
180
+ className?: string;
181
+ headerProps?: Partial<IStepperHeaderProps>;
182
+ nextButtonText?: string;
183
+ onIndexChange: Dispatch<SetStateAction<number>>;
184
+ previousButtonText?: string;
185
+ vertical?: boolean;
186
+ }
187
+
188
+ export default function Stepper({
189
+ children,
190
+ activeTabIndex,
191
+ vertical = false,
192
+ nextButtonText = "Next",
193
+ previousButtonText = "Previous",
194
+ onIndexChange,
195
+ className,
196
+ headerProps,
197
+ }: IStepperProps) {
198
+ const keys = children?.flatMap((child, index) => {
199
+ const item = React.isValidElement(child)
200
+ ? {
201
+ title: (child.props as { title: string }).title || "",
202
+ icon: (child.props as { icon: string }).icon,
203
+ index,
204
+ }
205
+ : { title: "", icon: "", index };
206
+ if (index === 0) {
207
+ return [item];
208
+ }
209
+ return ["SEPARATOR", item];
210
+ });
211
+ const stepsLength = Children.count(children);
212
+ const providerProps = useMemo(
213
+ () => ({
214
+ nextButtonText,
215
+ previousButtonText,
216
+ onIndexChange,
217
+ vertical,
218
+ stepsLength,
219
+ }),
220
+ [nextButtonText, previousButtonText, onIndexChange, vertical, stepsLength]
221
+ );
222
+ const filteredChildren = React.Children.toArray(children)?.[activeTabIndex];
223
+ return (
224
+ <StepperContext.Provider value={providerProps}>
225
+ <div className={cn(vertical ? "flex flex-row gap-10" : "", className)}>
226
+ <StepperHeader
227
+ keysWithSeparator={keys}
228
+ activeTabIndex={activeTabIndex}
229
+ vertical={vertical}
230
+ {...headerProps}
231
+ />
232
+ {filteredChildren}
233
+ </div>
234
+ </StepperContext.Provider>
235
+ );
236
+ }
@@ -0,0 +1,213 @@
1
+ "use client";
2
+
3
+ import { cva, VariantProps } from "class-variance-authority";
4
+ import Link from "next/link";
5
+ import { usePathname, useSearchParams } from "next/navigation";
6
+ import { ComponentType, ReactNode, Suspense } from "react";
7
+ import { cn } from "@repo/ayasofyazilim-ui/lib/utils";
8
+ import { Skeleton } from "@repo/ayasofyazilim-ui/components/skeleton";
9
+
10
+ type DeepPartial<T> = T extends object
11
+ ? {
12
+ [P in keyof T]?: DeepPartial<T[P]>;
13
+ }
14
+ : T;
15
+ const defaultClassNames = {
16
+ vertical: {
17
+ tabs: "flex h-full overflow-clip md:overflow-hidden block gap-2",
18
+ tabList:
19
+ "flex flex-col h-full justify-start max-w-sm overflow-hidden border-b-2 pb-2 mb-2 md:mb-0 mb:border-b-0",
20
+ tabTrigger: "justify-start md:max-w-lg overflow-hidden w-full",
21
+ tabContent: "mx-2 my-0 w-full h-full overflow-auto flex-1",
22
+ },
23
+ horizontal: {
24
+ tabs: "flex h-full overflow-hidden flex-col",
25
+ tabList: "w-full mx:w-max overflow-x-auto overflow-y-hidden min-h-max",
26
+ tabTrigger: "min-w-max",
27
+ tabContent: "h-full my-2 overflow-auto",
28
+ },
29
+ };
30
+
31
+ const tabsVariants = cva("", {
32
+ variants: {
33
+ variant: {
34
+ default: "",
35
+ simple: "",
36
+ },
37
+ orientation: {
38
+ horizontal: "md:flex md:h-full md:overflow-hidden flex-col",
39
+ vertical: "md:flex md:h-full",
40
+ },
41
+ },
42
+ defaultVariants: {
43
+ orientation: "horizontal",
44
+ variant: "default",
45
+ },
46
+ });
47
+
48
+ const tabListVariants = cva("", {
49
+ variants: {
50
+ variant: {
51
+ default:
52
+ "inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
53
+ simple: "",
54
+ },
55
+ orientation: {
56
+ horizontal: "w-max mx:w-max overflow-x-auto overflow-y-hidden min-h-max",
57
+ vertical:
58
+ "flex flex-col md:h-full justify-start md:max-w-[220px] w-full md:overflow-hidden md:pr-3 md:border-r border-muted",
59
+ },
60
+ },
61
+ defaultVariants: {
62
+ orientation: "horizontal",
63
+ variant: "default",
64
+ },
65
+ });
66
+
67
+ const tabTriggerVariants = cva(
68
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
69
+ {
70
+ variants: {
71
+ variant: {
72
+ default:
73
+ "px-3 py-1 ring-offset-background transition-all focus-visible:ring-2 focus-visible:ring-offset-2 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
74
+ simple:
75
+ "px-3 py-2 ring-offset-background transition-all rounded-lg focus-visible:ring-2 focus-visible:ring-offset-2 data-[state=active]:bg-muted data-[state=active]:text-foreground",
76
+ },
77
+ orientation: {
78
+ horizontal: "",
79
+ vertical: "justify-start md:max-w-lg overflow-hidden w-full",
80
+ },
81
+ },
82
+ defaultVariants: {
83
+ orientation: "horizontal",
84
+ variant: "default",
85
+ },
86
+ }
87
+ );
88
+
89
+ const tabContentVariants = cva("", {
90
+ variants: {
91
+ variant: {
92
+ default:
93
+ "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
94
+ simple: "",
95
+ },
96
+ orientation: {
97
+ horizontal: "h-full my-2 overflow-auto",
98
+ vertical: "my-0 w-full h-full overflow-auto flex-1",
99
+ },
100
+ },
101
+ defaultVariants: {
102
+ orientation: "horizontal",
103
+ variant: "default",
104
+ },
105
+ });
106
+
107
+ function findActiveTab(tabList: { href: string }[], path: string) {
108
+ const indexOfActiveTab = path
109
+ .split("/")
110
+ .reverse()
111
+ .findIndex((_, index) => {
112
+ if (index === 0) {
113
+ return tabList.find((i) => i.href === path);
114
+ }
115
+ const link = path.split("/").slice(0, -index).join("/");
116
+ return tabList.find((i) => i.href === link);
117
+ });
118
+ if (indexOfActiveTab === -1) {
119
+ return undefined;
120
+ }
121
+ if (indexOfActiveTab === 0) {
122
+ return tabList.find((i) => i.href === path)?.href;
123
+ }
124
+ return tabList.find(
125
+ (i) => i.href === path.split("/").slice(0, -indexOfActiveTab).join("/")
126
+ )?.href;
127
+ }
128
+
129
+ export function TabLayout({
130
+ tabList,
131
+ children,
132
+ orientation = "horizontal",
133
+ classNames,
134
+ variant = "default",
135
+ }: {
136
+ tabList: {
137
+ label: string;
138
+ href: string;
139
+ icon?: ComponentType<{ className?: string }>;
140
+ fallback?: ReactNode;
141
+ disabled?: boolean;
142
+ }[];
143
+ children: ReactNode;
144
+ orientation?: "horizontal" | "vertical";
145
+ classNames?: DeepPartial<typeof defaultClassNames>;
146
+ variant?: VariantProps<typeof tabsVariants>["variant"];
147
+ }) {
148
+ const tabsClassNames = tabsVariants({ orientation, variant });
149
+ const tabListClassNames = tabListVariants({ orientation, variant });
150
+ const tabTriggerClassNames = tabTriggerVariants({ orientation, variant });
151
+ const tabContentClassNames = tabContentVariants({ orientation, variant });
152
+ const path = usePathname();
153
+
154
+ const searchParams = `?${useSearchParams().toString()}`;
155
+ const active =
156
+ findActiveTab(tabList, path + searchParams) ||
157
+ findActiveTab(tabList, path) ||
158
+ tabList[0]?.href ||
159
+ "";
160
+
161
+ return (
162
+ <div
163
+ className={cn(tabsClassNames, classNames?.[orientation]?.tabs)}
164
+ role="tabpanel"
165
+ >
166
+ <div
167
+ role="tablist"
168
+ className={cn(tabListClassNames, classNames?.[orientation]?.tabList)}
169
+ style={{
170
+ scrollbarWidth: "thin",
171
+ }}
172
+ >
173
+ {tabList.map((tab) => (
174
+ <span
175
+ role="tab"
176
+ key={tab.href}
177
+ data-state={tab.href === active ? "active" : "inactive"}
178
+ className={cn(
179
+ tabTriggerClassNames,
180
+ classNames?.[orientation]?.tabTrigger,
181
+ tab.disabled && "text-muted-foreground cursor-not-allowed"
182
+ )}
183
+ >
184
+ {tab.disabled ? (
185
+ <span className="w-full overflow-hidden text-elipsis data-[state=active]:sticky data-[state=active]:left-0 data-[state=active]:right-0">
186
+ {tab.icon && <tab.icon className="block md:hidden" />}
187
+ {tab.label}
188
+ </span>
189
+ ) : (
190
+ <Link
191
+ href={tab.href}
192
+ className="w-full overflow-hidden text-elipsis data-[state=active]:sticky data-[state=active]:left-0 data-[state=active]:right-0"
193
+ >
194
+ {tab.icon && <tab.icon className="block md:hidden" />}
195
+ {tab.label}
196
+ </Link>
197
+ )}
198
+ </span>
199
+ ))}
200
+ </div>
201
+ <div
202
+ className={cn(
203
+ tabContentClassNames,
204
+ classNames?.[orientation]?.tabContent
205
+ )}
206
+ >
207
+ <Suspense fallback={<Skeleton className="flex-1 size-full" />}>
208
+ {children}
209
+ </Suspense>
210
+ </div>
211
+ </div>
212
+ );
213
+ }
@@ -0,0 +1,12 @@
1
+ export * from "./tanstack-table-column-header";
2
+ export * from "./tanstack-table-filter-faceted";
3
+ export * from "./tanstack-table-filter-text";
4
+ export * from "./tanstack-table-pagination";
5
+ export * from "./tanstack-table-row-actions-confirmation";
6
+ export * from "./tanstack-table-row-actions-custom-dialog";
7
+ export * from "./tanstack-table-row-actions";
8
+ export * from "./tanstack-table-table-actions-custom-dialog";
9
+ export * from "./tanstack-table-toolbar";
10
+ export * from "./tanstack-table-view-options";
11
+ export * from "./tanstack-table-plain-table";
12
+ export * from "./tanstack-table-action-dialogs";
@@ -0,0 +1,89 @@
1
+ import React, { Dispatch, useEffect } from "react";
2
+ import {
3
+ TanstackTableConfirmationDialog,
4
+ TanstackTableCustomDialog,
5
+ TanstackTableTableCustomDialog,
6
+ } from ".";
7
+ import {
8
+ TanstackTableRowActionsType,
9
+ TanstackTableTableActionsType,
10
+ } from "../types";
11
+ import { TanstackTableTableSchemaFormDialog } from "./tanstack-table-table-actions-schemaform-dialog";
12
+
13
+ export function TanstackTableActionDialogs<TData>({
14
+ rowAction,
15
+ setRowAction,
16
+ tableAction,
17
+ setTableAction,
18
+ }: {
19
+ rowAction: (TanstackTableRowActionsType<TData> & { row: TData }) | null;
20
+ setRowAction: Dispatch<
21
+ React.SetStateAction<
22
+ | (TanstackTableRowActionsType<TData> & {
23
+ row: TData;
24
+ })
25
+ | null
26
+ >
27
+ >;
28
+ setTableAction: Dispatch<
29
+ React.SetStateAction<TanstackTableTableActionsType<TData> | null>
30
+ >;
31
+ tableAction: TanstackTableTableActionsType<TData> | null;
32
+ }) {
33
+ useEffect(() => {
34
+ if (rowAction?.type === "simple") {
35
+ rowAction.onClick(rowAction.row);
36
+ setRowAction(null);
37
+ }
38
+ }, [rowAction]);
39
+
40
+ return (
41
+ <>
42
+ {rowAction?.type === "confirmation-dialog" && (
43
+ <TanstackTableConfirmationDialog<TData>
44
+ setDialogOpen={() => setRowAction(null)}
45
+ row={rowAction.row}
46
+ title={rowAction.title}
47
+ description={rowAction.description}
48
+ confirmationText={rowAction.confirmationText}
49
+ cancelText={rowAction.cancelText}
50
+ onConfirm={rowAction.onConfirm}
51
+ onCancel={rowAction.onCancel}
52
+ type="confirmation-dialog"
53
+ />
54
+ )}
55
+ {rowAction?.type === "custom-dialog" && (
56
+ <TanstackTableCustomDialog<TData>
57
+ setDialogOpen={() => setRowAction(null)}
58
+ row={rowAction.row}
59
+ title={rowAction.title}
60
+ content={rowAction.content}
61
+ confirmationText={rowAction.confirmationText}
62
+ cancelText={rowAction.cancelText}
63
+ onConfirm={rowAction.onConfirm}
64
+ onCancel={rowAction.onCancel}
65
+ type="custom-dialog"
66
+ />
67
+ )}
68
+ {tableAction?.type === "custom-dialog" && (
69
+ <TanstackTableTableCustomDialog
70
+ setDialogOpen={() => setTableAction(null)}
71
+ title={tableAction.title}
72
+ type="custom-dialog"
73
+ content={tableAction.content}
74
+ confirmationText={tableAction.confirmationText}
75
+ cancelText={tableAction.cancelText}
76
+ onConfirm={tableAction.onConfirm}
77
+ onCancel={tableAction.onCancel}
78
+ dialogClassNames={tableAction.dialogClassNames}
79
+ />
80
+ )}
81
+ {tableAction?.type === "schemaform-dialog" && (
82
+ <TanstackTableTableSchemaFormDialog<TData>
83
+ setDialogOpen={() => setTableAction(null)}
84
+ {...tableAction}
85
+ />
86
+ )}
87
+ </>
88
+ );
89
+ }
@@ -0,0 +1,66 @@
1
+ import { ArrowDownIcon, ArrowUpIcon, ChevronsUpDownIcon } from "lucide-react";
2
+ import { Column } from "@tanstack/react-table";
3
+
4
+ import { HTMLAttributes } from "react";
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
+
14
+ interface TanstackTableColumnHeaderProps<TData, TValue>
15
+ extends HTMLAttributes<HTMLDivElement> {
16
+ column: Column<TData, TValue>;
17
+ title: string;
18
+ }
19
+
20
+ export function TanstackTableColumnHeader<TData, TValue>({
21
+ column,
22
+ title,
23
+ className,
24
+ }: TanstackTableColumnHeaderProps<TData, TValue>) {
25
+ if (!column.getCanSort()) {
26
+ return <div className={cn(className)}>{title}</div>;
27
+ }
28
+
29
+ return (
30
+ <div className={cn("flex items-center w-full space-x-2 mx-2", className)}>
31
+ <DropdownMenu>
32
+ <DropdownMenuTrigger asChild>
33
+ <Button
34
+ variant="ghost"
35
+ size="sm"
36
+ className="-ml-3 h-8 data-[state=open]:bg-accent w-full justify-between"
37
+ >
38
+ <span>{title}</span>
39
+ {column.getIsSorted() === "desc" ? (
40
+ <ArrowDownIcon className="ml-2 h-4 w-4" />
41
+ ) : column.getIsSorted() === "asc" ? (
42
+ <ArrowUpIcon className="ml-2 h-4 w-4" />
43
+ ) : (
44
+ <ChevronsUpDownIcon className="ml-2 h-4 w-4" />
45
+ )}
46
+ </Button>
47
+ </DropdownMenuTrigger>
48
+ <DropdownMenuContent align="start">
49
+ <DropdownMenuItem onClick={() => column.toggleSorting(false)}>
50
+ <ArrowUpIcon className="mr-2 h-3.5 w-3.5 text-muted-foreground/70" />
51
+ Asc
52
+ </DropdownMenuItem>
53
+ <DropdownMenuItem onClick={() => column.toggleSorting(true)}>
54
+ <ArrowDownIcon className="mr-2 h-3.5 w-3.5 text-muted-foreground/70" />
55
+ Desc
56
+ </DropdownMenuItem>
57
+ {/* <DropdownMenuSeparator />
58
+ <DropdownMenuItem onClick={() => column.toggleVisibility(false)}>
59
+ <EyeNoneIcon className="mr-2 h-3.5 w-3.5 text-muted-foreground/70" />
60
+ Hide
61
+ </DropdownMenuItem> */}
62
+ </DropdownMenuContent>
63
+ </DropdownMenu>
64
+ </div>
65
+ );
66
+ }