@postxl/generators 1.1.1 → 1.2.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 (161) hide show
  1. package/dist/frontend-core/frontend.generator.d.ts +0 -58
  2. package/dist/frontend-core/frontend.generator.js +6 -172
  3. package/dist/frontend-core/frontend.generator.js.map +1 -1
  4. package/dist/frontend-core/template/README.md +1 -1
  5. package/dist/frontend-core/template/src/components/admin/table-filter.tsx +1 -5
  6. package/dist/frontend-core/template/src/components/ui/color-mode-toggle/color-mode-toggle.tsx +10 -4
  7. package/dist/frontend-core/template/src/pages/dashboard/dashboard.page.tsx +2 -3
  8. package/dist/frontend-core/template/src/pages/error/default-error.page.tsx +1 -1
  9. package/dist/frontend-core/template/src/pages/error/not-found-error.page.tsx +1 -1
  10. package/dist/frontend-core/template/src/styles/styles.css +13 -1
  11. package/dist/frontend-core/template/tsconfig.json +2 -0
  12. package/dist/frontend-core/types/component.d.ts +1 -1
  13. package/dist/frontend-forms/generators/discriminated-union/fields.generator.js +4 -6
  14. package/dist/frontend-forms/generators/discriminated-union/fields.generator.js.map +1 -1
  15. package/dist/frontend-forms/generators/discriminated-union/inputs.generator.js +1 -1
  16. package/dist/frontend-forms/generators/discriminated-union/inputs.generator.js.map +1 -1
  17. package/dist/frontend-forms/generators/enum/inputs.generator.js +1 -1
  18. package/dist/frontend-forms/generators/enum/inputs.generator.js.map +1 -1
  19. package/dist/frontend-forms/generators/model/forms.generator.js +8 -12
  20. package/dist/frontend-forms/generators/model/forms.generator.js.map +1 -1
  21. package/dist/frontend-forms/generators/model/inputs.generator.js +2 -6
  22. package/dist/frontend-forms/generators/model/inputs.generator.js.map +1 -1
  23. package/dist/frontend-forms/template/src/components/ui/field/field.tsx +1 -4
  24. package/dist/frontend-tables/generators/model-table.generator.js +1 -5
  25. package/dist/frontend-tables/generators/model-table.generator.js.map +1 -1
  26. package/package.json +3 -2
  27. package/dist/frontend-core/template/src/components/ui/accordion/accordion.stories.tsx +0 -47
  28. package/dist/frontend-core/template/src/components/ui/accordion/accordion.tsx +0 -52
  29. package/dist/frontend-core/template/src/components/ui/admin-sidebar/admin-sidebar.tsx +0 -195
  30. package/dist/frontend-core/template/src/components/ui/alert/alert.stories.tsx +0 -61
  31. package/dist/frontend-core/template/src/components/ui/alert/alert.tsx +0 -45
  32. package/dist/frontend-core/template/src/components/ui/alert-dialog/alert-dialog.stories.tsx +0 -52
  33. package/dist/frontend-core/template/src/components/ui/alert-dialog/alert-dialog.tsx +0 -105
  34. package/dist/frontend-core/template/src/components/ui/avatar/avatar.stories.tsx +0 -30
  35. package/dist/frontend-core/template/src/components/ui/avatar/avatar.tsx +0 -39
  36. package/dist/frontend-core/template/src/components/ui/badge/badge.stories.tsx +0 -78
  37. package/dist/frontend-core/template/src/components/ui/badge/badge.tsx +0 -48
  38. package/dist/frontend-core/template/src/components/ui/breadcrumb/breadcrumb.stories.tsx +0 -67
  39. package/dist/frontend-core/template/src/components/ui/breadcrumb/breadcrumb.tsx +0 -85
  40. package/dist/frontend-core/template/src/components/ui/button/button.stories.tsx +0 -150
  41. package/dist/frontend-core/template/src/components/ui/button/button.tsx +0 -68
  42. package/dist/frontend-core/template/src/components/ui/calendar/calendar.stories.tsx +0 -160
  43. package/dist/frontend-core/template/src/components/ui/calendar/calendar.tsx +0 -293
  44. package/dist/frontend-core/template/src/components/ui/card/card.stories.tsx +0 -77
  45. package/dist/frontend-core/template/src/components/ui/card/card.tsx +0 -45
  46. package/dist/frontend-core/template/src/components/ui/card-hover/card-hover.stories.tsx +0 -29
  47. package/dist/frontend-core/template/src/components/ui/card-hover/card-hover.tsx +0 -28
  48. package/dist/frontend-core/template/src/components/ui/carousel/carousel.stories.tsx +0 -154
  49. package/dist/frontend-core/template/src/components/ui/carousel/carousel.tsx +0 -227
  50. package/dist/frontend-core/template/src/components/ui/checkbox/checkbox.stories.tsx +0 -106
  51. package/dist/frontend-core/template/src/components/ui/checkbox/checkbox.tsx +0 -88
  52. package/dist/frontend-core/template/src/components/ui/checkbox/shadcn-checkbox.stories.tsx +0 -90
  53. package/dist/frontend-core/template/src/components/ui/checkbox/shadcn-checkbox.tsx +0 -54
  54. package/dist/frontend-core/template/src/components/ui/collapse/collapse.stories.tsx +0 -52
  55. package/dist/frontend-core/template/src/components/ui/collapse/collapse.tsx +0 -9
  56. package/dist/frontend-core/template/src/components/ui/combobox/combobox.stories.tsx +0 -207
  57. package/dist/frontend-core/template/src/components/ui/combobox/combobox.tsx +0 -79
  58. package/dist/frontend-core/template/src/components/ui/command/command.stories.tsx +0 -186
  59. package/dist/frontend-core/template/src/components/ui/command/command.tsx +0 -165
  60. package/dist/frontend-core/template/src/components/ui/command-palette/command-palette.stories.tsx +0 -160
  61. package/dist/frontend-core/template/src/components/ui/command-palette/command-palette.tsx +0 -134
  62. package/dist/frontend-core/template/src/components/ui/content-frame/content-frame.stories.tsx +0 -198
  63. package/dist/frontend-core/template/src/components/ui/content-frame/content-frame.tsx +0 -100
  64. package/dist/frontend-core/template/src/components/ui/context-menu/context-menu.stories.tsx +0 -78
  65. package/dist/frontend-core/template/src/components/ui/context-menu/context-menu.tsx +0 -179
  66. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/cell-variant-types.ts +0 -11
  67. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/checkbox-cell.tsx +0 -116
  68. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/date-cell.tsx +0 -157
  69. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/gantt-cell.tsx +0 -82
  70. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/long-text-cell.tsx +0 -180
  71. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/multi-select-cell.tsx +0 -280
  72. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/number-cell.tsx +0 -169
  73. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/react-node-cell.tsx +0 -33
  74. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/select-cell.tsx +0 -175
  75. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/short-text-cell.tsx +0 -138
  76. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/utils/gantt-timeline.tsx +0 -92
  77. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/utils/gantt-timerange-picker.tsx +0 -330
  78. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-cell-wrapper.tsx +0 -212
  79. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-cell.tsx +0 -157
  80. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-column-header.tsx +0 -340
  81. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-context-menu.tsx +0 -271
  82. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-row.tsx +0 -123
  83. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-search.tsx +0 -211
  84. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-types.ts +0 -159
  85. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-utils.ts +0 -67
  86. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-view-menu.tsx +0 -360
  87. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid.stories.tsx +0 -780
  88. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid.tsx +0 -217
  89. package/dist/frontend-core/template/src/components/ui/data-grid/hooks/use-callback-ref.ts +0 -22
  90. package/dist/frontend-core/template/src/components/ui/data-grid/hooks/use-data-grid.tsx +0 -1892
  91. package/dist/frontend-core/template/src/components/ui/data-grid/hooks/use-debounced-callback.ts +0 -19
  92. package/dist/frontend-core/template/src/components/ui/data-grid/styles.css +0 -3
  93. package/dist/frontend-core/template/src/components/ui/data-table/context-menu-simple.tsx +0 -141
  94. package/dist/frontend-core/template/src/components/ui/data-table/data-table.stories.tsx +0 -146
  95. package/dist/frontend-core/template/src/components/ui/data-table/data-table.tsx +0 -447
  96. package/dist/frontend-core/template/src/components/ui/data-table/renderers/country-array-cell-renderer.tsx +0 -77
  97. package/dist/frontend-core/template/src/components/ui/data-table/renderers/country-cell-renderer.tsx +0 -56
  98. package/dist/frontend-core/template/src/components/ui/data-table/renderers/favorite-cell-renderer.tsx +0 -68
  99. package/dist/frontend-core/template/src/components/ui/data-table/renderers/links-cell-renderer.tsx +0 -205
  100. package/dist/frontend-core/template/src/components/ui/data-table/utils/columns.ts +0 -351
  101. package/dist/frontend-core/template/src/components/ui/data-table/utils/data-table.utils.ts +0 -49
  102. package/dist/frontend-core/template/src/components/ui/date-picker/date-picker.stories.tsx +0 -149
  103. package/dist/frontend-core/template/src/components/ui/date-picker/date-picker.tsx +0 -30
  104. package/dist/frontend-core/template/src/components/ui/dialog/dialog.stories.tsx +0 -80
  105. package/dist/frontend-core/template/src/components/ui/dialog/dialog.tsx +0 -134
  106. package/dist/frontend-core/template/src/components/ui/drawer/drawer.stories.tsx +0 -104
  107. package/dist/frontend-core/template/src/components/ui/drawer/drawer.tsx +0 -87
  108. package/dist/frontend-core/template/src/components/ui/dropdown-menu/dropdown-menu.stories.tsx +0 -168
  109. package/dist/frontend-core/template/src/components/ui/dropdown-menu/dropdown-menu.tsx +0 -225
  110. package/dist/frontend-core/template/src/components/ui/input/input.stories.tsx +0 -141
  111. package/dist/frontend-core/template/src/components/ui/input/input.tsx +0 -47
  112. package/dist/frontend-core/template/src/components/ui/label/label.stories.tsx +0 -41
  113. package/dist/frontend-core/template/src/components/ui/label/label.tsx +0 -20
  114. package/dist/frontend-core/template/src/components/ui/loader/loader.stories.tsx +0 -45
  115. package/dist/frontend-core/template/src/components/ui/loader/loader.tsx +0 -17
  116. package/dist/frontend-core/template/src/components/ui/mark-value-renderer/mark-value-renderer.stories.tsx +0 -114
  117. package/dist/frontend-core/template/src/components/ui/mark-value-renderer/mark-value-renderer.tsx +0 -48
  118. package/dist/frontend-core/template/src/components/ui/menubar/menu.stories.tsx +0 -134
  119. package/dist/frontend-core/template/src/components/ui/menubar/menubar.tsx +0 -208
  120. package/dist/frontend-core/template/src/components/ui/modal/modal.stories.tsx +0 -297
  121. package/dist/frontend-core/template/src/components/ui/modal/modal.tsx +0 -80
  122. package/dist/frontend-core/template/src/components/ui/navigation-menu/navigation-menu.stories.tsx +0 -213
  123. package/dist/frontend-core/template/src/components/ui/navigation-menu/navigation-menu.tsx +0 -142
  124. package/dist/frontend-core/template/src/components/ui/pagination/pagination.stories.tsx +0 -49
  125. package/dist/frontend-core/template/src/components/ui/pagination/pagination.tsx +0 -84
  126. package/dist/frontend-core/template/src/components/ui/popover/popover.stories.tsx +0 -82
  127. package/dist/frontend-core/template/src/components/ui/popover/popover.tsx +0 -55
  128. package/dist/frontend-core/template/src/components/ui/progress/progress.stories.tsx +0 -80
  129. package/dist/frontend-core/template/src/components/ui/progress/progress.tsx +0 -17
  130. package/dist/frontend-core/template/src/components/ui/radio-group/radio-group.stories.tsx +0 -154
  131. package/dist/frontend-core/template/src/components/ui/radio-group/radio-group.tsx +0 -68
  132. package/dist/frontend-core/template/src/components/ui/resizable/resizable.stories.tsx +0 -73
  133. package/dist/frontend-core/template/src/components/ui/resizable/resizeable.tsx +0 -38
  134. package/dist/frontend-core/template/src/components/ui/scroll-area/scroll-area.stories.tsx +0 -55
  135. package/dist/frontend-core/template/src/components/ui/scroll-area/scroll-area.tsx +0 -39
  136. package/dist/frontend-core/template/src/components/ui/select/select.stories.tsx +0 -297
  137. package/dist/frontend-core/template/src/components/ui/select/select.tsx +0 -227
  138. package/dist/frontend-core/template/src/components/ui/separator/separator.tsx +0 -21
  139. package/dist/frontend-core/template/src/components/ui/separator/seperator.stories.tsx +0 -25
  140. package/dist/frontend-core/template/src/components/ui/sheet/sheet.stories.tsx +0 -45
  141. package/dist/frontend-core/template/src/components/ui/sheet/sheet.tsx +0 -107
  142. package/dist/frontend-core/template/src/components/ui/skeleton/skeleton.stories.tsx +0 -26
  143. package/dist/frontend-core/template/src/components/ui/skeleton/skeleton.tsx +0 -7
  144. package/dist/frontend-core/template/src/components/ui/slider/slider.stories.tsx +0 -101
  145. package/dist/frontend-core/template/src/components/ui/slider/slider.tsx +0 -98
  146. package/dist/frontend-core/template/src/components/ui/spinner/spinner.stories.tsx +0 -19
  147. package/dist/frontend-core/template/src/components/ui/spinner/spinner.tsx +0 -21
  148. package/dist/frontend-core/template/src/components/ui/switch/switch.stories.tsx +0 -33
  149. package/dist/frontend-core/template/src/components/ui/switch/switch.tsx +0 -28
  150. package/dist/frontend-core/template/src/components/ui/tabs/tabs.stories.tsx +0 -215
  151. package/dist/frontend-core/template/src/components/ui/tabs/tabs.tsx +0 -70
  152. package/dist/frontend-core/template/src/components/ui/textarea/textarea.stories.tsx +0 -138
  153. package/dist/frontend-core/template/src/components/ui/textarea/textarea.tsx +0 -40
  154. package/dist/frontend-core/template/src/components/ui/toast/toast.mdx +0 -31
  155. package/dist/frontend-core/template/src/components/ui/toast/toast.stories.tsx +0 -89
  156. package/dist/frontend-core/template/src/components/ui/toggle/toggle.stories.tsx +0 -65
  157. package/dist/frontend-core/template/src/components/ui/toggle/toggle.tsx +0 -38
  158. package/dist/frontend-core/template/src/components/ui/toggle-group/toggle-group.stories.tsx +0 -85
  159. package/dist/frontend-core/template/src/components/ui/toggle-group/toggle-group.tsx +0 -54
  160. package/dist/frontend-core/template/src/components/ui/tooltip/tooltip.stories.tsx +0 -29
  161. package/dist/frontend-core/template/src/components/ui/tooltip/tooltip.tsx +0 -29
@@ -1,123 +0,0 @@
1
- import { flexRender, type Row } from '@tanstack/react-table'
2
- import type { Virtualizer } from '@tanstack/react-virtual'
3
-
4
- import * as React from 'react'
5
-
6
- import type { CellPosition, RowHeightValue } from '@components/ui/data-grid/data-grid-types'
7
- import { getCommonPinningStyles, getLineCount } from '@components/ui/data-grid/data-grid-utils'
8
- import { useComposedRefs } from '@lib/compose-refs'
9
- import { cn } from '@lib/utils'
10
-
11
- type DataGridRowProps<TData> = {
12
- row: Row<TData>
13
- rowVirtualizer: Virtualizer<HTMLDivElement, Element>
14
- virtualRowIndex: number
15
- rowMapRef: React.RefObject<Map<number, HTMLDivElement>>
16
- rowHeight: RowHeightValue
17
- focusedCell: CellPosition | null
18
- } & React.ComponentProps<'div'>
19
-
20
- export const DataGridRow = React.memo(DataGridRowImpl, (prev, next) => {
21
- if (prev.row.id !== next.row.id) {
22
- return false
23
- }
24
-
25
- // Check if the actual row data has changed
26
- if (prev.row.original !== next.row.original) {
27
- return false
28
- }
29
-
30
- const prevRowIndex = prev.virtualRowIndex
31
- const nextRowIndex = next.virtualRowIndex
32
-
33
- const prevHasFocus = prev.focusedCell?.rowIndex === prevRowIndex
34
- const nextHasFocus = next.focusedCell?.rowIndex === nextRowIndex
35
-
36
- if (prevHasFocus !== nextHasFocus) {
37
- return false
38
- }
39
-
40
- if (nextHasFocus && prevHasFocus) {
41
- const prevFocusedCol = prev.focusedCell?.columnId
42
- const nextFocusedCol = next.focusedCell?.columnId
43
- if (prevFocusedCol !== nextFocusedCol) {
44
- return false
45
- }
46
- }
47
-
48
- return next.rowVirtualizer.isScrolling
49
- }) as typeof DataGridRowImpl
50
-
51
- function DataGridRowImpl<TData>({
52
- row,
53
- virtualRowIndex,
54
- rowVirtualizer,
55
- rowMapRef,
56
- rowHeight,
57
- focusedCell,
58
- ref,
59
- className,
60
- ...props
61
- }: DataGridRowProps<TData>) {
62
- const rowRef = useComposedRefs(ref, (node) => {
63
- if (node && typeof virtualRowIndex !== 'undefined') {
64
- rowVirtualizer.measureElement(node)
65
- rowMapRef.current.set(virtualRowIndex, node)
66
- }
67
- })
68
-
69
- const isRowSelected = row.getIsSelected()
70
-
71
- return (
72
- <div
73
- key={row.id}
74
- role="row"
75
- aria-rowindex={virtualRowIndex + 2}
76
- aria-selected={isRowSelected}
77
- data-index={virtualRowIndex}
78
- data-slot="grid-row"
79
- ref={rowRef}
80
- tabIndex={-1}
81
- className={cn(
82
- 'absolute flex w-full border-b h-[calc(var(--data-grid-line-height)*(var(--line-count))+12px)]',
83
- className,
84
- )}
85
- style={{ '--line-count': `${getLineCount(rowHeight)}` } as React.CSSProperties}
86
- {...props}
87
- >
88
- {row.getVisibleCells().map((cell, colIndex) => {
89
- const isCellFocused = focusedCell?.rowIndex === virtualRowIndex && focusedCell?.columnId === cell.column.id
90
-
91
- return (
92
- <div
93
- key={cell.id}
94
- role="gridcell"
95
- aria-colindex={colIndex + 1}
96
- data-highlighted={isCellFocused ? '' : undefined}
97
- data-slot="grid-cell"
98
- tabIndex={-1}
99
- className={cn({
100
- 'border-r': cell.column.id !== 'select',
101
- })}
102
- style={{
103
- ...getCommonPinningStyles({ column: cell.column }),
104
- width: `calc(var(--col-${cell.column.id}-size) * 1px)`,
105
- }}
106
- >
107
- {typeof cell.column.columnDef.header === 'function' ? (
108
- <div
109
- className={cn('size-full px-3 py-1.5', {
110
- 'bg-accent-foreground/10': isRowSelected,
111
- })}
112
- >
113
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
114
- </div>
115
- ) : (
116
- flexRender(cell.column.columnDef.cell, cell.getContext())
117
- )}
118
- </div>
119
- )
120
- })}
121
- </div>
122
- )
123
- }
@@ -1,211 +0,0 @@
1
- import { ChevronDownIcon, ChevronUpIcon, Cross2Icon } from '@radix-ui/react-icons'
2
-
3
- import * as React from 'react'
4
-
5
- import { Button } from '@components/ui/button/button'
6
- import type { SearchState } from '@components/ui/data-grid/data-grid-types'
7
- import { useDebouncedCallback } from '@components/ui/data-grid/hooks/use-debounced-callback'
8
- import { Input } from '@components/ui/input/input'
9
-
10
- type DataGridSearchProps = {} & SearchState
11
-
12
- export const DataGridSearch = React.memo(DataGridSearchImpl, (prev, next) => {
13
- if (prev.searchOpen !== next.searchOpen) {
14
- return false
15
- }
16
-
17
- if (!next.searchOpen) {
18
- return true
19
- }
20
-
21
- if (prev.searchQuery !== next.searchQuery || prev.matchIndex !== next.matchIndex) {
22
- return false
23
- }
24
-
25
- if (prev.searchMatches.length !== next.searchMatches.length) {
26
- return false
27
- }
28
-
29
- for (let i = 0; i < prev.searchMatches.length; i++) {
30
- const prevMatch = prev.searchMatches[i]
31
- const nextMatch = next.searchMatches[i]
32
-
33
- if (!prevMatch || !nextMatch) {
34
- return false
35
- }
36
-
37
- if (prevMatch.rowIndex !== nextMatch.rowIndex || prevMatch.columnId !== nextMatch.columnId) {
38
- return false
39
- }
40
- }
41
-
42
- return true
43
- })
44
-
45
- function DataGridSearchImpl({
46
- searchMatches,
47
- matchIndex,
48
- searchOpen,
49
- onSearchOpenChange,
50
- searchQuery,
51
- onSearchQueryChange,
52
- onSearch,
53
- onNavigateToNextMatch,
54
- onNavigateToPrevMatch,
55
- }: DataGridSearchProps) {
56
- const inputRef = React.useRef<HTMLInputElement>(null)
57
-
58
- React.useEffect(() => {
59
- if (searchOpen) {
60
- requestAnimationFrame(() => {
61
- inputRef.current?.focus()
62
- })
63
- }
64
- }, [searchOpen])
65
-
66
- React.useEffect(() => {
67
- if (!searchOpen) {
68
- return
69
- }
70
-
71
- function onEscape(event: KeyboardEvent) {
72
- if (event.key === 'Escape') {
73
- event.preventDefault()
74
- onSearchOpenChange(false)
75
- }
76
- }
77
-
78
- document.addEventListener('keydown', onEscape)
79
- return () => document.removeEventListener('keydown', onEscape)
80
- }, [searchOpen, onSearchOpenChange])
81
-
82
- const onKeyDown = React.useCallback(
83
- (event: React.KeyboardEvent) => {
84
- event.stopPropagation()
85
-
86
- if (event.key === 'Enter') {
87
- event.preventDefault()
88
- if (event.shiftKey) {
89
- onNavigateToPrevMatch()
90
- } else {
91
- onNavigateToNextMatch()
92
- }
93
- }
94
- },
95
- [onNavigateToNextMatch, onNavigateToPrevMatch],
96
- )
97
-
98
- const debouncedSearch = useDebouncedCallback((query: string) => {
99
- onSearch(query)
100
- }, 150)
101
-
102
- const onChange = React.useCallback(
103
- (event: React.ChangeEvent<HTMLInputElement>) => {
104
- const value = event.target.value
105
- onSearchQueryChange(value)
106
- debouncedSearch(value)
107
- },
108
- [onSearchQueryChange, debouncedSearch],
109
- )
110
-
111
- const onTriggerPointerDown = React.useCallback((event: React.PointerEvent<HTMLButtonElement>) => {
112
- // prevent implicit pointer capture
113
- const target = event.target
114
- if (!(target instanceof HTMLElement)) {
115
- return
116
- }
117
- if (target.hasPointerCapture(event.pointerId)) {
118
- target.releasePointerCapture(event.pointerId)
119
- }
120
-
121
- // Only prevent default if we're not clicking on the input
122
- // This allows text selection in the input while still preventing focus stealing elsewhere
123
- if (
124
- event.button === 0 &&
125
- event.ctrlKey === false &&
126
- event.pointerType === 'mouse' &&
127
- !(event.target instanceof HTMLInputElement)
128
- ) {
129
- event.preventDefault()
130
- }
131
- }, [])
132
-
133
- const onPrevMatchPointerDown = React.useCallback(
134
- (event: React.PointerEvent<HTMLButtonElement>) => onTriggerPointerDown(event),
135
- [onTriggerPointerDown],
136
- )
137
-
138
- const onNextMatchPointerDown = React.useCallback(
139
- (event: React.PointerEvent<HTMLButtonElement>) => onTriggerPointerDown(event),
140
- [onTriggerPointerDown],
141
- )
142
-
143
- const onClose = React.useCallback(() => {
144
- onSearchOpenChange(false)
145
- }, [onSearchOpenChange])
146
-
147
- if (!searchOpen) {
148
- return null
149
- }
150
-
151
- return (
152
- <div
153
- role="search"
154
- data-slot="grid-search"
155
- className="fade-in-0 slide-in-from-top-2 absolute top-4 right-4 z-50 flex animate-in flex-col gap-2 rounded-lg border border-border bg-background p-2 shadow-lg"
156
- >
157
- <div className="flex items-center gap-2">
158
- <Input
159
- autoComplete="off"
160
- autoCorrect="off"
161
- autoCapitalize="off"
162
- spellCheck={false}
163
- placeholder="Find in table..."
164
- className="h-8 w-64"
165
- ref={inputRef}
166
- value={searchQuery}
167
- onChange={onChange}
168
- onKeyDown={onKeyDown}
169
- />
170
- <div className="flex items-center gap-1">
171
- <Button
172
- aria-label="Previous match"
173
- variant="ghost"
174
- size="icon"
175
- className="size-7"
176
- onClick={onNavigateToPrevMatch}
177
- onPointerDown={onPrevMatchPointerDown}
178
- disabled={searchMatches.length === 0}
179
- >
180
- <ChevronUpIcon />
181
- </Button>
182
- <Button
183
- aria-label="Next match"
184
- variant="ghost"
185
- size="icon"
186
- className="size-7"
187
- onClick={onNavigateToNextMatch}
188
- onPointerDown={onNextMatchPointerDown}
189
- disabled={searchMatches.length === 0}
190
- >
191
- <ChevronDownIcon />
192
- </Button>
193
- <Button aria-label="Close search" variant="ghost" size="icon" className="size-7" onClick={onClose}>
194
- <Cross2Icon />
195
- </Button>
196
- </div>
197
- </div>
198
- <div className="flex items-center gap-1 whitespace-nowrap text-muted-foreground">
199
- {searchMatches.length > 0 ? (
200
- <span>
201
- {matchIndex + 1} of {searchMatches.length}
202
- </span>
203
- ) : searchQuery ? (
204
- <span>No results</span>
205
- ) : (
206
- <span>Type to search</span>
207
- )}
208
- </div>
209
- </div>
210
- )
211
- }
@@ -1,159 +0,0 @@
1
- import { Column, RowData } from '@tanstack/react-table'
2
-
3
- import { ISODateRange } from './cell-variants/utils/gantt-timerange-picker'
4
-
5
- export type RowHeightValue = 'short' | 'medium' | 'tall' | 'extra-tall'
6
-
7
- export type CellSelectOption = {
8
- label: string
9
- value: string
10
- }
11
-
12
- export type Cell =
13
- | {
14
- variant: 'short-text'
15
- }
16
- | {
17
- variant: 'long-text'
18
- }
19
- | {
20
- variant: 'number'
21
- min?: number
22
- max?: number
23
- step?: number
24
- prefix?: string
25
- suffix?: string
26
- fallbackValue?: string
27
- }
28
- | {
29
- variant: 'select'
30
- options: CellSelectOption[]
31
- hasSearch?: boolean
32
- }
33
- | {
34
- variant: 'multi-select'
35
- options: CellSelectOption[]
36
- }
37
- | {
38
- variant: 'checkbox'
39
- }
40
- | {
41
- variant: 'date'
42
- }
43
- | {
44
- variant: 'react-node'
45
- }
46
- | {
47
- variant: 'gantt'
48
- timelineStart: Date
49
- timelineEnd: Date
50
- dateRangeFrom?: Date
51
- dateRangeTo?: Date
52
- onRangeChange?: (values: ISODateRange | undefined) => void
53
- }
54
-
55
- export type UpdateCell = {
56
- rowIndex: number
57
- columnId: string
58
- value: unknown
59
- }
60
-
61
- export type ColumnMenuRendererFunction<TData extends RowData, TValue> = (args: {
62
- column: Column<TData, TValue>
63
- open?: boolean
64
- onOpenChange?: (open: boolean) => void
65
- }) => React.ReactNode
66
-
67
- declare module '@tanstack/react-table' {
68
- // biome-ignore lint/correctness/noUnusedVariables lint/correctness/noUnusedVariables: TData and TValue are used in the ColumnMeta interface
69
- // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
70
- interface ColumnMeta<TData extends RowData, TValue> {
71
- label?: string
72
- cell?: Cell
73
- align?: 'left' | 'right' | 'center'
74
- className?: string | ((row: TData) => string | undefined)
75
- editable?: boolean | ((row: TData) => boolean)
76
- headerMenuFooter?: React.ReactNode | ColumnMenuRendererFunction<TData, TValue>
77
- headerCustomComponent?: React.ReactNode | ColumnMenuRendererFunction<TData, TValue>
78
- }
79
- // biome-ignore lint/correctness/noUnusedVariables: TData is used in the TableMeta interface
80
- // eslint-disable-next-line @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-unused-vars
81
- interface TableMeta<TData extends RowData> {
82
- dataGridRef?: React.RefObject<HTMLElement | null>
83
- focusedCell?: CellPosition | null
84
- editingCell?: CellPosition | null
85
- selectionState?: SelectionState
86
- searchOpen?: boolean
87
- isScrolling?: boolean
88
- getIsCellSelected?: (rowIndex: number, columnId: string) => boolean
89
- getIsSearchMatch?: (rowIndex: number, columnId: string) => boolean
90
- getIsActiveSearchMatch?: (rowIndex: number, columnId: string) => boolean
91
- onDataUpdate?: (props: UpdateCell | UpdateCell[]) => void
92
- /**
93
- * Called for each individual cell update. Receives a single UpdateCell.
94
- * Use this to implement field-level updates (id + column + value).
95
- */
96
- onCellChange?: (update: UpdateCell) => void
97
- onRowsDelete?: (rowIndices: number[]) => void | Promise<void>
98
- onColumnClick?: (columnId: string) => void
99
- onCellClick?: (rowIndex: number, columnId: string, event?: React.MouseEvent) => void
100
- onCellDoubleClick?: (rowIndex: number, columnId: string) => void
101
- onCellMouseDown?: (rowIndex: number, columnId: string, event: React.MouseEvent) => void
102
- onCellMouseEnter?: (rowIndex: number, columnId: string, event: React.MouseEvent) => void
103
- onCellMouseUp?: () => void
104
- onCellContextMenu?: (rowIndex: number, columnId: string, event: React.MouseEvent) => void
105
- onCellEditingStart?: (rowIndex: number, columnId: string) => void
106
- onCellEditingStop?: (opts?: { direction?: NavigationDirection; moveToNextRow?: boolean }) => void
107
- contextMenu?: ContextMenuState
108
- onContextMenuOpenChange?: (open: boolean) => void
109
- rowHeight?: RowHeightValue
110
- onRowHeightChange?: (value: RowHeightValue) => void
111
- onRowSelect?: (rowIndex: number, checked: boolean, shiftKey: boolean) => void
112
- }
113
- }
114
-
115
- export type CellPosition = {
116
- rowIndex: number
117
- columnId: string
118
- }
119
-
120
- export type CellRange = {
121
- start: CellPosition
122
- end: CellPosition
123
- }
124
-
125
- export type SelectionState = {
126
- selectedCells: Set<string>
127
- selectionRange: CellRange | null
128
- isSelecting: boolean
129
- }
130
-
131
- export type ContextMenuState = {
132
- open: boolean
133
- x: number
134
- y: number
135
- }
136
-
137
- export type NavigationDirection =
138
- | 'up'
139
- | 'down'
140
- | 'left'
141
- | 'right'
142
- | 'home'
143
- | 'end'
144
- | 'ctrl+home'
145
- | 'ctrl+end'
146
- | 'pageup'
147
- | 'pagedown'
148
-
149
- export type SearchState = {
150
- searchMatches: CellPosition[]
151
- matchIndex: number
152
- searchOpen: boolean
153
- onSearchOpenChange: (open: boolean) => void
154
- searchQuery: string
155
- onSearchQueryChange: (query: string) => void
156
- onSearch: (query: string) => void
157
- onNavigateToNextMatch: () => void
158
- onNavigateToPrevMatch: () => void
159
- }
@@ -1,67 +0,0 @@
1
- import type { Column } from '@tanstack/react-table'
2
-
3
- import type { CellPosition, RowHeightValue } from '@components/ui/data-grid/data-grid-types'
4
-
5
- export function getCellKey(rowIndex: number, columnId: string) {
6
- return `${rowIndex}:${columnId}`
7
- }
8
-
9
- export function parseCellKey(cellKey: string): Required<CellPosition> {
10
- const parts = cellKey.split(':')
11
- const rowIndexStr = parts[0]
12
- const columnId = parts[1]
13
- if (rowIndexStr && columnId) {
14
- const rowIndex = parseInt(rowIndexStr, 10)
15
- if (!Number.isNaN(rowIndex)) {
16
- return { rowIndex, columnId }
17
- }
18
- }
19
- return { rowIndex: 0, columnId: '' }
20
- }
21
-
22
- export function getRowHeightValue(rowHeight: RowHeightValue): number {
23
- // TODO: Make lineHeight configurable / use css variable: --data-grid-line-height
24
- const lineHeight = 16
25
-
26
- return lineHeight * getLineCount(rowHeight) + 12
27
- }
28
-
29
- export function getLineCount(rowHeight: RowHeightValue): number {
30
- const lineCountMap: Record<RowHeightValue, number> = {
31
- short: 1,
32
- medium: 2,
33
- tall: 3,
34
- 'extra-tall': 4,
35
- }
36
-
37
- return lineCountMap[rowHeight]
38
- }
39
-
40
- export function getCommonPinningStyles<TData>({
41
- column,
42
- withBorder = false,
43
- }: {
44
- column: Column<TData>
45
- withBorder?: boolean
46
- }): React.CSSProperties {
47
- const isPinned = column.getIsPinned()
48
- const isLastLeftPinnedColumn = isPinned === 'left' && column.getIsLastColumn('left')
49
- const isFirstRightPinnedColumn = isPinned === 'right' && column.getIsFirstColumn('right')
50
-
51
- return {
52
- boxShadow: withBorder
53
- ? isLastLeftPinnedColumn
54
- ? '-4px 0 4px var(--border) inset'
55
- : isFirstRightPinnedColumn
56
- ? '4px 0 -4px var(--border) inset'
57
- : undefined
58
- : undefined,
59
- left: isPinned === 'left' ? `${column.getStart('left')}px` : undefined,
60
- right: isPinned === 'right' ? `${column.getAfter('right')}px` : undefined,
61
- opacity: isPinned ? 0.97 : 1,
62
- position: isPinned ? 'sticky' : 'relative',
63
- background: isPinned ? 'var(--background)' : 'var(--background)',
64
- width: column.getSize(),
65
- zIndex: isPinned ? 1 : undefined,
66
- }
67
- }