@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,219 @@
1
+ "use client";
2
+
3
+ import { ColumnDef } from "@tanstack/react-table";
4
+ import { useEffect, useState } from "react";
5
+ import { Input } from "@repo/ayasofyazilim-ui/components/input";
6
+ import {
7
+ Select,
8
+ SelectContent,
9
+ SelectGroup,
10
+ SelectItem,
11
+ SelectTrigger,
12
+ SelectValue,
13
+ } from "@repo/ayasofyazilim-ui/components/select";
14
+ import { Switch } from "@repo/ayasofyazilim-ui/components/switch";
15
+ import { cn } from "@repo/ayasofyazilim-ui/lib/utils";
16
+ import { createCell, tanstackTableCreateTitleWithLanguageData } from ".";
17
+ import { TanstackTableColumnHeader } from "../fields";
18
+ import {
19
+ TanstackTableCreateColumnsByRowId,
20
+ TanstacktableEditableColumnsByRowId,
21
+ } from "../types";
22
+ import { DatePicker } from "@repo/ayasofyazilim-ui/custom/date-picker";
23
+
24
+ export function tanstackTableEditableColumnsByRowData<T>(
25
+ params: TanstacktableEditableColumnsByRowId<T> &
26
+ Omit<TanstackTableCreateColumnsByRowId<T>, "rows" | "selectableRows">
27
+ ) {
28
+ const {
29
+ rows,
30
+ excludeColumns,
31
+ languageData,
32
+ editableColumns,
33
+ config,
34
+ faceted,
35
+ links,
36
+ badges,
37
+ classNames,
38
+ custom,
39
+ expandRowTrigger,
40
+ icons,
41
+ localization,
42
+ } = params;
43
+ const columns: ColumnDef<T>[] = [];
44
+
45
+ Object.keys(rows)
46
+ .filter((key) => !excludeColumns?.includes(key as keyof T))
47
+ .forEach((accessorKey) => {
48
+ const title = tanstackTableCreateTitleWithLanguageData({
49
+ languageData,
50
+ accessorKey,
51
+ });
52
+ const column: ColumnDef<T> = {
53
+ id: accessorKey,
54
+ accessorKey,
55
+ meta: title,
56
+ header: ({ column }) => (
57
+ <TanstackTableColumnHeader column={column} title={title} />
58
+ ),
59
+ cell: ({ getValue, row, column: { id }, table }) => {
60
+ const _accesorKey = accessorKey as keyof T;
61
+ if (editableColumns && !editableColumns.includes(_accesorKey)) {
62
+ return createCell<T>({
63
+ accessorKey: _accesorKey,
64
+ row,
65
+ link: links?.[_accesorKey],
66
+ faceted: faceted?.[_accesorKey]?.options,
67
+ badge: badges?.[_accesorKey],
68
+ icon: icons?.[_accesorKey],
69
+ className: classNames?.[_accesorKey],
70
+ expandRowTrigger: expandRowTrigger === _accesorKey,
71
+ format: rows[accessorKey]?.format,
72
+ custom: custom?.[_accesorKey],
73
+ config,
74
+ localization,
75
+ });
76
+ }
77
+ const initialValue = (getValue() as string)?.toString() || "";
78
+ const [value, setValue] = useState(initialValue);
79
+ const rowId = row.index.toString();
80
+ const isRowSelected = table.getRow(rowId)?.getIsSelected();
81
+
82
+ // When the input is blurred, we'll call our table meta's updateData function
83
+ const onBlur = () => {
84
+ let $value: string | number | boolean;
85
+ switch (rows[accessorKey]?.type) {
86
+ case "number":
87
+ $value = Number(value);
88
+ break;
89
+ case "boolean":
90
+ $value = value === "true";
91
+ break;
92
+ default:
93
+ $value = value;
94
+ }
95
+ table.options.meta?.updateData(row.index, id, $value);
96
+ };
97
+
98
+ function handleValueChange(newValue: string) {
99
+ setValue(newValue);
100
+ if (isRowSelected && newValue === initialValue) {
101
+ table.setRowSelection((old) => ({
102
+ ...old,
103
+ [rowId]: false,
104
+ }));
105
+ return;
106
+ }
107
+
108
+ if (!isRowSelected && newValue !== initialValue) {
109
+ table.setRowSelection((old) => ({
110
+ ...old,
111
+ [rowId]: true,
112
+ }));
113
+ }
114
+ }
115
+
116
+ useEffect(() => {
117
+ setValue(initialValue);
118
+ }, [initialValue]);
119
+
120
+ if (rows[accessorKey]?.enum) {
121
+ return (
122
+ <Select
123
+ value={value as string}
124
+ onValueChange={(_value) => {
125
+ handleValueChange(_value);
126
+ const $value =
127
+ rows[accessorKey]?.type === "number"
128
+ ? Number(_value)
129
+ : _value;
130
+ table.options.meta?.updateData(row.index, id, $value);
131
+ }}
132
+ >
133
+ <SelectTrigger
134
+ className={cn(
135
+ "w-[180px] min-w-max border-none rounded-none focus-visible:border-none focus-within:border-none ring-0 focus-visible:ring-0 focus-within:ring-0 ring-transparent shadow-none",
136
+ isRowSelected ? "font-medium italic" : "",
137
+ !value && "text-muted-foreground"
138
+ )}
139
+ >
140
+ <SelectValue
141
+ placeholder={
142
+ (languageData?.[
143
+ accessorKey as keyof typeof languageData
144
+ ] as string) || accessorKey
145
+ }
146
+ />
147
+ </SelectTrigger>
148
+ <SelectContent>
149
+ <SelectGroup>
150
+ {rows[accessorKey]?.enum?.map((item) => (
151
+ <SelectItem key={item.value} value={item.value}>
152
+ {item.label}
153
+ </SelectItem>
154
+ ))}
155
+ </SelectGroup>
156
+ </SelectContent>
157
+ </Select>
158
+ );
159
+ }
160
+ if (rows[accessorKey]?.type === "boolean") {
161
+ return (
162
+ <div className="text-center">
163
+ <Switch
164
+ className="align-middle"
165
+ checked={value === "true"}
166
+ onBlur={onBlur}
167
+ onCheckedChange={(_value) => {
168
+ handleValueChange(String(value));
169
+ table.options.meta?.updateData(row.index, id, _value);
170
+ }}
171
+ />
172
+ </div>
173
+ );
174
+ }
175
+ if (rows[accessorKey]?.format === "date-time") {
176
+ const date = new Date(value);
177
+ return (
178
+ <div className="text-center">
179
+ <DatePicker
180
+ id={`${accessorKey}_date`}
181
+ defaultValue={
182
+ date instanceof Date && !Number.isNaN(date.getTime())
183
+ ? date
184
+ : undefined
185
+ }
186
+ onChange={(date) => {
187
+ const $value =
188
+ rows[accessorKey]?.format === "date-time"
189
+ ? date?.toISOString()
190
+ : date;
191
+ table.options.meta?.updateData(row.index, id, $value);
192
+ }}
193
+ classNames={{
194
+ dateInput: "border-none rounded-none",
195
+ }}
196
+ />
197
+ </div>
198
+ );
199
+ }
200
+ return (
201
+ <Input
202
+ value={value as string}
203
+ className={cn(
204
+ "w-full border-none rounded-none focus-visible:border-none focus-within:border-none ring-0 focus-visible:ring-0 focus-within:ring-0 ring-transparent shadow-none",
205
+ isRowSelected ? "font-medium italic" : ""
206
+ )}
207
+ placeholder={accessorKey}
208
+ onChange={(e) => {
209
+ handleValueChange(e.target.value);
210
+ }}
211
+ onBlur={onBlur}
212
+ />
213
+ );
214
+ },
215
+ };
216
+ columns.push(column);
217
+ });
218
+ return columns;
219
+ }
@@ -0,0 +1,22 @@
1
+ import { CheckCircle, XCircle } from "lucide-react";
2
+
3
+ export const BooleanOptions = {
4
+ options: [
5
+ {
6
+ label: "Yes",
7
+ when: (value: string | number | boolean | Date) => Boolean(value),
8
+ value: "true",
9
+ icon: CheckCircle,
10
+ iconClassName: "text-green-700",
11
+ hideColumnValue: true,
12
+ },
13
+ {
14
+ label: "No",
15
+ when: (value: string | number | boolean | Date) => !value,
16
+ value: "false",
17
+ icon: XCircle,
18
+ iconClassName: "text-red-700",
19
+ hideColumnValue: true,
20
+ },
21
+ ],
22
+ };
@@ -0,0 +1,10 @@
1
+ "use client";
2
+
3
+ export * from "./table";
4
+ export * from "./column-names";
5
+ export * from "./cell-with-actions";
6
+ export * from "./columns-by-row-data";
7
+ export * from "./editable-columns-by-row-data";
8
+ export * from "./pinning-styles";
9
+ export * from "./test-conditions";
10
+ export * from "./faceted-boolean-options";
@@ -0,0 +1,57 @@
1
+ import { Column } from "@tanstack/react-table";
2
+ import { CSSProperties } from "react";
3
+
4
+ export function getCommonPinningStyles<TData>({
5
+ column,
6
+ fillerColumn,
7
+ withBorder,
8
+ resizeable,
9
+ }: {
10
+ resizeable?: boolean;
11
+ column: Column<TData>;
12
+ fillerColumn?: keyof TData;
13
+
14
+ /**
15
+ * Show box shadow between pinned and scrollable columns.
16
+ * @default false
17
+ */
18
+ withBorder?: boolean;
19
+ }): CSSProperties {
20
+ const isPinned = column.getIsPinned();
21
+ const isLastLeftPinnedColumn =
22
+ isPinned === "left" && column.getIsLastColumn("left");
23
+ const isFirstRightPinnedColumn =
24
+ isPinned === "right" && column.getIsFirstColumn("right");
25
+
26
+ let width: string | number = column.getSize();
27
+ if (resizeable) {
28
+ if (fillerColumn === column.id) {
29
+ width = 2000;
30
+ } else {
31
+ width = column.getSize();
32
+ }
33
+ } else if (fillerColumn === column.id) {
34
+ width = "100%";
35
+ } else {
36
+ width = column.getSize();
37
+ }
38
+
39
+ return {
40
+ boxShadow: withBorder
41
+ ? isLastLeftPinnedColumn
42
+ ? "-4px 0 4px -4px var(--border) inset"
43
+ : isFirstRightPinnedColumn
44
+ ? "4px 0 4px -4px var(--border) inset"
45
+ : undefined
46
+ : undefined,
47
+ left: isPinned === "left" ? `${column.getStart("left")}px` : undefined,
48
+ right: isPinned === "right" ? `${column.getAfter("right")}px` : undefined,
49
+ opacity: isPinned ? 0.97 : 1,
50
+ width,
51
+ position: isPinned ? "sticky" : "relative",
52
+ background: isPinned ? "var(--background)" : "",
53
+ zIndex: isPinned ? 1 : 0,
54
+ textWrap: "nowrap",
55
+ ...(column.id === "select" && { minWidth: "40px", padding: 0 }),
56
+ };
57
+ }
@@ -0,0 +1,83 @@
1
+ "use client";
2
+
3
+ import { ColumnFiltersState } from "@tanstack/react-table";
4
+ import { useState, useEffect } from "react";
5
+ import {
6
+ EditableTanstackTableProps,
7
+ NonEditableTanstackTableProps,
8
+ } from "../types";
9
+
10
+ export function NonEditableTanstackTable<TData>(
11
+ data: TData[],
12
+ rowCount: number
13
+ ): NonEditableTanstackTableProps<TData> {
14
+ const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
15
+
16
+ const [pagination, setPagination] = useState<{
17
+ pageIndex: number;
18
+ pageSize: number;
19
+ }>({ pageIndex: 0, pageSize: 10 });
20
+
21
+ return {
22
+ data,
23
+ rowCount,
24
+ pagination,
25
+ columnFilters,
26
+ onPaginationChange: setPagination,
27
+ onColumnFiltersChange: setColumnFilters,
28
+ };
29
+ }
30
+
31
+ export function EditableTanstackTable<TData>({
32
+ initialData,
33
+ onTableDataChange,
34
+ }: {
35
+ initialData: TData[];
36
+ onTableDataChange?: (data: TData[]) => void;
37
+ }): EditableTanstackTableProps<TData> {
38
+ const [tableData, setTableData] = useState<TData[]>(initialData);
39
+ useEffect(() => {
40
+ // When user submits the form, the initialData changes with the new data
41
+ // so we need to update the table data
42
+ setTableData(initialData);
43
+ }, [initialData]);
44
+
45
+ return {
46
+ data: tableData,
47
+ meta: {
48
+ removeRow: (rowIndex) => {
49
+ const newData = [...tableData];
50
+ newData.splice(rowIndex, 1);
51
+ setTableData(newData);
52
+ onTableDataChange?.(newData);
53
+ },
54
+ updateData: (rowIndex, columnId, value) => {
55
+ const newData = [...tableData];
56
+ newData[rowIndex] = {
57
+ ...newData[rowIndex],
58
+ [columnId]: value,
59
+ } as TData;
60
+ setTableData(newData);
61
+ onTableDataChange?.(newData);
62
+ },
63
+ addRow: () => {
64
+ const newData = [...tableData, {} as TData];
65
+ setTableData(newData);
66
+ onTableDataChange?.(newData);
67
+ },
68
+ duplicateRow: (rowIndex, value) => {
69
+ const newData = [...tableData];
70
+ newData.splice(rowIndex, 0, value);
71
+ setTableData(newData);
72
+ onTableDataChange?.(newData);
73
+ },
74
+ orderRow: (newIndex, oldIndex) => {
75
+ const newData = [...tableData];
76
+ const item = newData.splice(oldIndex, 1)[0] as TData;
77
+ newData.splice(newIndex, 0, item);
78
+ setTableData(newData);
79
+ onTableDataChange?.(newData);
80
+ },
81
+ },
82
+ };
83
+ }
@@ -0,0 +1,17 @@
1
+ import { Row } from "@tanstack/react-table";
2
+ import { TanstackTableCellCondition } from "../types";
3
+
4
+ export function testConditions<T>(
5
+ conditions: TanstackTableCellCondition[] | undefined,
6
+ row: Row<T>
7
+ ) {
8
+ if (!conditions) return true;
9
+
10
+ return (
11
+ conditions
12
+ .map((condition) =>
13
+ condition.when(row.getValue(condition.conditionAccessorKey))
14
+ )
15
+ .filter((i) => !i).length === 0
16
+ );
17
+ }
@@ -0,0 +1,208 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { Slot } from "radix-ui";
5
+ import { cn } from "@repo/ayasofyazilim-ui/lib/utils";
6
+
7
+ // Types
8
+ type TimelineContextValue = {
9
+ activeStep: number;
10
+ setActiveStep: (step: number) => void;
11
+ };
12
+
13
+ // Context
14
+ const TimelineContext = React.createContext<TimelineContextValue | undefined>(
15
+ undefined
16
+ );
17
+
18
+ const useTimeline = () => {
19
+ const context = React.useContext(TimelineContext);
20
+ if (!context) {
21
+ throw new Error("useTimeline must be used within a Timeline");
22
+ }
23
+ return context;
24
+ };
25
+
26
+ // Components
27
+ interface TimelineProps extends React.HTMLAttributes<HTMLDivElement> {
28
+ defaultValue?: number;
29
+ value?: number;
30
+ onValueChange?: (value: number) => void;
31
+ orientation?: "horizontal" | "vertical";
32
+ }
33
+
34
+ function Timeline({
35
+ defaultValue = 1,
36
+ value,
37
+ onValueChange,
38
+ orientation = "vertical",
39
+ className,
40
+ ...props
41
+ }: TimelineProps) {
42
+ const [activeStep, setInternalStep] = React.useState(defaultValue);
43
+
44
+ const setActiveStep = React.useCallback(
45
+ (step: number) => {
46
+ if (value === undefined) {
47
+ setInternalStep(step);
48
+ }
49
+ onValueChange?.(step);
50
+ },
51
+ [value, onValueChange]
52
+ );
53
+
54
+ const currentStep = value ?? activeStep;
55
+
56
+ return (
57
+ <TimelineContext.Provider
58
+ value={{ activeStep: currentStep, setActiveStep }}
59
+ >
60
+ <div
61
+ data-slot="timeline"
62
+ className={cn(
63
+ "group/timeline flex data-[orientation=horizontal]:w-full data-[orientation=horizontal]:flex-row data-[orientation=vertical]:flex-col",
64
+ className
65
+ )}
66
+ data-orientation={orientation}
67
+ {...props}
68
+ />
69
+ </TimelineContext.Provider>
70
+ );
71
+ }
72
+
73
+ // TimelineContent
74
+ function TimelineContent({
75
+ className,
76
+ ...props
77
+ }: React.HTMLAttributes<HTMLDivElement>) {
78
+ return (
79
+ <div
80
+ data-slot="timeline-content"
81
+ className={cn("text-sm text-muted-foreground", className)}
82
+ {...props}
83
+ />
84
+ );
85
+ }
86
+
87
+ // TimelineDate
88
+ interface TimelineDateProps extends React.HTMLAttributes<HTMLTimeElement> {
89
+ asChild?: boolean;
90
+ }
91
+
92
+ function TimelineDate({
93
+ asChild = false,
94
+ className,
95
+ ...props
96
+ }: TimelineDateProps) {
97
+ const Comp = asChild ? Slot.Root : "time";
98
+
99
+ return (
100
+ <Comp
101
+ data-slot="timeline-date"
102
+ className={cn(
103
+ "mb-1 block text-xs font-medium text-muted-foreground group-data-[orientation=vertical]/timeline:max-sm:h-4",
104
+ className
105
+ )}
106
+ {...props}
107
+ />
108
+ );
109
+ }
110
+
111
+ // TimelineHeader
112
+ function TimelineHeader({
113
+ className,
114
+ ...props
115
+ }: React.HTMLAttributes<HTMLDivElement>) {
116
+ return (
117
+ <div data-slot="timeline-header" className={cn(className)} {...props} />
118
+ );
119
+ }
120
+
121
+ // TimelineIndicator
122
+ interface TimelineIndicatorProps extends React.HTMLAttributes<HTMLDivElement> {
123
+ asChild?: boolean;
124
+ }
125
+
126
+ function TimelineIndicator({
127
+ className,
128
+ children,
129
+ ...props
130
+ }: TimelineIndicatorProps) {
131
+ return (
132
+ <div
133
+ data-slot="timeline-indicator"
134
+ className={cn(
135
+ "absolute size-4 rounded-full border-2 border-primary/20 group-data-completed/timeline-item:border-primary group-data-[orientation=horizontal]/timeline:-top-6 group-data-[orientation=horizontal]/timeline:left-0 group-data-[orientation=horizontal]/timeline:-translate-y-1/2 group-data-[orientation=vertical]/timeline:top-0 group-data-[orientation=vertical]/timeline:-left-6 group-data-[orientation=vertical]/timeline:-translate-x-1/2",
136
+ className
137
+ )}
138
+ aria-hidden="true"
139
+ {...props}
140
+ >
141
+ {children}
142
+ </div>
143
+ );
144
+ }
145
+
146
+ // TimelineItem
147
+ interface TimelineItemProps extends React.HTMLAttributes<HTMLDivElement> {
148
+ step: number;
149
+ }
150
+
151
+ function TimelineItem({ step, className, ...props }: TimelineItemProps) {
152
+ const { activeStep } = useTimeline();
153
+
154
+ return (
155
+ <div
156
+ data-slot="timeline-item"
157
+ className={cn(
158
+ "group/timeline-item relative flex flex-1 flex-col gap-0.5 group-data-[orientation=horizontal]/timeline:mt-8 group-data-[orientation=horizontal]/timeline:not-last:pe-8 group-data-[orientation=vertical]/timeline:ms-8 group-data-[orientation=vertical]/timeline:not-last:pb-12 has-[+[data-completed]]:**:data-[slot=timeline-separator]:bg-primary",
159
+ className
160
+ )}
161
+ data-completed={step <= activeStep || undefined}
162
+ {...props}
163
+ />
164
+ );
165
+ }
166
+
167
+ // TimelineSeparator
168
+ function TimelineSeparator({
169
+ className,
170
+ ...props
171
+ }: React.HTMLAttributes<HTMLDivElement>) {
172
+ return (
173
+ <div
174
+ data-slot="timeline-separator"
175
+ className={cn(
176
+ "absolute self-start bg-primary/10 group-last/timeline-item:hidden group-data-[orientation=horizontal]/timeline:-top-6 group-data-[orientation=horizontal]/timeline:h-0.5 group-data-[orientation=horizontal]/timeline:w-[calc(100%-1rem-0.25rem)] group-data-[orientation=horizontal]/timeline:translate-x-4.5 group-data-[orientation=horizontal]/timeline:-translate-y-1/2 group-data-[orientation=vertical]/timeline:-left-6 group-data-[orientation=vertical]/timeline:h-[calc(100%-1rem-0.25rem)] group-data-[orientation=vertical]/timeline:w-0.5 group-data-[orientation=vertical]/timeline:-translate-x-1/2 group-data-[orientation=vertical]/timeline:translate-y-4.5",
177
+ className
178
+ )}
179
+ aria-hidden="true"
180
+ {...props}
181
+ />
182
+ );
183
+ }
184
+
185
+ // TimelineTitle
186
+ function TimelineTitle({
187
+ className,
188
+ ...props
189
+ }: React.HTMLAttributes<HTMLHeadingElement>) {
190
+ return (
191
+ <h3
192
+ data-slot="timeline-title"
193
+ className={cn("text-sm font-medium", className)}
194
+ {...props}
195
+ />
196
+ );
197
+ }
198
+
199
+ export {
200
+ Timeline,
201
+ TimelineContent,
202
+ TimelineDate,
203
+ TimelineHeader,
204
+ TimelineIndicator,
205
+ TimelineItem,
206
+ TimelineSeparator,
207
+ TimelineTitle,
208
+ };