@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,780 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite'
2
-
3
- import { DataGrid } from './data-grid'
4
- import { useDataGrid } from './hooks/use-data-grid'
5
- import { Checkbox } from '../checkbox/checkbox'
6
- import { Button } from '../button/button'
7
- import { MinusIcon, MoonIcon, PlusIcon, SunIcon, TrashIcon } from '@radix-ui/react-icons'
8
- import { useCallback, useEffect, useMemo, useState } from 'react'
9
- import { ColumnDef, getExpandedRowModel } from '@tanstack/react-table'
10
- import { RowHeightValue } from './data-grid-types'
11
- import { ISODateRange, isoToLocalDate } from './cell-variants/utils/gantt-timerange-picker'
12
- import { DataGridViewMenu } from './data-grid-view-menu'
13
- import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../select/select'
14
-
15
- const meta = {
16
- title: 'DataGrid',
17
- component: DataGrid,
18
- tags: ['autodocs'],
19
- parameters: {
20
- layout: 'centered',
21
- },
22
- argTypes: {},
23
- } satisfies Meta<typeof DataGrid>
24
- export default meta
25
-
26
- type Story = StoryObj<typeof meta>
27
-
28
- type ExampleData = {
29
- shortText: string
30
- longText: string | null
31
- valueLabelSelect: string | null
32
- boolean: boolean
33
- enumSelect: string
34
- multiSelect: string[] | null
35
- number: number | null
36
- startDate: Date | null
37
- endDate: Date | null
38
- accessorFn?: 'day' | 'night'
39
- customNode?: React.ReactNode
40
- }
41
-
42
- const getCustomReactNodeCell = (time: 'day' | 'night') => {
43
- return (
44
- <div className="size-full flex items-center justify-center">
45
- {time === 'day' ? <SunIcon className="text-yellow-500" /> : <MoonIcon className="text-blue-900" />}
46
- </div>
47
- )
48
- }
49
-
50
- const initialData: ExampleData[] = [
51
- {
52
- shortText: 'Reduce energy consumption',
53
- longText: 'Implement energy-efficient practices to lower consumption by 15%.',
54
- valueLabelSelect: 'ja982ika782',
55
- boolean: true,
56
- enumSelect: 'Red',
57
- multiSelect: ['optionA', 'optionC'],
58
- number: 1500,
59
- startDate: new Date('2024-12-31'),
60
- endDate: new Date('2025-12-31'),
61
- accessorFn: 'day',
62
- customNode: <div className="size-full flex items-center justify-center text-blue-500 font-bold">Direct Node 1</div>,
63
- },
64
- {
65
- shortText: 'Waste reduction program',
66
- longText: 'Launch a waste reduction initiative to decrease waste by 20%.',
67
- valueLabelSelect: 'jd81j980905',
68
- boolean: false,
69
- enumSelect: 'Green',
70
- multiSelect: null,
71
- number: 800,
72
- startDate: null,
73
- endDate: null,
74
- accessorFn: 'night',
75
- customNode: (
76
- <div className="size-full flex items-center justify-center">
77
- <Button size="xs2" className="h-5">
78
- Action
79
- </Button>
80
- </div>
81
- ),
82
- },
83
- {
84
- shortText: 'Water conservation efforts',
85
- longText: null,
86
- valueLabelSelect: null,
87
- boolean: false,
88
- enumSelect: 'Amber',
89
- multiSelect: ['optionB'],
90
- number: 600,
91
- startDate: new Date('2025-01-15'),
92
- endDate: new Date('2025-10-20'),
93
- },
94
- {
95
- shortText: 'Sustainable sourcing',
96
- longText: 'Source 25% of materials from sustainable suppliers.',
97
- valueLabelSelect: null,
98
- boolean: true,
99
- enumSelect: 'Red',
100
- multiSelect: ['optionA', 'optionD'],
101
- number: 2000,
102
- startDate: new Date('2024-10-20'),
103
- endDate: null,
104
- },
105
- {
106
- shortText: 'Employee training on sustainability',
107
- longText: 'Conduct training sessions to educate employees on sustainable practices.',
108
- valueLabelSelect: 'jd0920982ljkna8',
109
- boolean: true,
110
- enumSelect: 'Green',
111
- multiSelect: ['optionA', 'optionC', 'optionD'],
112
- number: 300,
113
- startDate: new Date('2024-09-15'),
114
- endDate: new Date('2024-12-15'),
115
- accessorFn: 'day',
116
- },
117
- {
118
- shortText: 'Carbon footprint assessment',
119
- longText: 'Evaluate and report the company’s carbon footprint.',
120
- valueLabelSelect: 'jad982ja9802ijlljk',
121
- boolean: false,
122
- enumSelect: 'NA',
123
- multiSelect: null,
124
- number: null,
125
- startDate: new Date('2024-08-31'),
126
- endDate: new Date('2024-11-30'),
127
- },
128
- ]
129
-
130
- const parseDate = (value: string | Date | null): Date | null => {
131
- if (!value) return null
132
- if (value instanceof Date) return value
133
- if (typeof value === 'string') {
134
- const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value)
135
- if (match) {
136
- return new Date(Number.parseInt(match[1], 10), Number.parseInt(match[2], 10) - 1, Number.parseInt(match[3], 10))
137
- }
138
- }
139
- const parsed = new Date(value)
140
- return Number.isNaN(parsed.getTime()) ? null : parsed
141
- }
142
-
143
- const DataGridDemo = () => {
144
- const [data, setData] = useState<ExampleData[]>(initialData)
145
- const [selectedGanttRange, setSelectedGanttRange] = useState<ISODateRange | undefined>(undefined)
146
-
147
- const columns = useMemo<ColumnDef<ExampleData>[]>(
148
- () => [
149
- {
150
- id: 'select',
151
- header: ({ table }) => (
152
- <div className="size-full p-0 m-0 flex items-center gap-2 ">
153
- <Checkbox
154
- variant={table.getIsSomePageRowsSelected() ? 'default' : 'simple'}
155
- iconStyle={table.getIsSomePageRowsSelected() ? 'default' : 'simple'}
156
- checkIcon="check"
157
- checked={table.getIsAllPageRowsSelected() || table.getIsSomePageRowsSelected()}
158
- onChange={(e) => table.toggleAllPageRowsSelected(!!e.target.checked)}
159
- />
160
- <Button
161
- variant="ghost"
162
- className="size-5 hover:[&_svg]:text-background hover:bg-destructive/90"
163
- onClick={() => {
164
- const toRemove = Array.from(table.getSelectedRowModel().rows)
165
- if (toRemove.length === 0) {
166
- return
167
- }
168
- const idsToRemove = new Set(toRemove.map((row) => row.index))
169
- setData((prev) => prev.filter((_, index) => !idsToRemove.has(index)))
170
- table.toggleAllRowsSelected(false)
171
- }}
172
- >
173
- <TrashIcon />
174
- </Button>
175
- </div>
176
- ),
177
- cell: ({ row }) => (
178
- <Checkbox
179
- variant="simple"
180
- iconStyle="simple"
181
- checkIcon="check"
182
- checked={row.getIsSelected()}
183
- onChange={(e) => row.toggleSelected(!!e.target.checked)}
184
- />
185
- ),
186
- size: 70,
187
- enableSorting: false,
188
- enableHiding: false,
189
- },
190
- {
191
- id: 'shortText',
192
- accessorKey: 'shortText',
193
- header: 'Short Text',
194
- meta: { cell: { variant: 'short-text' } },
195
- size: 150,
196
- },
197
- {
198
- id: 'longText',
199
- accessorKey: 'longText',
200
- header: 'Long Text',
201
- meta: { cell: { variant: 'long-text' } },
202
- size: 150,
203
- },
204
- {
205
- id: 'boolean',
206
- accessorKey: 'boolean',
207
- header: 'Boolean',
208
- meta: { cell: { variant: 'checkbox' } },
209
- size: 150,
210
- },
211
- {
212
- id: 'enumSelect',
213
- accessorKey: 'enumSelect',
214
- header: 'Enum Select',
215
- meta: {
216
- cell: {
217
- variant: 'select',
218
- options: [
219
- { label: 'Red', value: 'Red' },
220
- { label: 'Amber', value: 'Amber' },
221
- { label: 'Green', value: 'Green' },
222
- { label: 'NA', value: 'NA' },
223
- ],
224
- },
225
- },
226
- size: 150,
227
- },
228
- {
229
- id: 'valueLabelSelect',
230
- accessorKey: 'valueLabelSelect',
231
- header: 'Value-label Select',
232
- meta: {
233
- cell: {
234
- variant: 'select',
235
- options: [
236
- { label: 'Max Mustermann', value: 'ja982ika782' },
237
- { label: 'Erika Musterfrau', value: 'jd81j980905' },
238
- { label: 'John Doe', value: 'jia82813jh4g' },
239
- { label: 'Jane Doe', value: '28jnfg8a8x9' },
240
- { label: 'Anna Schmidt', value: 'jd0920982ljkna8' },
241
- { label: 'Paul Müller', value: 'jad982ja9802ijlljk' },
242
- ],
243
- hasSearch: true,
244
- },
245
- },
246
- size: 170,
247
- },
248
- {
249
- id: 'multiSelect',
250
- accessorKey: 'multiSelect',
251
- header: 'Multi Select',
252
- meta: {
253
- cell: {
254
- variant: 'multi-select',
255
- options: [
256
- { label: 'Option A', value: 'optionA' },
257
- { label: 'Option B', value: 'optionB' },
258
- { label: 'Option C', value: 'optionC' },
259
- { label: 'Option D', value: 'optionD' },
260
- ],
261
- },
262
- },
263
- size: 210,
264
- },
265
- {
266
- id: 'number',
267
- accessorKey: 'number',
268
- header: 'Number',
269
- meta: { cell: { variant: 'number' } },
270
- size: 150,
271
- },
272
- {
273
- id: 'startDate',
274
- accessorKey: 'startDate',
275
- header: 'Start Date',
276
- meta: { cell: { variant: 'date' } },
277
- size: 150,
278
- },
279
- {
280
- id: 'endDate',
281
- accessorKey: 'endDate',
282
- header: 'End Date',
283
- meta: { cell: { variant: 'date' } },
284
- size: 150,
285
- },
286
- {
287
- id: 'timeline',
288
- header: 'Timeline',
289
- accessorFn: (row) => {
290
- const start = parseDate(row.startDate as unknown as string | Date | null)
291
- const end = parseDate(row.endDate as unknown as string | Date | null)
292
-
293
- if (!start || !end) {
294
- return null
295
- }
296
- return {
297
- start,
298
- end,
299
- barClassName: row.boolean ? 'bg-primary' : 'bg-primary/50',
300
- }
301
- },
302
- meta: {
303
- cell: {
304
- variant: 'gantt',
305
- timelineStart: new Date(new Date().getFullYear() - 1, 6, 0),
306
- timelineEnd: new Date(new Date().getFullYear() + 1, 3, 1),
307
- dateRangeFrom: selectedGanttRange?.from ? isoToLocalDate(selectedGanttRange.from) : undefined,
308
- dateRangeTo: selectedGanttRange?.to ? isoToLocalDate(selectedGanttRange.to) : undefined,
309
- onRangeChange: setSelectedGanttRange,
310
- },
311
- },
312
- maxSize: 1000,
313
- size: 500,
314
- },
315
- {
316
- id: 'withAccessorFn',
317
- accessorFn: (row) => (row.accessorFn ? getCustomReactNodeCell(row.accessorFn) : null),
318
- header: 'With accessorFn',
319
- meta: { cell: { variant: 'react-node' } },
320
- size: 150,
321
- },
322
- {
323
- id: 'customNode',
324
- accessorKey: 'customNode',
325
- header: 'Custom React Node',
326
- meta: { cell: { variant: 'react-node' } },
327
- size: 150,
328
- },
329
- ],
330
- [selectedGanttRange],
331
- )
332
-
333
- const onRowAdd = useCallback(() => {
334
- setData((prev) => [...prev, { shortText: 'New Item', boolean: false, enumSelect: 'NA' } as ExampleData])
335
-
336
- return {
337
- rowIndex: data.length,
338
- columnId: 'shortText',
339
- }
340
- }, [data.length])
341
-
342
- const { table, ...dataGridProps } = useDataGrid({
343
- columns,
344
- data,
345
- onDataChange: setData,
346
- onRowAdd,
347
- initialState: {
348
- columnPinning: {
349
- left: ['select'],
350
- },
351
- },
352
- enableSearch: true,
353
- })
354
- return (
355
- <div className="w-220 flex flex-col gap-2">
356
- <DataGridViewMenu table={table} />
357
- <DataGrid {...dataGridProps} table={table} />
358
- </div>
359
- )
360
- }
361
-
362
- export const Default: Story = {
363
- args: {} as any,
364
- render: () => <DataGridDemo />,
365
- }
366
-
367
- type PropertyDemoData = {
368
- normal: string
369
- editable: boolean
370
- withAlignment: string
371
- }
372
-
373
- const initialPropertyDemoData: PropertyDemoData[] = [
374
- {
375
- normal: 'Text',
376
- editable: false,
377
- withAlignment: 'Aligned Text',
378
- },
379
- {
380
- normal: 'Text',
381
- editable: true,
382
- withAlignment: 'Aligned Text',
383
- },
384
- {
385
- normal: 'Text',
386
- editable: false,
387
- withAlignment: 'Aligned Text',
388
- },
389
- ]
390
-
391
- const DataGridPropertyDemo = () => {
392
- const [data, setData] = useState<PropertyDemoData[]>(initialPropertyDemoData)
393
-
394
- const [alignment, setAlignment] = useState<'left' | 'center' | 'right' | undefined>(undefined)
395
- const [rowHeight, setRowHeight] = useState<RowHeightValue>('short')
396
- const [enableColumnSelection, setEnableColumnSelection] = useState(true)
397
-
398
- const columns = useMemo<ColumnDef<PropertyDemoData>[]>(
399
- () => [
400
- {
401
- id: 'normal',
402
- accessorKey: 'normal',
403
- header: 'Normal',
404
- meta: { cell: { variant: 'short-text' } },
405
- size: 150,
406
- },
407
- {
408
- id: 'editable',
409
- accessorKey: 'editable',
410
- header: 'Editable',
411
- meta: {
412
- cell: { variant: 'checkbox' },
413
- },
414
- size: 110,
415
- },
416
- {
417
- id: 'withEditable',
418
- accessorFn: (row) => (row.editable ? 'Cell is editable' : 'Cell is not editable'),
419
- header: 'With Editable',
420
- meta: { cell: { variant: 'short-text' }, editable: (row: PropertyDemoData) => row.editable },
421
- size: 150,
422
- },
423
- {
424
- id: 'withAlignment',
425
- accessorKey: 'withAlignment',
426
- header: 'With Alignment',
427
- meta: { cell: { variant: 'short-text' }, align: alignment },
428
- size: 150,
429
- },
430
- {
431
- id: 'withClassName',
432
- accessorFn: (row) => (row.editable ? 'Row has editable set' : 'Row has not editable set'),
433
- header: 'With Class name',
434
- meta: {
435
- cell: { variant: 'short-text' },
436
- className: (row: PropertyDemoData) => (row.editable ? undefined : 'opacity-50'),
437
- },
438
- size: 170,
439
- },
440
- {
441
- id: 'notSortable',
442
- accessorKey: 'normal',
443
- header: 'Not sortable',
444
- meta: { cell: { variant: 'short-text' } },
445
- enableSorting: false,
446
- size: 150,
447
- },
448
- {
449
- id: 'notPinnable',
450
- accessorKey: 'normal',
451
- header: 'Not pinnable',
452
- meta: { cell: { variant: 'short-text' } },
453
- enablePinning: false,
454
- size: 150,
455
- },
456
- {
457
- id: 'notHideable',
458
- accessorKey: 'normal',
459
- header: 'Not hideable',
460
- meta: { cell: { variant: 'short-text' } },
461
- enableHiding: false,
462
- size: 150,
463
- },
464
- {
465
- id: 'notResizable',
466
- accessorKey: 'normal',
467
- header: 'Not resizable',
468
- meta: { cell: { variant: 'short-text' } },
469
- enableResizing: false,
470
- size: 150,
471
- },
472
- {
473
- id: 'controlledResizeable',
474
- accessorKey: 'normal',
475
- header: 'Controlled resizable (200-300 px)',
476
- meta: { cell: { variant: 'short-text' } },
477
- size: 250,
478
- minSize: 200,
479
- maxSize: 300,
480
- },
481
- {
482
- id: 'customHeader',
483
- header: () => <span className="text-primary font-bold">Custom Header & Cells</span>,
484
- cell: ({ row }) => (
485
- <a href={`https://www.example.com/${row.index + 1}`} className="text-primary font-bold hover:underline">
486
- Custom Cell {row.index + 1}
487
- </a>
488
- ),
489
- size: 180,
490
- },
491
- ],
492
- [alignment],
493
- )
494
-
495
- const { table, ...dataGridProps } = useDataGrid({
496
- columns,
497
- data,
498
- onDataChange: setData,
499
- enableSearch: true,
500
- rowHeight,
501
- enableColumnSelection,
502
- })
503
-
504
- return (
505
- <div className="w-220 flex flex-col gap-2">
506
- <div className="flex gap-2 items-center flex-wrap">
507
- <Select value={alignment} onValueChange={(value) => setAlignment(value as 'left' | 'center' | 'right')}>
508
- <SelectTrigger size="sm" className="w-[150px]">
509
- Select alignment
510
- </SelectTrigger>
511
- <SelectContent>
512
- <SelectItem value="left">Left</SelectItem>
513
- <SelectItem value="center">Center</SelectItem>
514
- <SelectItem value="right">Right</SelectItem>
515
- </SelectContent>
516
- </Select>
517
-
518
- <Select value={rowHeight} onValueChange={(value) => setRowHeight(value as RowHeightValue)}>
519
- <SelectTrigger size="sm" className="w-[150px]">
520
- Row height
521
- </SelectTrigger>
522
- <SelectContent>
523
- <SelectItem value="short">Short</SelectItem>
524
- <SelectItem value="medium">Medium</SelectItem>
525
- <SelectItem value="tall">Tall</SelectItem>
526
- <SelectItem value="extra-tall">Extra Tall</SelectItem>
527
- </SelectContent>
528
- </Select>
529
-
530
- <div className="flex items-center gap-2 border rounded-md px-3 py-1 h-8 text-sm bg-background">
531
- <Checkbox
532
- id="col-select"
533
- checked={enableColumnSelection}
534
- onChange={(e) => setEnableColumnSelection(e.target.checked)}
535
- />
536
- <label htmlFor="col-select">Enable Column Selection</label>
537
- </div>
538
-
539
- <DataGridViewMenu table={table} />
540
- </div>
541
- <DataGrid {...dataGridProps} table={table} />
542
- </div>
543
- )
544
- }
545
-
546
- export const PropertyDemo: Story = {
547
- args: {} as any,
548
- render: () => <DataGridPropertyDemo />,
549
- }
550
-
551
- type ExpandableData = {
552
- id: string
553
- name: string
554
- foundedYear?: number
555
- type: 'company' | 'department' | 'team' | 'employee'
556
- role?: string
557
- salary?: number
558
- subRows?: ExpandableData[]
559
- }
560
-
561
- const expandableData: ExpandableData[] = [
562
- {
563
- id: 'company-1',
564
- name: 'Tech Corp',
565
- foundedYear: 1998,
566
- type: 'company',
567
- subRows: [
568
- {
569
- id: 'dept-1',
570
- name: 'Engineering',
571
- foundedYear: 1999,
572
- type: 'department',
573
- subRows: [
574
- {
575
- id: 'team-1',
576
- name: 'Frontend Team',
577
- foundedYear: 2010,
578
- type: 'team',
579
- subRows: [
580
- {
581
- id: 'emp-1',
582
- name: 'Alice Johnson',
583
- role: 'Senior Frontend Engineer',
584
- type: 'employee',
585
- salary: 90000,
586
- },
587
- {
588
- id: 'emp-2',
589
- name: 'Bob Smith',
590
- role: 'Frontend Engineer',
591
- type: 'employee',
592
- salary: 75000,
593
- },
594
- ],
595
- },
596
- {
597
- id: 'team-2',
598
- name: 'Backend Team',
599
- foundedYear: 2008,
600
- type: 'team',
601
- subRows: [
602
- {
603
- id: 'emp-3',
604
- name: 'Charlie Brown',
605
- role: 'Backend Engineer',
606
- type: 'employee',
607
- salary: 80000,
608
- },
609
- ],
610
- },
611
- ],
612
- },
613
- {
614
- id: 'dept-2',
615
- name: 'Design',
616
- foundedYear: 2005,
617
- type: 'department',
618
- subRows: [
619
- {
620
- id: 'emp-4',
621
- name: 'Diana Miller',
622
- role: 'Product Designer',
623
- type: 'employee',
624
- salary: 70000,
625
- },
626
- ],
627
- },
628
- ],
629
- },
630
- ]
631
-
632
- function aggregateSalaries(data: ExpandableData[]): ExpandableData[] {
633
- return data.map((node) => {
634
- if (!node.subRows || node.subRows.length === 0) {
635
- return {
636
- ...node,
637
- salary: node.salary ?? 0,
638
- }
639
- }
640
- const aggregatedSubRows = aggregateSalaries(node.subRows)
641
- const totalSalary = aggregatedSubRows.reduce((sum, child) => sum + (child.salary ?? 0), 0)
642
- return {
643
- ...node,
644
- subRows: aggregatedSubRows,
645
- salary: totalSalary,
646
- }
647
- })
648
- }
649
-
650
- const aggregatedData = aggregateSalaries(expandableData)
651
-
652
- const DataGridExpandableDemo = () => {
653
- const [data] = useState(aggregatedData)
654
-
655
- const columns = useMemo<ColumnDef<ExpandableData>[]>(
656
- () => [
657
- {
658
- id: 'name',
659
- accessorKey: 'name',
660
- header: 'Name',
661
- cell: ({ row, getValue }) => {
662
- const indent = row.depth * 16
663
- const canExpand = row.getCanExpand()
664
- const isExpanded = row.getIsExpanded()
665
-
666
- return (
667
- <div className="size-full flex items-center px-2">
668
- <div style={{ width: indent, minWidth: indent }} />
669
- {canExpand ? (
670
- <>
671
- <Button
672
- variant="ghost"
673
- size="iconSm"
674
- className="size-5.5 mr-1"
675
- onClick={row.getToggleExpandedHandler()}
676
- aria-label={isExpanded ? 'Collapse' : 'Expand'}
677
- >
678
- {isExpanded ? <MinusIcon /> : <PlusIcon />}
679
- </Button>
680
- <span className="truncate font-semibold">{getValue<string>()}</span>
681
- </>
682
- ) : (
683
- <span className="truncate">{getValue<string>()}</span>
684
- )}
685
- </div>
686
- )
687
- },
688
- meta: { cell: { variant: 'short-text' } },
689
- size: 200,
690
- },
691
- {
692
- id: 'type',
693
- accessorKey: 'type',
694
- header: 'Type',
695
- meta: {
696
- cell: {
697
- variant: 'select',
698
- options: [
699
- { label: 'Company', value: 'company' },
700
- { label: 'Department', value: 'department' },
701
- { label: 'Team', value: 'team' },
702
- { label: 'Employee', value: 'employee' },
703
- ],
704
- },
705
- },
706
- size: 150,
707
- },
708
- {
709
- id: 'foundedYear',
710
- accessorKey: 'foundedYear',
711
- header: 'Founded Year',
712
- meta: { cell: { variant: 'number' } },
713
- size: 150,
714
- },
715
- {
716
- id: 'salary',
717
- accessorKey: 'salary',
718
- header: 'Salary',
719
- meta: {
720
- cell: {
721
- variant: 'number',
722
- suffix: ' €',
723
- fallbackValue: 'N/A',
724
- },
725
- className(row) {
726
- return row?.type === 'employee' ? undefined : 'font-semibold'
727
- },
728
- editable(row) {
729
- return row?.type === 'employee'
730
- },
731
- },
732
- size: 150,
733
- },
734
- {
735
- id: 'role',
736
- accessorKey: 'role',
737
- header: 'Role',
738
- meta: { cell: { variant: 'short-text' } },
739
- size: 150,
740
- },
741
- ],
742
- [],
743
- )
744
-
745
- const defaultExpanded = useMemo(() => {
746
- const expanded: Record<string, boolean> = {}
747
- for (const p of data) {
748
- if (p.subRows && p.subRows.length > 0) {
749
- expanded[p.id] = true
750
- }
751
- }
752
- return expanded
753
- }, [data])
754
-
755
- const { table, ...dataGridProps } = useDataGrid({
756
- columns,
757
- data,
758
- getRowId: (row) => row.id,
759
- getSubRows: (row) => row.subRows,
760
- getExpandedRowModel: getExpandedRowModel(),
761
- initialState: { expanded: defaultExpanded, columnPinning: { left: ['name'] } },
762
- })
763
-
764
- useEffect(() => {
765
- if (table && defaultExpanded) {
766
- table.setExpanded(defaultExpanded)
767
- }
768
- }, [table, defaultExpanded])
769
-
770
- return (
771
- <div className="w-220 flex flex-col gap-2">
772
- <DataGrid {...dataGridProps} table={table} />
773
- </div>
774
- )
775
- }
776
-
777
- export const ExpandableRows: Story = {
778
- args: {} as any,
779
- render: () => <DataGridExpandableDemo />,
780
- }