@postxl/generators 1.1.1 → 1.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 (181) hide show
  1. package/dist/backend-core/backend.generator.js +4 -1
  2. package/dist/backend-core/backend.generator.js.map +1 -1
  3. package/dist/backend-core/generators/jest.config.generator.d.ts +2 -0
  4. package/dist/backend-core/{template/jest.config.ts → generators/jest.config.generator.js} +12 -8
  5. package/dist/backend-core/generators/jest.config.generator.js.map +1 -0
  6. package/dist/backend-core/generators/tsconfig.generator.d.ts +1 -1
  7. package/dist/backend-core/generators/tsconfig.generator.js +1 -9
  8. package/dist/backend-core/generators/tsconfig.generator.js.map +1 -1
  9. package/dist/backend-core/types.d.ts +2 -0
  10. package/dist/base/base.generator.js +12 -8
  11. package/dist/base/base.generator.js.map +1 -1
  12. package/dist/e2e/template/e2e/package.json +1 -1
  13. package/dist/e2e/template/e2e/specs/example.spec.ts +1 -1
  14. package/dist/e2e/template/e2e/specs/example.spec.ts-snapshots/Navigate-to-homepage-and-take-snapshot-1-chromium-linux.png +0 -0
  15. package/dist/frontend-core/frontend.generator.d.ts +0 -58
  16. package/dist/frontend-core/frontend.generator.js +9 -173
  17. package/dist/frontend-core/frontend.generator.js.map +1 -1
  18. package/dist/frontend-core/generators/tsconfig.generator.js +2 -0
  19. package/dist/frontend-core/generators/tsconfig.generator.js.map +1 -1
  20. package/dist/frontend-core/template/README.md +1 -1
  21. package/dist/frontend-core/template/src/components/admin/table-filter.tsx +1 -5
  22. package/dist/frontend-core/template/src/components/ui/color-mode-toggle/color-mode-toggle.tsx +10 -4
  23. package/dist/frontend-core/template/src/lib/query-client.ts +45 -4
  24. package/dist/frontend-core/template/src/pages/dashboard/dashboard.page.tsx +2 -3
  25. package/dist/frontend-core/template/src/pages/error/default-error.page.tsx +45 -12
  26. package/dist/frontend-core/template/src/pages/error/not-found-error.page.tsx +1 -1
  27. package/dist/frontend-core/template/src/styles/styles.css +13 -1
  28. package/dist/frontend-core/template/tsconfig.json +2 -0
  29. package/dist/frontend-core/types/component.d.ts +1 -1
  30. package/dist/frontend-forms/generators/discriminated-union/fields.generator.js +4 -6
  31. package/dist/frontend-forms/generators/discriminated-union/fields.generator.js.map +1 -1
  32. package/dist/frontend-forms/generators/discriminated-union/inputs.generator.js +1 -1
  33. package/dist/frontend-forms/generators/discriminated-union/inputs.generator.js.map +1 -1
  34. package/dist/frontend-forms/generators/enum/inputs.generator.js +1 -1
  35. package/dist/frontend-forms/generators/enum/inputs.generator.js.map +1 -1
  36. package/dist/frontend-forms/generators/model/forms.generator.js +8 -12
  37. package/dist/frontend-forms/generators/model/forms.generator.js.map +1 -1
  38. package/dist/frontend-forms/generators/model/inputs.generator.js +2 -6
  39. package/dist/frontend-forms/generators/model/inputs.generator.js.map +1 -1
  40. package/dist/frontend-forms/template/src/components/ui/field/field.tsx +1 -4
  41. package/dist/frontend-tables/generators/model-table.generator.js +1 -5
  42. package/dist/frontend-tables/generators/model-table.generator.js.map +1 -1
  43. package/package.json +4 -3
  44. package/dist/e2e/generators/package-json.generator.d.ts +0 -2
  45. package/dist/e2e/generators/package-json.generator.js +0 -29
  46. package/dist/e2e/generators/package-json.generator.js.map +0 -1
  47. package/dist/frontend-core/template/src/components/ui/accordion/accordion.stories.tsx +0 -47
  48. package/dist/frontend-core/template/src/components/ui/accordion/accordion.tsx +0 -52
  49. package/dist/frontend-core/template/src/components/ui/admin-sidebar/admin-sidebar.tsx +0 -195
  50. package/dist/frontend-core/template/src/components/ui/alert/alert.stories.tsx +0 -61
  51. package/dist/frontend-core/template/src/components/ui/alert/alert.tsx +0 -45
  52. package/dist/frontend-core/template/src/components/ui/alert-dialog/alert-dialog.stories.tsx +0 -52
  53. package/dist/frontend-core/template/src/components/ui/alert-dialog/alert-dialog.tsx +0 -105
  54. package/dist/frontend-core/template/src/components/ui/avatar/avatar.stories.tsx +0 -30
  55. package/dist/frontend-core/template/src/components/ui/avatar/avatar.tsx +0 -39
  56. package/dist/frontend-core/template/src/components/ui/badge/badge.stories.tsx +0 -78
  57. package/dist/frontend-core/template/src/components/ui/badge/badge.tsx +0 -48
  58. package/dist/frontend-core/template/src/components/ui/breadcrumb/breadcrumb.stories.tsx +0 -67
  59. package/dist/frontend-core/template/src/components/ui/breadcrumb/breadcrumb.tsx +0 -85
  60. package/dist/frontend-core/template/src/components/ui/button/button.stories.tsx +0 -150
  61. package/dist/frontend-core/template/src/components/ui/button/button.tsx +0 -68
  62. package/dist/frontend-core/template/src/components/ui/calendar/calendar.stories.tsx +0 -160
  63. package/dist/frontend-core/template/src/components/ui/calendar/calendar.tsx +0 -293
  64. package/dist/frontend-core/template/src/components/ui/card/card.stories.tsx +0 -77
  65. package/dist/frontend-core/template/src/components/ui/card/card.tsx +0 -45
  66. package/dist/frontend-core/template/src/components/ui/card-hover/card-hover.stories.tsx +0 -29
  67. package/dist/frontend-core/template/src/components/ui/card-hover/card-hover.tsx +0 -28
  68. package/dist/frontend-core/template/src/components/ui/carousel/carousel.stories.tsx +0 -154
  69. package/dist/frontend-core/template/src/components/ui/carousel/carousel.tsx +0 -227
  70. package/dist/frontend-core/template/src/components/ui/checkbox/checkbox.stories.tsx +0 -106
  71. package/dist/frontend-core/template/src/components/ui/checkbox/checkbox.tsx +0 -88
  72. package/dist/frontend-core/template/src/components/ui/checkbox/shadcn-checkbox.stories.tsx +0 -90
  73. package/dist/frontend-core/template/src/components/ui/checkbox/shadcn-checkbox.tsx +0 -54
  74. package/dist/frontend-core/template/src/components/ui/collapse/collapse.stories.tsx +0 -52
  75. package/dist/frontend-core/template/src/components/ui/collapse/collapse.tsx +0 -9
  76. package/dist/frontend-core/template/src/components/ui/combobox/combobox.stories.tsx +0 -207
  77. package/dist/frontend-core/template/src/components/ui/combobox/combobox.tsx +0 -79
  78. package/dist/frontend-core/template/src/components/ui/command/command.stories.tsx +0 -186
  79. package/dist/frontend-core/template/src/components/ui/command/command.tsx +0 -165
  80. package/dist/frontend-core/template/src/components/ui/command-palette/command-palette.stories.tsx +0 -160
  81. package/dist/frontend-core/template/src/components/ui/command-palette/command-palette.tsx +0 -134
  82. package/dist/frontend-core/template/src/components/ui/content-frame/content-frame.stories.tsx +0 -198
  83. package/dist/frontend-core/template/src/components/ui/content-frame/content-frame.tsx +0 -100
  84. package/dist/frontend-core/template/src/components/ui/context-menu/context-menu.stories.tsx +0 -78
  85. package/dist/frontend-core/template/src/components/ui/context-menu/context-menu.tsx +0 -179
  86. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/cell-variant-types.ts +0 -11
  87. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/checkbox-cell.tsx +0 -116
  88. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/date-cell.tsx +0 -157
  89. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/gantt-cell.tsx +0 -82
  90. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/long-text-cell.tsx +0 -180
  91. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/multi-select-cell.tsx +0 -280
  92. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/number-cell.tsx +0 -169
  93. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/react-node-cell.tsx +0 -33
  94. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/select-cell.tsx +0 -175
  95. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/short-text-cell.tsx +0 -138
  96. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/utils/gantt-timeline.tsx +0 -92
  97. package/dist/frontend-core/template/src/components/ui/data-grid/cell-variants/utils/gantt-timerange-picker.tsx +0 -330
  98. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-cell-wrapper.tsx +0 -212
  99. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-cell.tsx +0 -157
  100. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-column-header.tsx +0 -340
  101. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-context-menu.tsx +0 -271
  102. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-row.tsx +0 -123
  103. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-search.tsx +0 -211
  104. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-types.ts +0 -159
  105. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-utils.ts +0 -67
  106. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid-view-menu.tsx +0 -360
  107. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid.stories.tsx +0 -780
  108. package/dist/frontend-core/template/src/components/ui/data-grid/data-grid.tsx +0 -217
  109. package/dist/frontend-core/template/src/components/ui/data-grid/hooks/use-callback-ref.ts +0 -22
  110. package/dist/frontend-core/template/src/components/ui/data-grid/hooks/use-data-grid.tsx +0 -1892
  111. package/dist/frontend-core/template/src/components/ui/data-grid/hooks/use-debounced-callback.ts +0 -19
  112. package/dist/frontend-core/template/src/components/ui/data-grid/styles.css +0 -3
  113. package/dist/frontend-core/template/src/components/ui/data-table/context-menu-simple.tsx +0 -141
  114. package/dist/frontend-core/template/src/components/ui/data-table/data-table.stories.tsx +0 -146
  115. package/dist/frontend-core/template/src/components/ui/data-table/data-table.tsx +0 -447
  116. package/dist/frontend-core/template/src/components/ui/data-table/renderers/country-array-cell-renderer.tsx +0 -77
  117. package/dist/frontend-core/template/src/components/ui/data-table/renderers/country-cell-renderer.tsx +0 -56
  118. package/dist/frontend-core/template/src/components/ui/data-table/renderers/favorite-cell-renderer.tsx +0 -68
  119. package/dist/frontend-core/template/src/components/ui/data-table/renderers/links-cell-renderer.tsx +0 -205
  120. package/dist/frontend-core/template/src/components/ui/data-table/utils/columns.ts +0 -351
  121. package/dist/frontend-core/template/src/components/ui/data-table/utils/data-table.utils.ts +0 -49
  122. package/dist/frontend-core/template/src/components/ui/date-picker/date-picker.stories.tsx +0 -149
  123. package/dist/frontend-core/template/src/components/ui/date-picker/date-picker.tsx +0 -30
  124. package/dist/frontend-core/template/src/components/ui/dialog/dialog.stories.tsx +0 -80
  125. package/dist/frontend-core/template/src/components/ui/dialog/dialog.tsx +0 -134
  126. package/dist/frontend-core/template/src/components/ui/drawer/drawer.stories.tsx +0 -104
  127. package/dist/frontend-core/template/src/components/ui/drawer/drawer.tsx +0 -87
  128. package/dist/frontend-core/template/src/components/ui/dropdown-menu/dropdown-menu.stories.tsx +0 -168
  129. package/dist/frontend-core/template/src/components/ui/dropdown-menu/dropdown-menu.tsx +0 -225
  130. package/dist/frontend-core/template/src/components/ui/input/input.stories.tsx +0 -141
  131. package/dist/frontend-core/template/src/components/ui/input/input.tsx +0 -47
  132. package/dist/frontend-core/template/src/components/ui/label/label.stories.tsx +0 -41
  133. package/dist/frontend-core/template/src/components/ui/label/label.tsx +0 -20
  134. package/dist/frontend-core/template/src/components/ui/loader/loader.stories.tsx +0 -45
  135. package/dist/frontend-core/template/src/components/ui/loader/loader.tsx +0 -17
  136. package/dist/frontend-core/template/src/components/ui/mark-value-renderer/mark-value-renderer.stories.tsx +0 -114
  137. package/dist/frontend-core/template/src/components/ui/mark-value-renderer/mark-value-renderer.tsx +0 -48
  138. package/dist/frontend-core/template/src/components/ui/menubar/menu.stories.tsx +0 -134
  139. package/dist/frontend-core/template/src/components/ui/menubar/menubar.tsx +0 -208
  140. package/dist/frontend-core/template/src/components/ui/modal/modal.stories.tsx +0 -297
  141. package/dist/frontend-core/template/src/components/ui/modal/modal.tsx +0 -80
  142. package/dist/frontend-core/template/src/components/ui/navigation-menu/navigation-menu.stories.tsx +0 -213
  143. package/dist/frontend-core/template/src/components/ui/navigation-menu/navigation-menu.tsx +0 -142
  144. package/dist/frontend-core/template/src/components/ui/pagination/pagination.stories.tsx +0 -49
  145. package/dist/frontend-core/template/src/components/ui/pagination/pagination.tsx +0 -84
  146. package/dist/frontend-core/template/src/components/ui/popover/popover.stories.tsx +0 -82
  147. package/dist/frontend-core/template/src/components/ui/popover/popover.tsx +0 -55
  148. package/dist/frontend-core/template/src/components/ui/progress/progress.stories.tsx +0 -80
  149. package/dist/frontend-core/template/src/components/ui/progress/progress.tsx +0 -17
  150. package/dist/frontend-core/template/src/components/ui/radio-group/radio-group.stories.tsx +0 -154
  151. package/dist/frontend-core/template/src/components/ui/radio-group/radio-group.tsx +0 -68
  152. package/dist/frontend-core/template/src/components/ui/resizable/resizable.stories.tsx +0 -73
  153. package/dist/frontend-core/template/src/components/ui/resizable/resizeable.tsx +0 -38
  154. package/dist/frontend-core/template/src/components/ui/scroll-area/scroll-area.stories.tsx +0 -55
  155. package/dist/frontend-core/template/src/components/ui/scroll-area/scroll-area.tsx +0 -39
  156. package/dist/frontend-core/template/src/components/ui/select/select.stories.tsx +0 -297
  157. package/dist/frontend-core/template/src/components/ui/select/select.tsx +0 -227
  158. package/dist/frontend-core/template/src/components/ui/separator/separator.tsx +0 -21
  159. package/dist/frontend-core/template/src/components/ui/separator/seperator.stories.tsx +0 -25
  160. package/dist/frontend-core/template/src/components/ui/sheet/sheet.stories.tsx +0 -45
  161. package/dist/frontend-core/template/src/components/ui/sheet/sheet.tsx +0 -107
  162. package/dist/frontend-core/template/src/components/ui/skeleton/skeleton.stories.tsx +0 -26
  163. package/dist/frontend-core/template/src/components/ui/skeleton/skeleton.tsx +0 -7
  164. package/dist/frontend-core/template/src/components/ui/slider/slider.stories.tsx +0 -101
  165. package/dist/frontend-core/template/src/components/ui/slider/slider.tsx +0 -98
  166. package/dist/frontend-core/template/src/components/ui/spinner/spinner.stories.tsx +0 -19
  167. package/dist/frontend-core/template/src/components/ui/spinner/spinner.tsx +0 -21
  168. package/dist/frontend-core/template/src/components/ui/switch/switch.stories.tsx +0 -33
  169. package/dist/frontend-core/template/src/components/ui/switch/switch.tsx +0 -28
  170. package/dist/frontend-core/template/src/components/ui/tabs/tabs.stories.tsx +0 -215
  171. package/dist/frontend-core/template/src/components/ui/tabs/tabs.tsx +0 -70
  172. package/dist/frontend-core/template/src/components/ui/textarea/textarea.stories.tsx +0 -138
  173. package/dist/frontend-core/template/src/components/ui/textarea/textarea.tsx +0 -40
  174. package/dist/frontend-core/template/src/components/ui/toast/toast.mdx +0 -31
  175. package/dist/frontend-core/template/src/components/ui/toast/toast.stories.tsx +0 -89
  176. package/dist/frontend-core/template/src/components/ui/toggle/toggle.stories.tsx +0 -65
  177. package/dist/frontend-core/template/src/components/ui/toggle/toggle.tsx +0 -38
  178. package/dist/frontend-core/template/src/components/ui/toggle-group/toggle-group.stories.tsx +0 -85
  179. package/dist/frontend-core/template/src/components/ui/toggle-group/toggle-group.tsx +0 -54
  180. package/dist/frontend-core/template/src/components/ui/tooltip/tooltip.stories.tsx +0 -29
  181. 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
- }