@gentleduck/registry-ui 0.3.0 → 0.3.2
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.
- package/.turbo/turbo-test.log +19 -19
- package/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/SECURITY.md +19 -0
- package/bunfig.toml +2 -0
- package/package.json +12 -4
- package/src/calendar/calendar-day.tsx +131 -0
- package/src/calendar/calendar-header.tsx +291 -0
- package/src/calendar/calendar.tsx +195 -182
- package/src/calendar/calendar.types.ts +135 -0
- package/src/calendar/calendar.utils.ts +23 -0
- package/src/calendar/index.ts +2 -1
- package/src/sonner/sonner.chunks.tsx +0 -1
- package/tsconfig.json +1 -1
- package/src/_old/_table/index.ts +0 -14
- package/src/_old/_table/table-advanced.constants.tsx +0 -24
- package/src/_old/_table/table-advanced.tsx +0 -311
- package/src/_old/_table/table-advanced.types.ts +0 -272
- package/src/_old/_table/table.constants.ts +0 -2
- package/src/_old/_table/table.hook.tsx +0 -115
- package/src/_old/_table/table.lib.ts +0 -85
- package/src/_old/_table/table.tsx +0 -916
- package/src/_old/_table/table.types.ts +0 -118
- package/src/_old/_table/todo.md +0 -11
- package/src/_old/_upload/index.ts +0 -22
- package/src/_old/_upload/todo.md +0 -38
- package/src/_old/_upload/upload-advanced-chunks.tsx +0 -1624
- package/src/_old/_upload/upload-advanced.tsx +0 -507
- package/src/_old/_upload/upload-sonner.tsx +0 -58
- package/src/_old/_upload/upload.assets.tsx +0 -239
- package/src/_old/_upload/upload.constants.tsx +0 -75
- package/src/_old/_upload/upload.dto.ts +0 -19
- package/src/_old/_upload/upload.lib.tsx +0 -630
- package/src/_old/_upload/upload.tsx +0 -491
- package/src/_old/_upload/upload.types.ts +0 -436
|
@@ -1,916 +0,0 @@
|
|
|
1
|
-
// // @ts-noCheck
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// import { cn } from '@gentleduck/libs/cn'
|
|
5
|
-
// import { groupArrays } from '@gentleduck/libs/group-array'
|
|
6
|
-
// import { useDebounceCallback } from '@gentleduck/libs/use-debounce'
|
|
7
|
-
// import { CaretSortIcon, MixerHorizontalIcon } from '@radix-ui/react-icons'
|
|
8
|
-
// import { CirclePlus, LucideIcon } from 'lucide-react'
|
|
9
|
-
// import * as React from 'react'
|
|
10
|
-
// import { Badge } from '../badge'
|
|
11
|
-
// import { LabelType } from '../button'
|
|
12
|
-
// import { Combobox, type ComboboxType } from '../combobox'
|
|
13
|
-
// import { type CommandListGroupDataType, CommandShortcut } from '../command'
|
|
14
|
-
// import { ContextCustomView, DuckContextMenuProps } from '../context-menu'
|
|
15
|
-
// import { DropdownMenuView } from '../dropdown-menu'
|
|
16
|
-
// import { Input } from '../input'
|
|
17
|
-
// import { PaginationCustomView } from '../pagination'
|
|
18
|
-
// import { ScrollArea } from '../scroll-area'
|
|
19
|
-
// import { Separator } from '../separator'
|
|
20
|
-
// import {
|
|
21
|
-
// TooltipContent,
|
|
22
|
-
// TooltipProvider,
|
|
23
|
-
// TooltipTrigger,
|
|
24
|
-
// TooltipTrigger,
|
|
25
|
-
// } from '../tooltip'
|
|
26
|
-
// import { PAGE_INDEX, PAGE_SIZE } from './table.constants'
|
|
27
|
-
// import { useDuckTable } from './table.hook'
|
|
28
|
-
// import { get_options_data } from './table.lib'
|
|
29
|
-
// import { TableHeaderType, TablePaginationType } from './table.types'
|
|
30
|
-
//
|
|
31
|
-
// /*
|
|
32
|
-
// * - This's the normal table components.
|
|
33
|
-
// * It's a custom table component, you can use the dataTable Functionality down
|
|
34
|
-
// * this file to make sure you get the best performance, out of this table with
|
|
35
|
-
// * a more customized design.
|
|
36
|
-
// */
|
|
37
|
-
// const Table = React.forwardRef<
|
|
38
|
-
// HTMLTableElement,
|
|
39
|
-
// React.HTMLAttributes<HTMLTableElement>
|
|
40
|
-
// >(({ className, ...props }, ref) => (
|
|
41
|
-
// <div className='relative w-full overflow-auto'>
|
|
42
|
-
// <table
|
|
43
|
-
// className={cn('w-full caption-bottom text-sm', className)}
|
|
44
|
-
// ref={ref}
|
|
45
|
-
// {...props}
|
|
46
|
-
// />
|
|
47
|
-
// </div>
|
|
48
|
-
// ))
|
|
49
|
-
// Table.displayName = 'Table'
|
|
50
|
-
//
|
|
51
|
-
// const TableHeader = React.forwardRef<
|
|
52
|
-
// HTMLTableSectionElement,
|
|
53
|
-
// React.HTMLAttributes<HTMLTableSectionElement>
|
|
54
|
-
// >(({ className, ...props }, ref) => (
|
|
55
|
-
// <thead
|
|
56
|
-
// className={cn('[&_tr]:border-b', className)}
|
|
57
|
-
// ref={ref}
|
|
58
|
-
// {...props}
|
|
59
|
-
// />
|
|
60
|
-
// ))
|
|
61
|
-
// TableHeader.displayName = 'TableHeader'
|
|
62
|
-
//
|
|
63
|
-
// const TableBody = React.forwardRef<
|
|
64
|
-
// HTMLTableSectionElement,
|
|
65
|
-
// React.HTMLAttributes<HTMLTableSectionElement>
|
|
66
|
-
// >(({ className, ...props }, ref) => (
|
|
67
|
-
// <tbody
|
|
68
|
-
// className={cn('[&_tr:last-child]:border-0', className)}
|
|
69
|
-
// ref={ref}
|
|
70
|
-
// {...props}
|
|
71
|
-
// />
|
|
72
|
-
// ))
|
|
73
|
-
// TableBody.displayName = 'TableBody'
|
|
74
|
-
//
|
|
75
|
-
// const TableFooter = React.forwardRef<
|
|
76
|
-
// HTMLTableSectionElement,
|
|
77
|
-
// React.HTMLAttributes<HTMLTableSectionElement>
|
|
78
|
-
// >(({ className, ...props }, ref) => (
|
|
79
|
-
// <tfoot
|
|
80
|
-
// className={cn(
|
|
81
|
-
// 'border-t bg-muted/50 font-medium [&>tr]:last:border-b-0',
|
|
82
|
-
// className
|
|
83
|
-
// )}
|
|
84
|
-
// ref={ref}
|
|
85
|
-
// {...props}
|
|
86
|
-
// />
|
|
87
|
-
// ))
|
|
88
|
-
// TableFooter.displayName = 'TableFooter'
|
|
89
|
-
//
|
|
90
|
-
// const TableRow = React.forwardRef<
|
|
91
|
-
// HTMLTableRowElement,
|
|
92
|
-
// React.HTMLAttributes<HTMLTableRowElement>
|
|
93
|
-
// >(({ className, ...props }, ref) => (
|
|
94
|
-
// <tr
|
|
95
|
-
// className={cn(
|
|
96
|
-
// 'border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
|
|
97
|
-
// className
|
|
98
|
-
// )}
|
|
99
|
-
// ref={ref}
|
|
100
|
-
// {...props}
|
|
101
|
-
// />
|
|
102
|
-
// ))
|
|
103
|
-
// TableRow.displayName = 'TableRow'
|
|
104
|
-
//
|
|
105
|
-
// const TableHead = React.forwardRef<
|
|
106
|
-
// HTMLTableCellElement,
|
|
107
|
-
// React.ThHTMLAttributes<HTMLTableCellElement>
|
|
108
|
-
// >(({ className, ...props }, ref) => (
|
|
109
|
-
// <th
|
|
110
|
-
// className={cn(
|
|
111
|
-
// 'h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0',
|
|
112
|
-
// className
|
|
113
|
-
// )}
|
|
114
|
-
// ref={ref}
|
|
115
|
-
// {...props}
|
|
116
|
-
// />
|
|
117
|
-
// ))
|
|
118
|
-
// TableHead.displayName = 'TableHead'
|
|
119
|
-
//
|
|
120
|
-
// const TableCell = React.forwardRef<
|
|
121
|
-
// HTMLTableCellElement,
|
|
122
|
-
// React.TdHTMLAttributes<HTMLTableCellElement>
|
|
123
|
-
// >(({ className, ...props }, ref) => (
|
|
124
|
-
// <td
|
|
125
|
-
// className={cn('p-4 align-middle [&:has([role=checkbox])]:pr-0', className)}
|
|
126
|
-
// ref={ref}
|
|
127
|
-
// {...props}
|
|
128
|
-
// />
|
|
129
|
-
// ))
|
|
130
|
-
// TableCell.displayName = 'TableCell'
|
|
131
|
-
//
|
|
132
|
-
// const TableCaption = React.forwardRef<
|
|
133
|
-
// HTMLTableCaptionElement,
|
|
134
|
-
// React.HTMLAttributes<HTMLTableCaptionElement>
|
|
135
|
-
// >(({ className, ...props }, ref) => (
|
|
136
|
-
// <caption
|
|
137
|
-
// className={cn('mt-4 text-sm text-muted-foreground', className)}
|
|
138
|
-
// ref={ref}
|
|
139
|
-
// {...props}
|
|
140
|
-
// />
|
|
141
|
-
// ))
|
|
142
|
-
// TableCaption.displayName = 'TableCaption'
|
|
143
|
-
//
|
|
144
|
-
// export const DuckTableBar = ({
|
|
145
|
-
// children,
|
|
146
|
-
// className,
|
|
147
|
-
// ...props
|
|
148
|
-
// }: React.HTMLAttributes<HTMLDivElement>) => {
|
|
149
|
-
// return (
|
|
150
|
-
// <div
|
|
151
|
-
// className={cn(
|
|
152
|
-
// 'flex items-end lg:items-center justify-between gap-2',
|
|
153
|
-
// className
|
|
154
|
-
// )}
|
|
155
|
-
// {...props}
|
|
156
|
-
// >
|
|
157
|
-
// {children}
|
|
158
|
-
// </div>
|
|
159
|
-
// )
|
|
160
|
-
// }
|
|
161
|
-
//
|
|
162
|
-
// export interface DuckTableSearchProps extends React.HTMLProps<HTMLDivElement> {
|
|
163
|
-
// input?: DuckTableSearchInputProps
|
|
164
|
-
// }
|
|
165
|
-
//
|
|
166
|
-
// export const DuckTableSearch = ({
|
|
167
|
-
// children,
|
|
168
|
-
// className,
|
|
169
|
-
// input,
|
|
170
|
-
// ...props
|
|
171
|
-
// }: DuckTableSearchProps) => {
|
|
172
|
-
// const { setSearch } = useDuckTable() ?? {}
|
|
173
|
-
//
|
|
174
|
-
// //NOTE: Debounce search
|
|
175
|
-
// const debouncedSearch = useDebounceCallback(
|
|
176
|
-
// (newValue: string) => setSearch?.((_) => ({ query: newValue })),
|
|
177
|
-
// 500
|
|
178
|
-
// )
|
|
179
|
-
//
|
|
180
|
-
// return (
|
|
181
|
-
// <div
|
|
182
|
-
// className={cn('flex flex-1 items-center space-x-2', className)}
|
|
183
|
-
// {...props}
|
|
184
|
-
// >
|
|
185
|
-
// <DuckTableSearchInput
|
|
186
|
-
// {...input}
|
|
187
|
-
// trigger={{
|
|
188
|
-
// ...input?.trigger,
|
|
189
|
-
// onChange: (event: React.ChangeEvent<HTMLInputElement>) =>
|
|
190
|
-
// debouncedSearch(event.target.value),
|
|
191
|
-
// }}
|
|
192
|
-
// />
|
|
193
|
-
// </div>
|
|
194
|
-
// )
|
|
195
|
-
// }
|
|
196
|
-
//
|
|
197
|
-
// export interface DuckTableSearchInputProps {
|
|
198
|
-
// trigger: React.ComponentPropsWithoutRef<typeof Input>
|
|
199
|
-
// label?: LabelType
|
|
200
|
-
// badge?: React.ComponentPropsWithoutRef<typeof CommandShortcut>
|
|
201
|
-
// keys?: string[]
|
|
202
|
-
// }
|
|
203
|
-
//
|
|
204
|
-
// const DuckTableSearchInput = React.forwardRef<
|
|
205
|
-
// React.ComponentRef<typeof Input>,
|
|
206
|
-
// DuckTableSearchInputProps
|
|
207
|
-
// >(({ trigger, label, badge, keys }, ref) => {
|
|
208
|
-
// const {
|
|
209
|
-
// children: badgeChildren = 'Ctrl+Shift+F',
|
|
210
|
-
// className: badgeClassName,
|
|
211
|
-
// ...badgeProps
|
|
212
|
-
// } = badge ?? {}
|
|
213
|
-
// const {
|
|
214
|
-
// children: labelChildren = 'Filter tasks...',
|
|
215
|
-
// className: labelClassName,
|
|
216
|
-
// ...labelProps
|
|
217
|
-
// } = label ?? {}
|
|
218
|
-
// const {
|
|
219
|
-
// className: triggerClassName = 'h-8 w-[150px] lg:w-[200px]',
|
|
220
|
-
// placeholder = 'Filter tasks...',
|
|
221
|
-
// ...triggerProps
|
|
222
|
-
// } = trigger ?? {}
|
|
223
|
-
//
|
|
224
|
-
// //NOTE: Duck shortcut
|
|
225
|
-
// const inputRef = React.useRef<HTMLInputElement>(null)
|
|
226
|
-
// // useDuckShortcut(
|
|
227
|
-
// // {
|
|
228
|
-
// // keys: keys ?? ['ctrl+shift+f'],
|
|
229
|
-
// // onKeysPressed: () => {
|
|
230
|
-
// // if (inputRef.current) {
|
|
231
|
-
// // inputRef.current.focus()
|
|
232
|
-
// // }
|
|
233
|
-
// // },
|
|
234
|
-
// // },
|
|
235
|
-
// // [inputRef],
|
|
236
|
-
// // )
|
|
237
|
-
// //
|
|
238
|
-
//
|
|
239
|
-
// return (
|
|
240
|
-
// <div
|
|
241
|
-
// className='flex flex-col'
|
|
242
|
-
// ref={ref}
|
|
243
|
-
// >
|
|
244
|
-
// <TooltipTrigger delayDuration={100}>
|
|
245
|
-
// <TooltipTrigger>
|
|
246
|
-
// <Input
|
|
247
|
-
// className={cn('h-8 w-[150px] lg:w-[200px]', triggerClassName)}
|
|
248
|
-
// placeholder={placeholder}
|
|
249
|
-
// ref={inputRef}
|
|
250
|
-
// {...triggerProps}
|
|
251
|
-
// />
|
|
252
|
-
// </TooltipTrigger>
|
|
253
|
-
// <TooltipContent
|
|
254
|
-
// className={cn(
|
|
255
|
-
// 'flex items-center gap-2 z-50 justify-start',
|
|
256
|
-
// labelClassName
|
|
257
|
-
// )}
|
|
258
|
-
// {...labelProps}
|
|
259
|
-
// >
|
|
260
|
-
// <CommandShortcut
|
|
261
|
-
// className='text-[.8rem]'
|
|
262
|
-
// {...badgeProps}
|
|
263
|
-
// >
|
|
264
|
-
// <Badge
|
|
265
|
-
// className='p-0 px-2'
|
|
266
|
-
// size='sm'
|
|
267
|
-
// variant='secondary'
|
|
268
|
-
// >
|
|
269
|
-
// {badgeChildren}
|
|
270
|
-
// </Badge>
|
|
271
|
-
// </CommandShortcut>
|
|
272
|
-
// <p className='text-sm'>{labelChildren}</p>
|
|
273
|
-
// </TooltipContent>
|
|
274
|
-
// </TooltipTrigger>
|
|
275
|
-
// </div>
|
|
276
|
-
// )
|
|
277
|
-
// })
|
|
278
|
-
//
|
|
279
|
-
// export interface DuckTableFilterProps<
|
|
280
|
-
// T extends Record<string, any> = Record<string, string>,
|
|
281
|
-
// Y extends keyof Record<string, unknown> = string
|
|
282
|
-
// > extends React.HTMLProps<HTMLDivElement> {
|
|
283
|
-
// filter: ComboboxType<Y, Extract<keyof T, string>>[]
|
|
284
|
-
// }
|
|
285
|
-
//
|
|
286
|
-
// export const DuckTableFilter = <
|
|
287
|
-
// T extends Record<string, any> = Record<string, string>,
|
|
288
|
-
// Y extends keyof Record<string, unknown> = string
|
|
289
|
-
// >({
|
|
290
|
-
// children,
|
|
291
|
-
// filter,
|
|
292
|
-
// className,
|
|
293
|
-
// ...props
|
|
294
|
-
// }: DuckTableFilterProps<T, Y>) => {
|
|
295
|
-
// const { filterBy, setFilterBy } = useDuckTable() ?? {}
|
|
296
|
-
//
|
|
297
|
-
// return (
|
|
298
|
-
// <div
|
|
299
|
-
// className={cn('flex items-center gap-2', className)}
|
|
300
|
-
// {...props}
|
|
301
|
-
// >
|
|
302
|
-
// {filter?.map((filter, idx) => {
|
|
303
|
-
// const {
|
|
304
|
-
// className: triggerClassName,
|
|
305
|
-
// children: triggerChildren,
|
|
306
|
-
// ...triggerProps
|
|
307
|
-
// } = filter?.trigger ?? {}
|
|
308
|
-
// return (
|
|
309
|
-
// <Combobox<Y, Extract<keyof T, string>>
|
|
310
|
-
// content={{
|
|
311
|
-
// ...filter?.content!,
|
|
312
|
-
// }}
|
|
313
|
-
// key={idx}
|
|
314
|
-
// onSelect={
|
|
315
|
-
// filter?.onSelect ?? {
|
|
316
|
-
// setValue: setFilterBy as React.Dispatch<
|
|
317
|
-
// React.SetStateAction<Extract<keyof T, string>[]>
|
|
318
|
-
// >,
|
|
319
|
-
// value: filterBy as Extract<keyof T, string>[],
|
|
320
|
-
// }
|
|
321
|
-
// }
|
|
322
|
-
// title={filter?.title}
|
|
323
|
-
// trigger={{
|
|
324
|
-
// children: (triggerChildren ?? 'not found') as Y,
|
|
325
|
-
// className: cn('', triggerClassName),
|
|
326
|
-
// icon: { children: CirclePlus },
|
|
327
|
-
// size: 'sm',
|
|
328
|
-
// ...triggerProps,
|
|
329
|
-
// }}
|
|
330
|
-
// type={'listbox'}
|
|
331
|
-
// wrapper={filter?.wrapper}
|
|
332
|
-
// />
|
|
333
|
-
// )
|
|
334
|
-
// })}
|
|
335
|
-
// </div>
|
|
336
|
-
// )
|
|
337
|
-
// }
|
|
338
|
-
//
|
|
339
|
-
// export interface DuckTableBarRightSideProps
|
|
340
|
-
// extends React.HTMLProps<HTMLDivElement> { }
|
|
341
|
-
//
|
|
342
|
-
// export const DuckTableBarRightSide = React.forwardRef<
|
|
343
|
-
// HTMLDivElement,
|
|
344
|
-
// DuckTableBarRightSideProps
|
|
345
|
-
// >(({ className, children, ...props }, ref) => {
|
|
346
|
-
// return (
|
|
347
|
-
// <div
|
|
348
|
-
// className={cn(
|
|
349
|
-
// 'grid lg:flex items-center lg:justify-between gap-2',
|
|
350
|
-
// className
|
|
351
|
-
// )}
|
|
352
|
-
// ref={ref}
|
|
353
|
-
// {...props}
|
|
354
|
-
// >
|
|
355
|
-
// {children}
|
|
356
|
-
// </div>
|
|
357
|
-
// )
|
|
358
|
-
// })
|
|
359
|
-
//
|
|
360
|
-
// export interface DuckTableBarLeftSideProps
|
|
361
|
-
// extends React.HTMLProps<HTMLDivElement> { }
|
|
362
|
-
//
|
|
363
|
-
// export const DuckTableBarLeftSide = React.forwardRef<
|
|
364
|
-
// HTMLDivElement,
|
|
365
|
-
// DuckTableBarLeftSideProps
|
|
366
|
-
// >(({ className, children, ...props }, ref) => {
|
|
367
|
-
// return (
|
|
368
|
-
// <div
|
|
369
|
-
// className={cn(
|
|
370
|
-
// 'grid lg:flex items-center lg:justify-between gap-2',
|
|
371
|
-
// className
|
|
372
|
-
// )}
|
|
373
|
-
// ref={ref}
|
|
374
|
-
// {...props}
|
|
375
|
-
// >
|
|
376
|
-
// {children}
|
|
377
|
-
// </div>
|
|
378
|
-
// )
|
|
379
|
-
// })
|
|
380
|
-
//
|
|
381
|
-
// export interface DuckTableBarActionsProps<
|
|
382
|
-
// T extends Record<string, unknown>,
|
|
383
|
-
// C extends boolean
|
|
384
|
-
// > {
|
|
385
|
-
// header: TableHeaderType<T, C>[]
|
|
386
|
-
// }
|
|
387
|
-
//
|
|
388
|
-
// export const TableBarViewButton = <
|
|
389
|
-
// T extends Record<string, any> = Record<string, string>,
|
|
390
|
-
// C extends boolean = false
|
|
391
|
-
// >({
|
|
392
|
-
// header,
|
|
393
|
-
// }: DuckTableBarActionsProps<T, C>) => {
|
|
394
|
-
// const { setColumnsViewed, columnsViewed } = useDuckTable<T>() ?? {}
|
|
395
|
-
//
|
|
396
|
-
// const option_data = get_options_data<T>({
|
|
397
|
-
// columnsViewed,
|
|
398
|
-
// header,
|
|
399
|
-
// setColumnsViewed,
|
|
400
|
-
// })
|
|
401
|
-
//
|
|
402
|
-
// return (
|
|
403
|
-
// <>
|
|
404
|
-
// <DropdownMenuView
|
|
405
|
-
// content={{
|
|
406
|
-
// label: {
|
|
407
|
-
// children: 'Toggle columns',
|
|
408
|
-
// },
|
|
409
|
-
// options: {
|
|
410
|
-
// itemType: 'checkbox',
|
|
411
|
-
// optionsData: option_data,
|
|
412
|
-
// },
|
|
413
|
-
// }}
|
|
414
|
-
// trigger={{
|
|
415
|
-
// children: 'View',
|
|
416
|
-
// command: {
|
|
417
|
-
// key: 'ctrl+shift+v',
|
|
418
|
-
// label: 'Ctrl+Shift+V',
|
|
419
|
-
// },
|
|
420
|
-
// icon: {
|
|
421
|
-
// children: MixerHorizontalIcon as LucideIcon,
|
|
422
|
-
// },
|
|
423
|
-
// label: {
|
|
424
|
-
// children: 'Toggle columns',
|
|
425
|
-
// showCommand: true,
|
|
426
|
-
// showLabel: true,
|
|
427
|
-
// side: 'top',
|
|
428
|
-
// },
|
|
429
|
-
// size: 'sm',
|
|
430
|
-
// }}
|
|
431
|
-
// />
|
|
432
|
-
// </>
|
|
433
|
-
// )
|
|
434
|
-
// }
|
|
435
|
-
//
|
|
436
|
-
// export type TableBodyRowProps<T extends Record<string, unknown>> = {
|
|
437
|
-
// row?: React.ComponentPropsWithoutRef<typeof TableRow>
|
|
438
|
-
// } & Partial<DuckContextMenuProps<T>>
|
|
439
|
-
//
|
|
440
|
-
// export const DuckTableBodyRow = <C extends Record<string, unknown>>({
|
|
441
|
-
// wrapper,
|
|
442
|
-
// trigger,
|
|
443
|
-
// content,
|
|
444
|
-
// row,
|
|
445
|
-
// }: TableBodyRowProps<C>) => {
|
|
446
|
-
// const { children, ...props } = row ?? {}
|
|
447
|
-
// return (
|
|
448
|
-
// <ContextCustomView
|
|
449
|
-
// content={content}
|
|
450
|
-
// trigger={{
|
|
451
|
-
// ...trigger,
|
|
452
|
-
// children: (
|
|
453
|
-
// <TableRow {...props}>{children ?? trigger?.children}</TableRow>
|
|
454
|
-
// ),
|
|
455
|
-
// }}
|
|
456
|
-
// wrapper={wrapper}
|
|
457
|
-
// />
|
|
458
|
-
// )
|
|
459
|
-
// }
|
|
460
|
-
//
|
|
461
|
-
// export interface DuckTableFooterProps
|
|
462
|
-
// extends Partial<React.ComponentPropsWithoutRef<typeof TableFooter>> {
|
|
463
|
-
// columns: FooterColumnType[]
|
|
464
|
-
// }
|
|
465
|
-
// export type FooterColumnType = Partial<
|
|
466
|
-
// React.ComponentPropsWithoutRef<typeof TableCell>
|
|
467
|
-
// >
|
|
468
|
-
//
|
|
469
|
-
// export const DuckTableFooter = ({
|
|
470
|
-
// className,
|
|
471
|
-
// columns,
|
|
472
|
-
// }: DuckTableFooterProps) => {
|
|
473
|
-
// return (
|
|
474
|
-
// <TableFooter className={cn(className)}>
|
|
475
|
-
// <TableRow>
|
|
476
|
-
// {columns?.map((item, idx) => {
|
|
477
|
-
// const { children, ...props } = item
|
|
478
|
-
// return (
|
|
479
|
-
// <TableCell
|
|
480
|
-
// key={idx}
|
|
481
|
-
// {...props}
|
|
482
|
-
// >
|
|
483
|
-
// {children}
|
|
484
|
-
// </TableCell>
|
|
485
|
-
// )
|
|
486
|
-
// })}
|
|
487
|
-
// </TableRow>
|
|
488
|
-
// </TableFooter>
|
|
489
|
-
// )
|
|
490
|
-
// }
|
|
491
|
-
//
|
|
492
|
-
// export interface DuckTableDownBarProps
|
|
493
|
-
// extends React.HTMLProps<HTMLDivElement> { }
|
|
494
|
-
//
|
|
495
|
-
// export const DuckTableDownBar = ({
|
|
496
|
-
// children,
|
|
497
|
-
// className,
|
|
498
|
-
// ...props
|
|
499
|
-
// }: DuckTableDownBarProps) => {
|
|
500
|
-
// return (
|
|
501
|
-
// <>
|
|
502
|
-
// <Separator />
|
|
503
|
-
// <div
|
|
504
|
-
// className={cn(
|
|
505
|
-
// 'grid lg:flex items-center lg:justify-between gap-4 lg::gap-0',
|
|
506
|
-
// className
|
|
507
|
-
// )}
|
|
508
|
-
// {...props}
|
|
509
|
-
// >
|
|
510
|
-
// {children}
|
|
511
|
-
// </div>
|
|
512
|
-
// </>
|
|
513
|
-
// )
|
|
514
|
-
// }
|
|
515
|
-
// export type DuckTablePaginationProps = {}
|
|
516
|
-
//
|
|
517
|
-
// export const DuckTablePagination = ({ }: DuckTablePaginationProps) => {
|
|
518
|
-
// const { pagination, setPagination } = useDuckTable() ?? {}
|
|
519
|
-
// return (
|
|
520
|
-
// /*NOTE: Navigation */
|
|
521
|
-
// <PaginationCustomView
|
|
522
|
-
// left={{
|
|
523
|
-
// // onClick: () =>
|
|
524
|
-
// // setPaginationState({
|
|
525
|
-
// // ...paginationState,
|
|
526
|
-
// // activePage: paginationState.activePage === 0 ? 0 : (paginationState.activePage ?? 1) - 1,
|
|
527
|
-
// // }),
|
|
528
|
-
// // command: {
|
|
529
|
-
// // key: 'ctrl+shift+down',
|
|
530
|
-
// // label: 'Ctrl+Shift+Down',
|
|
531
|
-
// // action: () =>
|
|
532
|
-
// // setPaginationState({
|
|
533
|
-
// // ...paginationState,
|
|
534
|
-
// // activePage: paginationState.activePage === 0 ? 0 : (paginationState.activePage ?? 1) - 1,
|
|
535
|
-
// // }),
|
|
536
|
-
// // },
|
|
537
|
-
// label: {
|
|
538
|
-
// children: 'Previous page',
|
|
539
|
-
// showCommand: true,
|
|
540
|
-
// showLabel: true,
|
|
541
|
-
// side: 'top',
|
|
542
|
-
// },
|
|
543
|
-
// // disabled: paginationState.activePage === 0,
|
|
544
|
-
// }}
|
|
545
|
-
// maxLeft={{
|
|
546
|
-
// // onClick: () => setPaginationState({ ...paginationState, activePage: 0 }),
|
|
547
|
-
// // command: {
|
|
548
|
-
// // key: 'ctrl+shift+left',
|
|
549
|
-
// // label: 'Ctrl+Shift+Left',
|
|
550
|
-
// // action: () => setPaginationState({ ...paginationState, activePage: 0 }),
|
|
551
|
-
// // },
|
|
552
|
-
// label: {
|
|
553
|
-
// children: 'First page',
|
|
554
|
-
// showCommand: true,
|
|
555
|
-
// showLabel: true,
|
|
556
|
-
// side: 'top',
|
|
557
|
-
// },
|
|
558
|
-
// // disabled: paginationState.activePage === 0,
|
|
559
|
-
// }}
|
|
560
|
-
// maxRight={{
|
|
561
|
-
// // onClick: () => setPaginationState({ ...paginationState, activePage: resultArrays.length - 1 }),
|
|
562
|
-
// // command: {
|
|
563
|
-
// // key: 'ctrl+shift+right',
|
|
564
|
-
// // label: 'Ctrl+Shift+Right',
|
|
565
|
-
// // action: () => setPaginationState({ ...paginationState, activePage: resultArrays.length - 1 }),
|
|
566
|
-
// // },
|
|
567
|
-
// label: {
|
|
568
|
-
// children: 'Last page',
|
|
569
|
-
// showCommand: true,
|
|
570
|
-
// showLabel: true,
|
|
571
|
-
// side: 'top',
|
|
572
|
-
// },
|
|
573
|
-
// // disabled: paginationState.activePage === resultArrays.length - 1,
|
|
574
|
-
// }}
|
|
575
|
-
// right={{
|
|
576
|
-
// command: {
|
|
577
|
-
// key: 'ctrl+shift+up',
|
|
578
|
-
// label: 'Ctrl+Shift+Up',
|
|
579
|
-
// // action: () =>
|
|
580
|
-
// // setPaginationState({
|
|
581
|
-
// // ...paginationState,
|
|
582
|
-
// // activePage:
|
|
583
|
-
// // paginationState.activePage === resultArrays.length - 1
|
|
584
|
-
// // ? resultArrays.length - 1
|
|
585
|
-
// // : (paginationState.activePage ?? 1) + 1,
|
|
586
|
-
// // })
|
|
587
|
-
// // ,
|
|
588
|
-
// },
|
|
589
|
-
// label: {
|
|
590
|
-
// children: 'Next page',
|
|
591
|
-
// showCommand: true,
|
|
592
|
-
// showLabel: true,
|
|
593
|
-
// side: 'top',
|
|
594
|
-
// },
|
|
595
|
-
// onClick: () => {
|
|
596
|
-
// setPagination((old) => ({
|
|
597
|
-
// ...old,
|
|
598
|
-
// pageIndex:
|
|
599
|
-
// old.pageIndex === old.pageSize - 1
|
|
600
|
-
// ? old.pageSize - 1
|
|
601
|
-
// : (old.pageIndex ?? 1) + 1,
|
|
602
|
-
// }))
|
|
603
|
-
// },
|
|
604
|
-
// // disabled: paginationState.activePage === resultArrays.length - 1,
|
|
605
|
-
// }}
|
|
606
|
-
// />
|
|
607
|
-
// )
|
|
608
|
-
// }
|
|
609
|
-
//
|
|
610
|
-
// const TablePagination = <
|
|
611
|
-
// C extends Record<string, unknown> = Record<string, string>,
|
|
612
|
-
// Y extends keyof Record<string, unknown> = string
|
|
613
|
-
// >({
|
|
614
|
-
// resultArrays,
|
|
615
|
-
// selected,
|
|
616
|
-
// paginationState,
|
|
617
|
-
// paginations,
|
|
618
|
-
// value,
|
|
619
|
-
// tableData,
|
|
620
|
-
// setPaginationState,
|
|
621
|
-
// setValue,
|
|
622
|
-
// }: TablePaginationType<C>) => {
|
|
623
|
-
// //NOTE: gen the page length data
|
|
624
|
-
// const pageLengthData = paginations?.groupSize
|
|
625
|
-
// ? Array.from(
|
|
626
|
-
// { length: Math.ceil(tableData.length / paginations.groupSize) },
|
|
627
|
-
// (_, index) => {
|
|
628
|
-
// const start = index * paginations.groupSize + 1
|
|
629
|
-
// const end = Math.min(
|
|
630
|
-
// (index + 1) * paginations.groupSize,
|
|
631
|
-
// tableData.length
|
|
632
|
-
// )
|
|
633
|
-
// if (start > tableData.length) return null
|
|
634
|
-
// return end.toString()
|
|
635
|
-
// }
|
|
636
|
-
// )
|
|
637
|
-
// .filter(Boolean)
|
|
638
|
-
// .reduce((acc, curr) => {
|
|
639
|
-
// acc.push({ element: { children: curr! }, label: curr! })
|
|
640
|
-
// return acc
|
|
641
|
-
// }, [] as CommandListGroupDataType[])
|
|
642
|
-
// : []
|
|
643
|
-
//
|
|
644
|
-
// return (
|
|
645
|
-
// <>
|
|
646
|
-
// <div className='grid lg:flex items-center lg:justify-between gap-4 lg::gap-0'>
|
|
647
|
-
// <div className='flex items-center justify-between'>
|
|
648
|
-
// {/*NOTE: Select Count */}
|
|
649
|
-
// {paginations?.showSelectCount && (
|
|
650
|
-
// <span className='flex items-center justify-center text-sm font-medium text-muted-foreground whitespace-nowrap'>
|
|
651
|
-
// {selected.length} of {tableData.length} row(s) selected.
|
|
652
|
-
// </span>
|
|
653
|
-
// )}
|
|
654
|
-
// </div>
|
|
655
|
-
// <div className='flex items-center lg:justify-between lg:gap-4'>
|
|
656
|
-
// {/*NOTE: Group Size */}
|
|
657
|
-
// {paginations?.showGroup && (
|
|
658
|
-
// <div className='flex items-center gap-2'>
|
|
659
|
-
// <span className='max-2xl:hidden flex items-center justify-center text-sm font-medium text-muted-foreground whitespace-nowrap'>
|
|
660
|
-
// Rows per page
|
|
661
|
-
// </span>
|
|
662
|
-
// <TooltipProvider>
|
|
663
|
-
// <Combobox<Extract<keyof C, string>, Y>
|
|
664
|
-
// content={{
|
|
665
|
-
// className: 'w-[5rem] h-fit',
|
|
666
|
-
// data: (pageLengthData ??
|
|
667
|
-
// []) as CommandListGroupDataType<Y>[],
|
|
668
|
-
// showSearchInput: false,
|
|
669
|
-
// }}
|
|
670
|
-
// onSelect={{
|
|
671
|
-
// setValue: setValue as React.Dispatch<
|
|
672
|
-
// React.SetStateAction<Y[]>
|
|
673
|
-
// >,
|
|
674
|
-
// value: value as Y[],
|
|
675
|
-
// }}
|
|
676
|
-
// trigger={{
|
|
677
|
-
// className: 'w-[4.5rem] h-[32px] gap-0',
|
|
678
|
-
// command: {
|
|
679
|
-
// key: 'ctrl+shift+c',
|
|
680
|
-
// label: 'Ctrl+Shift+C',
|
|
681
|
-
// },
|
|
682
|
-
// label: {
|
|
683
|
-
// children: 'Rows per page',
|
|
684
|
-
// className: 'text-xs',
|
|
685
|
-
// showCommand: true,
|
|
686
|
-
// showLabel: true,
|
|
687
|
-
// side: 'top',
|
|
688
|
-
// },
|
|
689
|
-
// }}
|
|
690
|
-
// type='combobox'
|
|
691
|
-
// />
|
|
692
|
-
// </TooltipProvider>
|
|
693
|
-
// </div>
|
|
694
|
-
// )}
|
|
695
|
-
// {paginations?.showPageCount && (
|
|
696
|
-
// <span className='max-lg:hidden flex items-center justify-center text-sm font-medium text-muted-foreground whitespace-nowrap'>
|
|
697
|
-
// Page {paginationState.activePage + 1} of {resultArrays.length}
|
|
698
|
-
// </span>
|
|
699
|
-
// )}
|
|
700
|
-
// </div>
|
|
701
|
-
// </div>
|
|
702
|
-
// </>
|
|
703
|
-
// )
|
|
704
|
-
// }
|
|
705
|
-
//
|
|
706
|
-
// TablePagination.displayName = 'TablePagination'
|
|
707
|
-
//
|
|
708
|
-
// export type DuckTableBodyProps<T> = {
|
|
709
|
-
// data: T
|
|
710
|
-
// children: (data: T) => React.ReactNode
|
|
711
|
-
// }
|
|
712
|
-
//
|
|
713
|
-
// //NOTE: Function to split array into chunks
|
|
714
|
-
// const splitIntoChunks = <T,>(array: T[], chunkSize: number) => {
|
|
715
|
-
// const chunks = []
|
|
716
|
-
// for (let i = 0; i < array.length; i += chunkSize) {
|
|
717
|
-
// chunks.push(array.slice(i, i + chunkSize))
|
|
718
|
-
// }
|
|
719
|
-
// return chunks
|
|
720
|
-
// }
|
|
721
|
-
//
|
|
722
|
-
// export const DuckTableBody = <T,>({
|
|
723
|
-
// data,
|
|
724
|
-
// children,
|
|
725
|
-
// }: DuckTableBodyProps<T[]>) => {
|
|
726
|
-
// const { pagination, search, filterBy } = useDuckTable() ?? {}
|
|
727
|
-
// const tableDataGrouped = groupArrays<T>(
|
|
728
|
-
// [pagination?.pageSize ?? PAGE_SIZE],
|
|
729
|
-
// data
|
|
730
|
-
// )
|
|
731
|
-
// const pageIdx = pagination?.pageIndex ?? PAGE_INDEX
|
|
732
|
-
//
|
|
733
|
-
// // NOTE: Filter the items using the search query and filter keys.
|
|
734
|
-
// const filteredData = React.useMemo(() => {
|
|
735
|
-
// if (!tableDataGrouped[pageIdx]?.length) return []
|
|
736
|
-
//
|
|
737
|
-
// return tableDataGrouped[pageIdx]?.filter((item) => {
|
|
738
|
-
// const itemValues = Object.values(item as Record<string, unknown>).map(
|
|
739
|
-
// (value) => JSON.stringify(value).toLowerCase()
|
|
740
|
-
// )
|
|
741
|
-
//
|
|
742
|
-
// const matchesSearch = search?.query
|
|
743
|
-
// ? itemValues.some((value) => value.includes(search.query.toLowerCase()))
|
|
744
|
-
// : false
|
|
745
|
-
//
|
|
746
|
-
// const matchesFilterBy = filterBy?.length
|
|
747
|
-
// ? itemValues.some((value) =>
|
|
748
|
-
// filterBy.some((q) => value.includes(q.toLowerCase()))
|
|
749
|
-
// )
|
|
750
|
-
// : false
|
|
751
|
-
//
|
|
752
|
-
// return (
|
|
753
|
-
// (!search?.query && !filterBy?.length) ||
|
|
754
|
-
// matchesSearch ||
|
|
755
|
-
// matchesFilterBy
|
|
756
|
-
// )
|
|
757
|
-
// })
|
|
758
|
-
// }, [search, filterBy, tableDataGrouped, pageIdx])
|
|
759
|
-
//
|
|
760
|
-
// // NOTE: Split the data into chunks based on the group size.
|
|
761
|
-
// const resultArrays = React.useMemo(
|
|
762
|
-
// () => splitIntoChunks(filteredData, pagination?.pageSize ?? PAGE_SIZE),
|
|
763
|
-
// [filteredData, pagination?.pageSize]
|
|
764
|
-
// )
|
|
765
|
-
//
|
|
766
|
-
// console.log(filteredData)
|
|
767
|
-
//
|
|
768
|
-
// return (
|
|
769
|
-
// (resultArrays[pageIdx]?.length ?? 0 > 0) && (
|
|
770
|
-
// <TableBody>{children(resultArrays[pageIdx] as T[])}</TableBody>
|
|
771
|
-
// )
|
|
772
|
-
// )
|
|
773
|
-
// }
|
|
774
|
-
//
|
|
775
|
-
// export const EmptyTable = () => {
|
|
776
|
-
// return (
|
|
777
|
-
// <div className='w-full h-full flex items-center justify-center absolute top-1/2 left-1/2'>
|
|
778
|
-
// <h6 className='text-muted-foreground text-center'> No data </h6>
|
|
779
|
-
// </div>
|
|
780
|
-
// )
|
|
781
|
-
// }
|
|
782
|
-
//
|
|
783
|
-
// export interface DuckTableProps
|
|
784
|
-
// extends React.ComponentPropsWithoutRef<typeof Table> {
|
|
785
|
-
// wrapper?: React.ComponentPropsWithoutRef<typeof ScrollArea>
|
|
786
|
-
// }
|
|
787
|
-
//
|
|
788
|
-
// // const {children: captionChildren, className: captionClassName, ...captionProps } = caption! ?? []
|
|
789
|
-
// // const [selected, setSelected] = React.useState<TableContentDataType<C>[]>([])
|
|
790
|
-
// // const [tableData, setTableData] = React.useState<TableContentDataType<C>[]>(tableContentData)
|
|
791
|
-
// // const [paginationState, setPaginationState] = React.useState({
|
|
792
|
-
// // activePage: pagination?.activePage ?? 0,
|
|
793
|
-
// // groupSize: pagination?.groupSize ?? tableData.length,
|
|
794
|
-
// // })
|
|
795
|
-
// // const [headers, setHeaders] = React.useState<TableHeaderType<T, C>[]>(header ?? [])
|
|
796
|
-
// // const [search, setSearch] = React.useState<{ q: string; qBy: string[] }>({q: '', qBy: [] })
|
|
797
|
-
// // const [value, setValue] = React.useState<string[]>([paginationState.groupSize.toString()])
|
|
798
|
-
// //
|
|
799
|
-
// // const [filterLabels, setFilterLabels] = React.useState<{ [key: string]: number }>({})
|
|
800
|
-
// //
|
|
801
|
-
// // //NOTE: Function to split array into chunks
|
|
802
|
-
// // const splitIntoChunks = (array: typeof tableData, chunkSize: number) => {
|
|
803
|
-
// // const chunks = []
|
|
804
|
-
// // for (let i = 0; i < array.length; i += chunkSize) {
|
|
805
|
-
// // chunks.push(array.slice(i, i + chunkSize))
|
|
806
|
-
// // }
|
|
807
|
-
// // return chunks
|
|
808
|
-
// // }
|
|
809
|
-
// //
|
|
810
|
-
// // const filteredData = React.useMemo(() => {
|
|
811
|
-
// // //NOTE: Step 1: Filter the data based on search.q and search.qBy
|
|
812
|
-
// // const data = tableData.filter(item => {
|
|
813
|
-
// // return !search.qBy.length
|
|
814
|
-
// // ? Object.values(item).some(value => JSON.stringify(value).toLowerCase().includes(search.q.toLowerCase()))
|
|
815
|
-
// // : Object.values(item).some(value =>
|
|
816
|
-
// // search.qBy.some(q => JSON.stringify(value).toLowerCase().includes(q.toLowerCase()))
|
|
817
|
-
// // )
|
|
818
|
-
// // })
|
|
819
|
-
// //
|
|
820
|
-
// // //NOTE: Step 2: Calculate label counts based on the filtered data
|
|
821
|
-
// // const labelCounts: {[key: string]: number } = {}
|
|
822
|
-
// // data.forEach(item => {
|
|
823
|
-
// // Object.values(item).forEach(value => {
|
|
824
|
-
// // filters?.forEach(filter => {
|
|
825
|
-
// // filter?.content?.data.forEach(option => {
|
|
826
|
-
// // const label = option?.label?.toString().toLowerCase()
|
|
827
|
-
// // if (
|
|
828
|
-
// // JSON.stringify(value)
|
|
829
|
-
// // .toLowerCase()
|
|
830
|
-
// // .includes(label ?? '')
|
|
831
|
-
// // ) {
|
|
832
|
-
// // labelCounts[label ?? ''] = (labelCounts[label ?? ''] || 0) + 1
|
|
833
|
-
// // }
|
|
834
|
-
// // })
|
|
835
|
-
// // })
|
|
836
|
-
// // })
|
|
837
|
-
// // })
|
|
838
|
-
// //
|
|
839
|
-
// // setFilterLabels(labelCounts)
|
|
840
|
-
// //
|
|
841
|
-
// // return data
|
|
842
|
-
// // }, [tableData, filters, search])
|
|
843
|
-
// //
|
|
844
|
-
// // //NOTE: Step 3: Update the filters to display the count based on the filtered data
|
|
845
|
-
// // const updatedFilters = React.useMemo(() => {
|
|
846
|
-
// // return filters?.map(filter => {
|
|
847
|
-
// // return {
|
|
848
|
-
// // ...filter,
|
|
849
|
-
// // content: {
|
|
850
|
-
// // ...filter.content,
|
|
851
|
-
// // data: filter?.content?.data.map(option => {
|
|
852
|
-
// // const label = option?.label?.toString().toLowerCase()
|
|
853
|
-
// // return {
|
|
854
|
-
// // ...option,
|
|
855
|
-
// // element: {
|
|
856
|
-
// // ...option.element,
|
|
857
|
-
// // label: {
|
|
858
|
-
// // ...option?.element?.label,
|
|
859
|
-
// // children: filterLabels[label ?? ''] || 0,
|
|
860
|
-
// // },
|
|
861
|
-
// // },
|
|
862
|
-
// // }
|
|
863
|
-
// // }),
|
|
864
|
-
// // },
|
|
865
|
-
// // }
|
|
866
|
-
// // })
|
|
867
|
-
// // }, [filters, filterLabels])
|
|
868
|
-
// //
|
|
869
|
-
// // //NOTE: Step 4: Split the data into chunks based on the groupSize
|
|
870
|
-
// // const resultArrays = splitIntoChunks(filteredData, +value)
|
|
871
|
-
//
|
|
872
|
-
// // {tableData && !!resultArrays.length && (
|
|
873
|
-
// // <TableCustomBody<T, C, Y>
|
|
874
|
-
// // headers={headers}
|
|
875
|
-
// // resultArrays={resultArrays}
|
|
876
|
-
// // paginationState={paginationState}
|
|
877
|
-
// // selection={selection ?? false}
|
|
878
|
-
// // selected={selected}
|
|
879
|
-
// // filtersData={filters}
|
|
880
|
-
// // setSelected={setSelected}
|
|
881
|
-
// // dropdownMenu={dropdownMenu ?? {}}
|
|
882
|
-
// // contextMenu={contextMenu ?? {}}
|
|
883
|
-
// // />
|
|
884
|
-
// // )}
|
|
885
|
-
// // {footer?.columns && <TableCustomFooter {...footer} />}
|
|
886
|
-
// // {caption && (
|
|
887
|
-
// // <div
|
|
888
|
-
// // className={cn('mb-4 text-sm text-muted-foreground text-center', captionClassName)}
|
|
889
|
-
// // {...captionProps}
|
|
890
|
-
// // >
|
|
891
|
-
// // {caption?.children}
|
|
892
|
-
// // </div>
|
|
893
|
-
// // )}
|
|
894
|
-
// // {pagination && (
|
|
895
|
-
// // <TablePagination<C>
|
|
896
|
-
// // selected={selected}
|
|
897
|
-
// // value={value}
|
|
898
|
-
// // tableData={tableData}
|
|
899
|
-
// // resultArrays={resultArrays}
|
|
900
|
-
// // paginationState={paginationState}
|
|
901
|
-
// // paginations={pagination}
|
|
902
|
-
// // setValue={setValue}
|
|
903
|
-
// // setPaginationState={setPaginationState}
|
|
904
|
-
// // />
|
|
905
|
-
// // )}
|
|
906
|
-
//
|
|
907
|
-
// export {
|
|
908
|
-
// Table,
|
|
909
|
-
// TableHeader,
|
|
910
|
-
// TableBody,
|
|
911
|
-
// TableFooter,
|
|
912
|
-
// TableHead,
|
|
913
|
-
// TableRow,
|
|
914
|
-
// TableCell,
|
|
915
|
-
// TableCaption,
|
|
916
|
-
// }
|