@gentleduck/registry-ui 0.2.1

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 (175) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/index.css +3 -0
  3. package/package.json +59 -0
  4. package/src/_old/_table/index.ts +5 -0
  5. package/src/_old/_table/table-advanced.constants.tsx +24 -0
  6. package/src/_old/_table/table-advanced.tsx +311 -0
  7. package/src/_old/_table/table-advanced.types.ts +272 -0
  8. package/src/_old/_table/table.constants.ts +2 -0
  9. package/src/_old/_table/table.hook.tsx +115 -0
  10. package/src/_old/_table/table.lib.ts +85 -0
  11. package/src/_old/_table/table.tsx +916 -0
  12. package/src/_old/_table/table.types.ts +118 -0
  13. package/src/_old/_table/todo.md +11 -0
  14. package/src/_old/_upload/index.ts +9 -0
  15. package/src/_old/_upload/todo.md +38 -0
  16. package/src/_old/_upload/upload-advanced-chunks.tsx +1624 -0
  17. package/src/_old/_upload/upload-advanced.tsx +507 -0
  18. package/src/_old/_upload/upload-sonner.tsx +58 -0
  19. package/src/_old/_upload/upload.assets.tsx +239 -0
  20. package/src/_old/_upload/upload.constants.tsx +75 -0
  21. package/src/_old/_upload/upload.dto.ts +19 -0
  22. package/src/_old/_upload/upload.lib.tsx +630 -0
  23. package/src/_old/_upload/upload.tsx +491 -0
  24. package/src/_old/_upload/upload.types.ts +436 -0
  25. package/src/accordion/accordion.tsx +247 -0
  26. package/src/accordion/index.ts +1 -0
  27. package/src/alert/alert.constants.ts +17 -0
  28. package/src/alert/alert.tsx +52 -0
  29. package/src/alert/index.ts +2 -0
  30. package/src/alert-dialog/alert-dialog.tsx +107 -0
  31. package/src/alert-dialog/index.ts +1 -0
  32. package/src/aspect-ratio/aspect-ratio.tsx +33 -0
  33. package/src/aspect-ratio/index.ts +1 -0
  34. package/src/audio/audio-record.tsx +776 -0
  35. package/src/audio/audio-visualizer.tsx +377 -0
  36. package/src/audio/audio.libs.ts +5 -0
  37. package/src/audio/audio.types.ts +50 -0
  38. package/src/audio/index.ts +2 -0
  39. package/src/avatar/avatar.tsx +78 -0
  40. package/src/avatar/index.ts +1 -0
  41. package/src/badge/badge.constants.ts +38 -0
  42. package/src/badge/badge.tsx +19 -0
  43. package/src/badge/index.ts +2 -0
  44. package/src/breadcrumb/breadcrumb.tsx +119 -0
  45. package/src/breadcrumb/index.ts +1 -0
  46. package/src/button/button.constants.ts +44 -0
  47. package/src/button/button.tsx +79 -0
  48. package/src/button/button.types.ts +38 -0
  49. package/src/button/index.ts +3 -0
  50. package/src/button-group/button-group.constants.ts +26 -0
  51. package/src/button-group/button-group.tsx +65 -0
  52. package/src/button-group/index.ts +2 -0
  53. package/src/calendar/calendar.tsx +191 -0
  54. package/src/calendar/index.ts +1 -0
  55. package/src/card/card.tsx +81 -0
  56. package/src/card/index.ts +1 -0
  57. package/src/carousel/carousel.tsx +211 -0
  58. package/src/carousel/carousel.types.ts +23 -0
  59. package/src/carousel/index.ts +2 -0
  60. package/src/chart/chart.libs.ts +27 -0
  61. package/src/chart/chart.tsx +260 -0
  62. package/src/chart/chart.types.ts +38 -0
  63. package/src/chart/index.ts +3 -0
  64. package/src/checkbox/checkbox.tsx +144 -0
  65. package/src/checkbox/checkbox.types.ts +24 -0
  66. package/src/checkbox/index.ts +2 -0
  67. package/src/collapsible/collapsible.tsx +151 -0
  68. package/src/collapsible/index.ts +1 -0
  69. package/src/combobox/combobox.tsx +132 -0
  70. package/src/combobox/index.ts +1 -0
  71. package/src/command/command.tsx +192 -0
  72. package/src/command/command.types.ts +11 -0
  73. package/src/command/index.ts +2 -0
  74. package/src/context-menu/context-menu.tsx +178 -0
  75. package/src/context-menu/index.ts +1 -0
  76. package/src/dialog/dialog-responsive.tsx +137 -0
  77. package/src/dialog/dialog.tsx +97 -0
  78. package/src/dialog/index.ts +2 -0
  79. package/src/direction/direction.tsx +13 -0
  80. package/src/direction/index.ts +1 -0
  81. package/src/drawer/drawer.tsx +185 -0
  82. package/src/drawer/index.ts +1 -0
  83. package/src/dropdown-menu/dropdown-menu.tsx +181 -0
  84. package/src/dropdown-menu/index.ts +1 -0
  85. package/src/empty/empty.constants.ts +15 -0
  86. package/src/empty/empty.tsx +73 -0
  87. package/src/empty/index.ts +2 -0
  88. package/src/field/field.constants.ts +22 -0
  89. package/src/field/field.tsx +203 -0
  90. package/src/field/index.ts +2 -0
  91. package/src/hover-card/hover-card.tsx +79 -0
  92. package/src/hover-card/index.ts +1 -0
  93. package/src/input/index.ts +1 -0
  94. package/src/input/input.tsx +45 -0
  95. package/src/input-group/index.ts +1 -0
  96. package/src/input-group/input-group.tsx +170 -0
  97. package/src/input-otp/index.ts +1 -0
  98. package/src/input-otp/input-otp.tsx +66 -0
  99. package/src/item/index.ts +2 -0
  100. package/src/item/item.constants.ts +22 -0
  101. package/src/item/item.tsx +185 -0
  102. package/src/json-editor/index.ts +4 -0
  103. package/src/json-editor/json-editor.hooks.ts +21 -0
  104. package/src/json-editor/json-editor.libs.ts +34 -0
  105. package/src/json-editor/json-editor.tsx +425 -0
  106. package/src/json-editor/json-editor.types.ts +80 -0
  107. package/src/json-editor/json-editor.view.tsx +110 -0
  108. package/src/json-editor/json-text-area.tsx +7 -0
  109. package/src/kbd/index.ts +1 -0
  110. package/src/kbd/kbd.tsx +39 -0
  111. package/src/label/index.ts +1 -0
  112. package/src/label/label.tsx +28 -0
  113. package/src/menubar/index.ts +1 -0
  114. package/src/menubar/menubar.tsx +213 -0
  115. package/src/navigation-menu/index.ts +1 -0
  116. package/src/navigation-menu/navigation-menu.tsx +152 -0
  117. package/src/pagination/index.ts +2 -0
  118. package/src/pagination/pagination.tsx +191 -0
  119. package/src/pagination/pagination.types.ts +17 -0
  120. package/src/popover/index.ts +1 -0
  121. package/src/popover/popover.tsx +35 -0
  122. package/src/preview-panel/index.ts +3 -0
  123. package/src/preview-panel/preview-panel-dialog.tsx +99 -0
  124. package/src/preview-panel/preview-panel.tsx +389 -0
  125. package/src/preview-panel/preview-panel.types.ts +49 -0
  126. package/src/progress/index.ts +1 -0
  127. package/src/progress/progress.tsx +32 -0
  128. package/src/radio-group/index.ts +1 -0
  129. package/src/radio-group/radio-group.tsx +92 -0
  130. package/src/resizable/index.ts +1 -0
  131. package/src/resizable/resizable.tsx +52 -0
  132. package/src/scroll-area/index.ts +1 -0
  133. package/src/scroll-area/scroll-area.tsx +30 -0
  134. package/src/select/index.ts +1 -0
  135. package/src/select/select.tsx +138 -0
  136. package/src/separator/index.ts +1 -0
  137. package/src/separator/separator.tsx +28 -0
  138. package/src/sheet/index.ts +2 -0
  139. package/src/sheet/sheet.constants.tsx +20 -0
  140. package/src/sheet/sheet.tsx +92 -0
  141. package/src/sidebar/index.ts +4 -0
  142. package/src/sidebar/sidebar.constants.ts +30 -0
  143. package/src/sidebar/sidebar.hooks.ts +13 -0
  144. package/src/sidebar/sidebar.tsx +676 -0
  145. package/src/sidebar/sidebar.types.ts +28 -0
  146. package/src/skeleton/index.ts +1 -0
  147. package/src/skeleton/skeleton.tsx +22 -0
  148. package/src/slider/index.ts +1 -0
  149. package/src/slider/slider.tsx +57 -0
  150. package/src/sonner/index.ts +4 -0
  151. package/src/sonner/sonner.chunks.tsx +80 -0
  152. package/src/sonner/sonner.libs.ts +13 -0
  153. package/src/sonner/sonner.tsx +31 -0
  154. package/src/sonner/sonner.types.ts +9 -0
  155. package/src/switch/index.ts +1 -0
  156. package/src/switch/switch.tsx +63 -0
  157. package/src/table/index.ts +1 -0
  158. package/src/table/table.tsx +95 -0
  159. package/src/tabs/index.ts +1 -0
  160. package/src/tabs/tabs.tsx +151 -0
  161. package/src/textarea/index.ts +1 -0
  162. package/src/textarea/textarea.tsx +24 -0
  163. package/src/toggle/index.ts +2 -0
  164. package/src/toggle/toggle.constants.ts +22 -0
  165. package/src/toggle/toggle.tsx +24 -0
  166. package/src/toggle-group/index.ts +1 -0
  167. package/src/toggle-group/toggle-group.tsx +69 -0
  168. package/src/tooltip/index.ts +1 -0
  169. package/src/tooltip/tooltip.tsx +32 -0
  170. package/src/upload/index.ts +1 -0
  171. package/src/upload/upload.constants.tsx +19 -0
  172. package/src/upload/upload.libs.ts +97 -0
  173. package/src/upload/upload.tsx +340 -0
  174. package/src/upload/upload.types.ts +44 -0
  175. package/tsconfig.json +25 -0
@@ -0,0 +1,272 @@
1
+ // @ts-noCheck
2
+
3
+ import React from 'react'
4
+ import { Button, LabelType } from '../button'
5
+ import { ScrollArea } from '../scroll-area'
6
+ import { Table, TableBody } from './table'
7
+ import { sortArray } from './table.lib'
8
+
9
+ // ------------------------------------------------------------------------------------------------
10
+ // NOTE: These types are used for the `table-advanced` context.
11
+ // ------------------------------------------------------------------------------------------------
12
+
13
+ export interface DuckTableProviderProps<TColumnName extends string[]> extends React.HTMLAttributes<HTMLDivElement> {
14
+ table_columns: readonly TableColumnType[]
15
+ table_rows: TableContentDataType<TColumnName>[]
16
+ }
17
+
18
+ export type DuckTableContextType<TColumnName extends string[]> = {
19
+ tableColumns: Map<string, TableColumnType>
20
+ setTableColumns: React.Dispatch<React.SetStateAction<Map<string, TableColumnType>>>
21
+ tableRows: TableContentDataType<TColumnName>[]
22
+ selectedRows: Set<TableContentDataType<TColumnName>>
23
+ setSelectedRows: React.Dispatch<React.SetStateAction<Set<TableContentDataType<TColumnName>>>>
24
+ search: TableSearchStateType
25
+ setSearch: React.Dispatch<React.SetStateAction<TableSearchStateType>>
26
+ }
27
+
28
+ export type TableSortByStateType<TColumnName extends string[]> = {
29
+ label: TColumnName[number]
30
+ type: React.HTMLProps<HTMLDivElement>['aria-sort']
31
+ }
32
+
33
+ export interface TableSearchStateType {
34
+ query: string
35
+ queryBy: string[]
36
+ }
37
+
38
+ // ------------------------------------------------------------------------------------------------
39
+ // NOTE: These types are used for the `table-advanced` Components.
40
+ // ------------------------------------------------------------------------------------------------
41
+
42
+ /**
43
+ * Interface for the `DuckTable` component
44
+ */
45
+ export interface DuckTableProps extends React.ComponentPropsWithoutRef<typeof Table> {
46
+ wrapper?: React.ComponentPropsWithoutRef<typeof ScrollArea>
47
+ }
48
+
49
+ /**
50
+ * Interface for the `DuckTableHeader` component
51
+ */
52
+ export interface DuckTableHeaderProps {}
53
+
54
+ /**
55
+ * Interface for the `DuckTableHeadCheckbox` component
56
+ */
57
+ export interface DuckTableHeadCheckboxProps extends React.HTMLProps<HTMLDivElement> {}
58
+
59
+ /**
60
+ * Interface for the `DuckTableRowCheckbox` component
61
+ */
62
+ export interface DuckTableRowCheckboxProps<TColumnName extends readonly TableColumnType[]>
63
+ extends React.HTMLProps<HTMLDivElement> {
64
+ tableRow: TableContentDataType<GetColumnLabel<TColumnName>>
65
+ }
66
+
67
+ /**
68
+ * Interface for the `DuckTableHeadSelectable` component
69
+ */
70
+ export interface DuckTableHeadSelectableProps<TSort extends boolean = true> extends React.HTMLProps<HTMLDivElement> {
71
+ column: TableColumnType<TSort>
72
+ label: string
73
+ showLabel?: boolean | undefined
74
+ }
75
+
76
+ /**
77
+ * Interface for the `DuckTableBody` component
78
+ */
79
+ export interface DuckTableBodyProps extends React.ComponentPropsWithoutRef<typeof TableBody> {}
80
+
81
+ // ------------------------------------------------------------------------------------------------
82
+ // NOTE: These types are used for the `table-advanced, hence i use them to get the types.
83
+ // ------------------------------------------------------------------------------------------------
84
+
85
+ /**
86
+ * Extracts the `label` property from an array of `TableColumnType` objects
87
+ * and returns a tuple of string literals representing the column labels.
88
+ *
89
+ * ### Type Safety Guidelines:
90
+ * 1. Ensure the `columns` array is defined as `const` to preserve type inference.
91
+ * 2. Use `readonly TableColumnType[]` to enforce immutability and proper inference.
92
+ *
93
+ * #### Inferring Labels as a Union
94
+ * - Append `[number]` to the type to extract a union of possible labels.
95
+ * ```ts
96
+ * type ColumnLabel = GetColumnLabel<typeof columns>[number]; // 'Name' | 'Age' | 'Email'
97
+ * ```
98
+ *
99
+ * #### Defining Columns and Extracting Labels
100
+ * ```ts
101
+ * // Define columns as a strongly typed readonly array
102
+ * const columns = [
103
+ * { label: "Name" },
104
+ * { label: "Age" },
105
+ * { label: "Email" }
106
+ * ] as const satisfies readonly TableColumnType[];
107
+ *
108
+ * // Extract column labels as a tuple of string literals
109
+ * type ColumnLabels = GetColumnLabel<typeof columns>; // ['Name', 'Age', 'Email']
110
+ * ```
111
+ */
112
+ export type GetColumnLabel<TColumn extends readonly TableColumnType[]> = {
113
+ -readonly [K in keyof TColumn]: `${TColumn[K]['label']}`
114
+ }
115
+
116
+ /**
117
+ * Defines the column type for a table based on a dynamic set of column names.
118
+ *
119
+ * ### Type Safety Guidelines:
120
+ * 1. Define the columns array as `const` to infer the most precise type.
121
+ * 2. Ensure the type satisfies `readonly string[]` to preserve strict type checking.
122
+ *
123
+ * #### Inferring Column Names as a Union
124
+ * - Append `[number]` to the type to infer a union of possible column names.
125
+ * ```ts
126
+ * type ColumnName = TColumnName[number]; // Infers as a union of column names
127
+ * ```
128
+ *
129
+ * #### Defining Columns and Extracting Names
130
+ * ```ts
131
+ * // Define column names as a strongly typed readonly array
132
+ * const columnNames = ['name', 'age', 'email'] as const;
133
+ *
134
+ * // Extract column names as a union type
135
+ * type ColumnName = typeof columnNames[number]; // 'name' | 'age' | 'email'
136
+ * ```
137
+ *
138
+ * #### Example Usage
139
+ * ```ts
140
+ * type MyTableColumns = TableContentDataType<typeof columnNames>;
141
+ *
142
+ * const columns: MyTableColumns = {
143
+ * name: { label: "Full Name", children: "firstName", icon: { name: "user" } },
144
+ * age: { label: "Age", icon: { name: "calendar" } },
145
+ * email: { label: "Email Address" }
146
+ * };
147
+ * ```
148
+ */
149
+ export type TableContentDataType<TColumnName extends readonly string[]> = {
150
+ [key in TColumnName[number]]: TableColumnType & {
151
+ children?: TColumnName[number]
152
+ icon?: React.ReactNode
153
+ }
154
+ }
155
+
156
+ /**
157
+ * **Utility Type: Mutable**
158
+ * Converts all properties of a type `T` from readonly to mutable.
159
+ *
160
+ * @template T - The type to make mutable.
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * type ReadonlyUser = { readonly name: string; readonly age: number };
165
+ * type MutableUser = Mutable<ReadonlyUser>;
166
+ * // Result:
167
+ * // {
168
+ * // name: string;
169
+ * // age: number;
170
+ * // }
171
+ * ```
172
+ */
173
+ export type Mutable<T> = {
174
+ -readonly [K in keyof T]: T[K]
175
+ } & {}
176
+
177
+ /**
178
+ * **Utility Type: Immutable**
179
+ * Converts all properties of a type `T` from mutable to readonly.
180
+ *
181
+ * @template T - The type to make immutable.
182
+ *
183
+ * @example
184
+ * ```ts
185
+ * type User = { name: string; age: number };
186
+ * type ReadonlyUser = Immutable<User>;
187
+ * // Result:
188
+ * // {
189
+ * // readonly name: string;
190
+ * // readonly age: number;
191
+ * // }
192
+ * ```
193
+ */
194
+ export type Immutable<T> = {
195
+ readonly [K in keyof T]: T[K]
196
+ } & {}
197
+
198
+ /**
199
+ * **Utility Type: Mapped**
200
+ * A type that directly maps all keys of a given type `T` to themselves.
201
+ *
202
+ * @template T - The type to map.
203
+ *
204
+ * @example
205
+ * ```ts
206
+ * type User = { name: string; age: number };
207
+ * type MappedUser = Mapped<User>;
208
+ * // Result (Same as User):
209
+ * // {
210
+ * // name: string;
211
+ * // age: number;
212
+ * // }
213
+ * ```
214
+ */
215
+ export type Mapped<T> = {
216
+ [K in keyof T]: T[K]
217
+ } & {}
218
+
219
+ // ------------------------------------------------------------------------------------------------
220
+ // NOTE: These types are used for the `table-advanced, constants.
221
+ // ------------------------------------------------------------------------------------------------
222
+
223
+ export type TableColumnSortableType = React.ComponentPropsWithoutRef<typeof Button> & {
224
+ children: React.HTMLProps<HTMLDivElement>['aria-sort']
225
+ }
226
+
227
+ // ------------------------------------------------------------------------------------------------
228
+
229
+ export interface TableColumnType<TSort extends boolean = true> extends Partial<React.HTMLProps<HTMLTableCellElement>> {
230
+ label: string
231
+ sortable?: boolean
232
+ showLabel?: boolean
233
+ }
234
+
235
+ export interface TableDropdownMenuOptionsType<T extends boolean> {
236
+ sortArray: typeof sortArray
237
+ setHeaders: React.Dispatch<React.SetStateAction<TableColumnType[]>>
238
+ headers: TableColumnType[]
239
+ tableData: TableContentDataType<T>[]
240
+ setTableData: React.Dispatch<React.SetStateAction<TableContentDataType<T>[]>>
241
+ data: TableContentDataType<T>[]
242
+ idx: number
243
+ column: TableColumnType
244
+ }
245
+
246
+ export interface TableColumnType extends React.HTMLProps<HTMLTableCellElement> {
247
+ // TODO: clean up these legacy props
248
+ // FIX: make sure to use these in the future
249
+ withLabel?: Omit<LabelType, 'showCommand' | 'showLabel'>
250
+ withIcon?: React.ReactNode
251
+ }
252
+ // ------------------------------------------------------------------------------------------------
253
+ //NOTE: not used yet.
254
+ export type TableDataFilteredType<T extends Record<string, unknown>> = {
255
+ [K in keyof T]: [K, T[K]]
256
+ }[keyof T][]
257
+
258
+ export interface TablePaginationStateType {
259
+ pageSize: number
260
+ pageIndex: number
261
+ }
262
+
263
+ export interface TableSelectionStateType {
264
+ rowSelected: Record<string, unknown>[]
265
+ }
266
+
267
+ export type ColumnsViewedStateType<T extends Record<string, unknown>> = TableColumnType<T> | null
268
+
269
+ export type OrderStateType = {
270
+ orderBy: string
271
+ orderDir: 'asc' | 'desc'
272
+ }
@@ -0,0 +1,2 @@
1
+ export const PAGE_SIZE = 6
2
+ export const PAGE_INDEX = 0
@@ -0,0 +1,115 @@
1
+ // @ts-noCheck
2
+ import React from 'react'
3
+ import { DuckTableContext } from './table-advanced'
4
+ import { DuckTableContextType } from './table-advanced.types'
5
+
6
+ export const useDuckTable = <
7
+ Column extends Record<string, unknown> = Record<string, unknown>,
8
+ >(): DuckTableContextType<Column> | null => {
9
+ const context = React.useContext(DuckTableContext)
10
+ if (!context) {
11
+ throw new Error('useTableProvider must be used within an TableProvider')
12
+ }
13
+ return context
14
+ }
15
+
16
+ // <TableRow key={idx}>
17
+ // {tableDataFiltered.map(([key, value], idx) => {
18
+ // const headersEntries = headers.map(
19
+ // item => item.label.toString().toLowerCase() ?? item.children?.toString().toLowerCase()
20
+ // )
21
+ // const { className, children, withLabel, ...props } = value
22
+ // const {
23
+ // className: labelClassName,
24
+ // children: labelChildren,
25
+ // type: labelType = 'default',
26
+ // ...labelProps
27
+ // } = item?.[key]?.withLabel ?? {}
28
+ //
29
+ // return (
30
+ // headersEntries.includes(key.toString().toLowerCase()) && (
31
+ // <TableCell
32
+ // key={key}
33
+ // className={cn('py-2 h-[50px]', selected.includes(item) && 'bg-muted', className)}
34
+ // {...props}
35
+ // >
36
+ // <div
37
+ // className={cn(
38
+ // 'items-center gap-2 flex w-full',
39
+ // headers?.[idx]?.className,
40
+ // className,
41
+ // idx === headersEntries.length - 1 && dropdownMenu && 'justify-between w-full'
42
+ // )}
43
+ // >
44
+ // {/*NOTE: Rendering Checkbox */}
45
+ // {selection && idx === 0 && (
46
+ // <Checkbox
47
+ // className="border-border"
48
+ // onClick={() =>
49
+ // setSelected(
50
+ // selected.includes(item) ? selected.filter(i => i !== item) : [...selected, item]
51
+ // )
52
+ // }
53
+ // checked={selected.includes(item)}
54
+ // />
55
+ // )}
56
+ //
57
+ // {/*NOTE: Rendering Label */}
58
+ // {labelChildren && (
59
+ // <Badge
60
+ // variant={'outline'}
61
+ // size={'sm'}
62
+ // className={cn(labelType === 'default' ? '' : 'bg-red-500', labelClassName)}
63
+ // {...labelProps}
64
+ // >
65
+ // {labelChildren}
66
+ // </Badge>
67
+ // )}
68
+ //
69
+ // <div className="flex items-center gap-2 text-ellipsis overflow-hidden whitespace-nowrap">
70
+ // {/*NOTE: Getting Icons from Filter Data */}
71
+ // {filtersData?.length &&
72
+ // filtersData?.map(item => {
73
+ // return item?.content?.data.map((item, idx) => {
74
+ // const { children: Icon, ...props } = item?.element?.icon ?? {}
75
+ // return item.label?.toString().toLowerCase() ===
76
+ // (children as string).toString().toLowerCase() ? (
77
+ // <span
78
+ // className="whitespace-nowrap"
79
+ // key={idx}
80
+ // >
81
+ // {(Icon ? <Icon {...props} /> : '') as React.ReactNode}
82
+ // </span>
83
+ // ) : null
84
+ // })
85
+ // })}
86
+ //
87
+ // {/*NOTE: Rendering the row column childrend */}
88
+ // <span className="text-ellipsis overflow-hidden whitespace-nowrap">{children}</span>
89
+ // </div>
90
+ // {/*NOTE: Dropdown Menu */}
91
+ // {idx === headersEntries.length - 1 && dropdownMenu.optionsData?.length && (
92
+ // <DropdownMenuView
93
+ // trigger={{
94
+ // className: 'flex h-8 w-8 p-0 data-[state=open]:bg-muted',
95
+ // children: <span className="sr-only">Open menu</span>,
96
+ // variant: 'ghost',
97
+ // size: 'icon',
98
+ // icon: {
99
+ // children: Ellipsis,
100
+ // className: 'h-4 w-4',
101
+ // },
102
+ // }}
103
+ // content={{
104
+ // align: 'end',
105
+ // options: dropdownMenu,
106
+ // }}
107
+ // />
108
+ // )}
109
+ // </div>
110
+ // </TableCell>
111
+ // )
112
+ // )
113
+ // })}
114
+ // </TableRow>
115
+ //
@@ -0,0 +1,85 @@
1
+ // @ts-noCheck
2
+ import { DropdownMenuOptionsDataType } from '@/registry/default/ui/dropdown-menu'
3
+ import { Order, TableHeaderType } from './table.types'
4
+ import { ColumnsViewedStateType, TableContentDataType } from './table-advanced.types'
5
+
6
+ export function sortArray<T>(columns: TableHeaderType[], array: T[], key?: keyof T, order: Order = 'desc') {
7
+ const toggleSortOrder = (currentOrder: Order): Order => {
8
+ if (currentOrder === 'not sorted') return order
9
+ if (currentOrder === 'asc' && order === 'asc') return 'not sorted'
10
+ if (currentOrder === 'asc' && order === 'desc') return 'desc'
11
+ if (currentOrder === 'desc' && order === 'desc') return 'not sorted'
12
+ if (currentOrder === 'desc' && order === 'asc') return 'asc'
13
+ return 'not sorted'
14
+ }
15
+
16
+ const updatedColumns = columns.map((col) => {
17
+ if (col.label === key) {
18
+ return {
19
+ ...col,
20
+ currentSort: toggleSortOrder(col.currentSort ?? 'not sorted'),
21
+ }
22
+ }
23
+ return col
24
+ })
25
+
26
+ const sortedData = array.toSorted((a, b) => {
27
+ const valueA = key ? (a[key] as TableContentDataType).children : a
28
+ const valueB = key ? (b[key] as TableContentDataType).children : b
29
+
30
+ if (order === 'not sorted' || !key) return 0
31
+
32
+ if (typeof valueA === 'string' && typeof valueB === 'string') {
33
+ return order === 'asc' ? valueA.localeCompare(valueB) : valueB.localeCompare(valueA)
34
+ } else if (typeof valueA === 'number' && typeof valueB === 'number') {
35
+ return order === 'asc' ? valueA - valueB : valueB - valueA
36
+ } else {
37
+ return order === 'asc' ? (valueA > valueB ? 1 : -1) : valueA < valueB ? 1 : -1
38
+ }
39
+ })
40
+
41
+ return { sortedData, updatedColumns }
42
+ }
43
+
44
+ export type OptionsDataType<T extends Record<string, unknown>> = {
45
+ header: ColumnsViewedStateType<T>[]
46
+ columnsViewed?: ColumnsViewedStateType<T>[]
47
+ setColumnsViewed?: React.Dispatch<React.SetStateAction<ColumnsViewedStateType<T>[]>>
48
+ }
49
+
50
+ export function get_options_data<T extends Record<string, unknown> = Record<string, string>>({
51
+ header,
52
+ columnsViewed,
53
+ setColumnsViewed,
54
+ }: OptionsDataType<T>) {
55
+ return header.map((column, idx) => {
56
+ const { children, className, label, sortable, disabled, currentSort, dropdownMenuOptions, ...props } = column ?? {}
57
+
58
+ return {
59
+ checked: columnsViewed?.some((headerItem) => headerItem?.label === label),
60
+ children: label ?? children,
61
+ className: 'capitalize',
62
+ disabled: disabled,
63
+ key: idx,
64
+ onCheckedChange: () => {
65
+ setColumnsViewed?.((prevHeaders) => {
66
+ const exists = prevHeaders.some((headerItem) => headerItem?.label === label)
67
+
68
+ if (exists) {
69
+ return prevHeaders.filter((headerItem) => headerItem?.label !== label)
70
+ }
71
+
72
+ const originalIndex = header.findIndex((headerItem) => headerItem?.label === label)
73
+ const newHeaders = [...prevHeaders]
74
+ newHeaders.splice(originalIndex, 0, column)
75
+ return newHeaders.sort(
76
+ (a, b) =>
77
+ header.findIndex((headerItem) => headerItem?.label === a?.label) -
78
+ header.findIndex((headerItem) => headerItem?.label === b?.label),
79
+ )
80
+ })
81
+ },
82
+ ...props,
83
+ }
84
+ }) as DropdownMenuOptionsDataType<T>[]
85
+ }