@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,168 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite'
2
- import { SunIcon, ChevronUpIcon, ChevronDownIcon } from '@radix-ui/react-icons'
3
- import { expect, userEvent, screen, waitFor } from 'storybook/test'
4
- import { useState } from 'react'
5
- import {
6
- DropdownMenu,
7
- DropdownMenuPortal,
8
- DropdownMenuTrigger,
9
- DropdownMenuContent,
10
- DropdownMenuGroup,
11
- DropdownMenuLabel,
12
- DropdownMenuItem,
13
- DropdownMenuSeparator,
14
- DropdownMenuShortcut,
15
- DropdownMenuSub,
16
- DropdownMenuSubTrigger,
17
- DropdownMenuSubContent,
18
- } from './dropdown-menu'
19
- import { Button } from '@components/ui/button/button'
20
- import { Label } from '@components/ui/label/label'
21
- import { Checkbox } from '@components/ui/checkbox/checkbox'
22
- import { Input } from '@components/ui/input/input'
23
-
24
- const meta = {
25
- title: 'DropdownMenu',
26
- component: DropdownMenu,
27
- tags: ['autodocs'],
28
- parameters: {
29
- layout: 'centered',
30
- },
31
- argTypes: {},
32
- } satisfies Meta<typeof DropdownMenu>
33
- export default meta
34
-
35
- type Story = StoryObj<typeof meta>
36
-
37
- export const Default: Story = {
38
- render: () => (
39
- <div data-testid="outside-click-for-test" className="pointer-events-auto">
40
- <DropdownMenu>
41
- <DropdownMenuTrigger asChild>
42
- <Button variant="outline">Open dropdown</Button>
43
- </DropdownMenuTrigger>
44
- <DropdownMenuContent className="w-[250px]" align="start">
45
- <DropdownMenuLabel>Category 1</DropdownMenuLabel>
46
- <DropdownMenuGroup>
47
- <DropdownMenuItem>Item 1</DropdownMenuItem>
48
- <DropdownMenuItem>
49
- Item 2<DropdownMenuShortcut>⌘P (only visually)</DropdownMenuShortcut>
50
- </DropdownMenuItem>
51
- </DropdownMenuGroup>
52
- <DropdownMenuSeparator />
53
- <DropdownMenuGroup>
54
- <DropdownMenuSub>
55
- <DropdownMenuSubTrigger>Sub menu trigger</DropdownMenuSubTrigger>
56
- <DropdownMenuPortal>
57
- <DropdownMenuSubContent>
58
- <DropdownMenuItem>Sub Item 1</DropdownMenuItem>
59
- <DropdownMenuSeparator />
60
- <DropdownMenuItem>More... (just another item)</DropdownMenuItem>
61
- </DropdownMenuSubContent>
62
- </DropdownMenuPortal>
63
- </DropdownMenuSub>
64
- <DropdownMenuItem disabled>Disabled</DropdownMenuItem>
65
- <div className="flex items-center justify-center gap-3 mt-5">
66
- <span>or just use custom content instead of the DropdownMenuItems</span>
67
- <SunIcon className="size-15 text-yellow-500" />
68
- </div>
69
- </DropdownMenuGroup>
70
- </DropdownMenuContent>
71
- </DropdownMenu>
72
- </div>
73
- ),
74
- play: async () => {
75
- await userEvent.click(screen.getByText('Open dropdown'))
76
- const item1 = await screen.findByText('Item 1')
77
- await waitFor(() => {
78
- const style = window.getComputedStyle(item1)
79
- expect(style.visibility).toBe('visible')
80
- expect(Number(style.opacity)).toBeGreaterThan(0)
81
- })
82
- await userEvent.click(screen.getByTestId('outside-click-for-test'))
83
- await waitFor(() => {
84
- expect(screen.queryByText('Item 1')).toBeNull()
85
- })
86
- await userEvent.keyboard('{Escape}')
87
- await waitFor(() => {
88
- expect(screen.queryByText('Item 1')).toBeNull()
89
- })
90
- },
91
- }
92
-
93
- export const ExampleDropdownSearchableSelection: Story = {
94
- render: () => {
95
- const dummyUsers = [
96
- { id: '1', name: 'alice@wonderland.net' },
97
- { id: '2', name: 'bob.builder@kika.de' },
98
- { id: '3', name: 'charlie.bucket@chocolate-factory.com' },
99
- ]
100
- const [menuOpen, setMenuOpen] = useState(false)
101
- const [userFilterValue, setUserFilterValue] = useState('')
102
- const [selectedUserIds, setSelectedUserIds] = useState<string[]>([])
103
-
104
- const filteredUserData = dummyUsers.filter((user) =>
105
- user.name.toLowerCase().includes(userFilterValue.toLowerCase()),
106
- )
107
-
108
- const handleCheckboxChange = (userId: string) => {
109
- setSelectedUserIds((prev) => (prev.includes(userId) ? prev.filter((id) => id !== userId) : [...prev, userId]))
110
- }
111
-
112
- return (
113
- <div className="w-[180px]">
114
- <DropdownMenu open={menuOpen} onOpenChange={setMenuOpen}>
115
- <DropdownMenuTrigger asChild>
116
- <Button
117
- variant="outline"
118
- size="sm"
119
- className="group w-full flex items-center justify-between disabled:text-muted-foreground border-input hover:bg-muted-foreground hover:text-background"
120
- >
121
- <span className="mx-auto">
122
- {selectedUserIds.length === 0
123
- ? 'Select specific users'
124
- : `${selectedUserIds.length} user${selectedUserIds.length > 1 ? 's' : ''} selected`}
125
- </span>
126
- {menuOpen ? (
127
- <ChevronUpIcon className="size-4 opacity-50 text-muted-foreground group-hover:text-background" />
128
- ) : (
129
- <ChevronDownIcon className="size-4 opacity-50 group-hover:opacity-100 text-muted-foreground group-hover:text-background" />
130
- )}
131
- </Button>
132
- </DropdownMenuTrigger>
133
- <DropdownMenuContent align="start" className="w-[280px] flex flex-col p-0 border-(--discreet-border)">
134
- <Input
135
- className=" rounded-none border-0 border-b-1"
136
- variant="simple"
137
- placeholder="Search users"
138
- value={userFilterValue}
139
- onChange={(e) => setUserFilterValue(e.target.value)}
140
- />
141
- <div className="p-1">
142
- {filteredUserData.length > 0 ? (
143
- filteredUserData.map((user) => (
144
- <div key={user.id} className="flex hover:bg-accent py-1 px-2 rounded items-center gap-2">
145
- <Checkbox
146
- checked={selectedUserIds.includes(user.id)}
147
- onChange={() => handleCheckboxChange(user.id)}
148
- id={`user-${user.id}`}
149
- variant="iconSolo"
150
- checkboxSize="lg"
151
- checkIcon="check"
152
- iconStyle="solo"
153
- />
154
- <Label htmlFor={`user-${user.id}`} className="cursor-pointer">
155
- {user.name}
156
- </Label>
157
- </div>
158
- ))
159
- ) : (
160
- <p className="text-center text-muted-foreground py-3">no results found</p>
161
- )}
162
- </div>
163
- </DropdownMenuContent>
164
- </DropdownMenu>
165
- </div>
166
- )
167
- },
168
- }
@@ -1,225 +0,0 @@
1
- import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'
2
- import { CheckIcon, ChevronRightIcon, CircleIcon } from '@radix-ui/react-icons'
3
-
4
- import * as React from 'react'
5
-
6
- import { cn } from '@lib/utils'
7
-
8
- function DropdownMenu({ ...props }: Readonly<React.ComponentProps<typeof DropdownMenuPrimitive.Root>>) {
9
- return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
10
- }
11
-
12
- function DropdownMenuPortal({ ...props }: Readonly<React.ComponentProps<typeof DropdownMenuPrimitive.Portal>>) {
13
- return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
14
- }
15
-
16
- function DropdownMenuTrigger({ ...props }: Readonly<React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>>) {
17
- return <DropdownMenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />
18
- }
19
-
20
- function DropdownMenuContent({
21
- className,
22
- sideOffset = 4,
23
- ...props
24
- }: Readonly<React.ComponentProps<typeof DropdownMenuPrimitive.Content>>) {
25
- return (
26
- <DropdownMenuPrimitive.Portal>
27
- <DropdownMenuPrimitive.Content
28
- data-slot="dropdown-menu-content"
29
- sideOffset={sideOffset}
30
- className={cn(
31
- 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md',
32
- className,
33
- )}
34
- {...props}
35
- />
36
- </DropdownMenuPrimitive.Portal>
37
- )
38
- }
39
-
40
- function DropdownMenuGroup({ ...props }: Readonly<React.ComponentProps<typeof DropdownMenuPrimitive.Group>>) {
41
- return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
42
- }
43
-
44
- function DropdownMenuItem({
45
- className,
46
- inset,
47
- variant = 'default',
48
- ...props
49
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
50
- inset?: boolean
51
- variant?: 'default' | 'destructive'
52
- }) {
53
- return (
54
- <DropdownMenuPrimitive.Item
55
- data-slot="dropdown-menu-item"
56
- data-inset={inset}
57
- data-variant={variant}
58
- className={cn(
59
- "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
60
- className,
61
- )}
62
- {...props}
63
- />
64
- )
65
- }
66
-
67
- function DropdownMenuCheckboxItem({
68
- className,
69
- children,
70
- checked,
71
- ...props
72
- }: Readonly<React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>>) {
73
- return (
74
- <DropdownMenuPrimitive.CheckboxItem
75
- data-slot="dropdown-menu-checkbox-item"
76
- className={cn(
77
- "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
78
- className,
79
- )}
80
- checked={checked}
81
- {...props}
82
- >
83
- <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
84
- <DropdownMenuPrimitive.ItemIndicator>
85
- <CheckIcon className="size-4" />
86
- </DropdownMenuPrimitive.ItemIndicator>
87
- </span>
88
- {children}
89
- </DropdownMenuPrimitive.CheckboxItem>
90
- )
91
- }
92
-
93
- function DropdownMenuRadioGroup({ ...props }: Readonly<React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>>) {
94
- return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />
95
- }
96
-
97
- function DropdownMenuRadioItem({
98
- className,
99
- children,
100
- ...props
101
- }: Readonly<React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>>) {
102
- return (
103
- <DropdownMenuPrimitive.RadioItem
104
- data-slot="dropdown-menu-radio-item"
105
- className={cn(
106
- "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
107
- className,
108
- )}
109
- {...props}
110
- >
111
- <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
112
- <DropdownMenuPrimitive.ItemIndicator>
113
- <CircleIcon className="size-2 fill-current" />
114
- </DropdownMenuPrimitive.ItemIndicator>
115
- </span>
116
- {children}
117
- </DropdownMenuPrimitive.RadioItem>
118
- )
119
- }
120
-
121
- function DropdownMenuLabel({
122
- className,
123
- inset,
124
- ...props
125
- }: Readonly<
126
- React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
127
- inset?: boolean
128
- }
129
- >) {
130
- return (
131
- <DropdownMenuPrimitive.Label
132
- data-slot="dropdown-menu-label"
133
- data-inset={inset}
134
- className={cn('px-2 py-1.5 text-sm font-medium data-[inset]:pl-8', className)}
135
- {...props}
136
- />
137
- )
138
- }
139
-
140
- function DropdownMenuSeparator({
141
- className,
142
- ...props
143
- }: Readonly<React.ComponentProps<typeof DropdownMenuPrimitive.Separator>>) {
144
- return (
145
- <DropdownMenuPrimitive.Separator
146
- data-slot="dropdown-menu-separator"
147
- className={cn('bg-border -mx-1 my-1 h-px', className)}
148
- {...props}
149
- />
150
- )
151
- }
152
-
153
- function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {
154
- return (
155
- <span
156
- data-slot="dropdown-menu-shortcut"
157
- className={cn('text-muted-foreground ml-auto text-xs tracking-widest', className)}
158
- {...props}
159
- />
160
- )
161
- }
162
-
163
- function DropdownMenuSub({ ...props }: Readonly<React.ComponentProps<typeof DropdownMenuPrimitive.Sub>>) {
164
- return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
165
- }
166
-
167
- function DropdownMenuSubTrigger({
168
- className,
169
- inset,
170
- children,
171
- ...props
172
- }: Readonly<
173
- React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
174
- inset?: boolean
175
- }
176
- >) {
177
- return (
178
- <DropdownMenuPrimitive.SubTrigger
179
- data-slot="dropdown-menu-sub-trigger"
180
- data-inset={inset}
181
- className={cn(
182
- 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8',
183
- className,
184
- )}
185
- {...props}
186
- >
187
- {children}
188
- <ChevronRightIcon className="ml-auto size-4" />
189
- </DropdownMenuPrimitive.SubTrigger>
190
- )
191
- }
192
-
193
- function DropdownMenuSubContent({
194
- className,
195
- ...props
196
- }: Readonly<React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>>) {
197
- return (
198
- <DropdownMenuPrimitive.SubContent
199
- data-slot="dropdown-menu-sub-content"
200
- className={cn(
201
- 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg',
202
- className,
203
- )}
204
- {...props}
205
- />
206
- )
207
- }
208
-
209
- export {
210
- DropdownMenu,
211
- DropdownMenuPortal,
212
- DropdownMenuTrigger,
213
- DropdownMenuContent,
214
- DropdownMenuGroup,
215
- DropdownMenuLabel,
216
- DropdownMenuItem,
217
- DropdownMenuCheckboxItem,
218
- DropdownMenuRadioGroup,
219
- DropdownMenuRadioItem,
220
- DropdownMenuSeparator,
221
- DropdownMenuShortcut,
222
- DropdownMenuSub,
223
- DropdownMenuSubTrigger,
224
- DropdownMenuSubContent,
225
- }
@@ -1,141 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite'
2
- import { useState } from 'react'
3
-
4
- import { Input } from './input'
5
- import { expect, userEvent, screen } from 'storybook/test'
6
- import { Button } from '@components/ui/button/button'
7
-
8
- const meta = {
9
- title: 'Input',
10
- component: Input,
11
- tags: ['autodocs'],
12
- parameters: {
13
- layout: 'centered',
14
- },
15
- argTypes: {
16
- variant: {
17
- control: 'select',
18
- options: ['default', 'simple'],
19
- },
20
- },
21
- } satisfies Meta<typeof Input>
22
- export default meta
23
-
24
- type Story = StoryObj<typeof meta>
25
-
26
- export const Default: Story = {
27
- args: { variant: 'default' },
28
- render: (args) => {
29
- const [value, setValue] = useState('')
30
- return (
31
- <div className="flex items-center gap-2">
32
- <Input
33
- placeholder="Enter text..."
34
- {...args}
35
- value={value}
36
- onChange={(e) => setValue(e.target.value)}
37
- className="w-[200px]"
38
- />
39
- <span data-testid="input-value">
40
- {value ? 'value: ' : ''}
41
- {value}
42
- </span>
43
- </div>
44
- )
45
- },
46
- play: async () => {
47
- const input = screen.getByPlaceholderText('Enter text...')
48
- await userEvent.type(input, 'test')
49
- const valueSpan = screen.getByTestId('input-value')
50
- expect(valueSpan).toHaveTextContent('test')
51
- },
52
- }
53
-
54
- export const Variants: Story = {
55
- render: () => (
56
- <div className="flex flex-wrap gap-2 items-center">
57
- <Input placeholder="default" variant="default" className="w-48" />
58
- <Input placeholder="simple" variant="simple" className="w-48" />
59
- </div>
60
- ),
61
- }
62
-
63
- export const Disabled: Story = {
64
- render: (args) => (
65
- <div className="flex flex-wrap gap-4 items-center">
66
- <Input disabled {...args} className="w-[200px]" placeholder="Disabled" />
67
- </div>
68
- ),
69
- }
70
-
71
- export const EmailForm: Story = {
72
- render: () => {
73
- const [value, setValue] = useState('')
74
- const [error, setError] = useState<string | null>(null)
75
- const [submitted, setSubmitted] = useState(false)
76
- const [touched, setTouched] = useState(false)
77
-
78
- function validateEmail(email: string) {
79
- return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
80
- }
81
-
82
- function validate(value: string) {
83
- if (!value) return 'Field is required.'
84
- if (!validateEmail(value)) return 'Not a valid email.'
85
- return null
86
- }
87
-
88
- const handleSubmit = (e: React.FormEvent) => {
89
- e.preventDefault()
90
- setSubmitted(true)
91
- setError(validate(value))
92
- }
93
-
94
- const handleBlur = () => {
95
- setTouched(true)
96
- setError(validate(value))
97
- }
98
-
99
- return (
100
- <form className="flex flex-col gap-2 items-center w-[350px]" onSubmit={handleSubmit} noValidate>
101
- <Input
102
- className="w-full"
103
- placeholder="Enter an email..."
104
- value={value}
105
- onChange={(e) => {
106
- setValue(e.target.value)
107
- if (submitted || touched) setError(validate(e.target.value))
108
- }}
109
- onBlur={handleBlur}
110
- aria-invalid={!!error}
111
- />
112
- {error && (touched || submitted) && (
113
- <span className="text-destructive mt-1" role="alert">
114
- {error}
115
- </span>
116
- )}
117
- <Button type="submit" size="smLow">
118
- Submit
119
- </Button>
120
- </form>
121
- )
122
- },
123
- play: async () => {
124
- const input = screen.getByPlaceholderText('Enter an email...')
125
- const submitButton = screen.getByRole('button', { name: /submit/i })
126
-
127
- // Submit with empty input
128
- await userEvent.clear(input)
129
- await userEvent.click(submitButton)
130
- await expect(await screen.findByRole('alert')).toHaveTextContent('Field is required.')
131
- // Enter invalid email and submit
132
- await userEvent.type(input, 'not-an-email')
133
- await userEvent.click(submitButton)
134
- await expect(await screen.findByRole('alert')).toHaveTextContent('Not a valid email.')
135
- // Enter valid email and submit
136
- await userEvent.clear(input)
137
- await userEvent.type(input, 'test@example.com')
138
- await userEvent.click(submitButton)
139
- await expect(screen.queryByRole('alert')).toBeNull()
140
- },
141
- }
@@ -1,47 +0,0 @@
1
- import { cva, type VariantProps } from 'class-variance-authority'
2
- import * as React from 'react'
3
-
4
- import { cn } from '@lib/utils'
5
-
6
- const inputVariants = cva(
7
- 'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
8
- {
9
- variants: {
10
- variant: {
11
- default: 'h-9 md:text-sm focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
12
- simple: 'h-8',
13
- },
14
- },
15
- defaultVariants: {
16
- variant: 'default',
17
- },
18
- },
19
- )
20
-
21
- type InputProps = React.ComponentProps<'input'> &
22
- VariantProps<typeof inputVariants> & {
23
- /**
24
- * E2E test_id to identify the input.
25
- */
26
- __e2e_test_id__?: string
27
- onEnter?: () => void
28
- }
29
- function Input({ className, type, variant, __e2e_test_id__, onEnter, ...props }: InputProps) {
30
- return (
31
- <input
32
- type={type}
33
- data-slot="input"
34
- className={cn(inputVariants({ variant, className }))}
35
- data-test-id={__e2e_test_id__}
36
- onKeyDown={(e) => {
37
- props.onKeyDown?.(e)
38
- if (e.key === 'Enter') {
39
- onEnter?.()
40
- }
41
- }}
42
- {...props}
43
- />
44
- )
45
- }
46
-
47
- export { Input }
@@ -1,41 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite'
2
- import { expect, userEvent, screen } from 'storybook/test'
3
-
4
- import { Label } from './label'
5
- import { Checkbox } from '@components/ui/checkbox/shadcn-checkbox'
6
-
7
- const meta = {
8
- title: 'Label',
9
- component: Label,
10
- tags: ['autodocs'],
11
- parameters: {
12
- layout: 'centered',
13
- },
14
- } satisfies Meta<typeof Label>
15
- export default meta
16
-
17
- type Story = StoryObj<typeof meta>
18
-
19
- export const Default: Story = {
20
- render: () => <Label>Label</Label>,
21
- }
22
-
23
- export const Usage: Story = {
24
- render: () => (
25
- <div className="flex flex-wrap gap-2 items-center">
26
- <Checkbox id="label-1" />
27
- <Label htmlFor="label-1" className="cursor-pointer">
28
- Label for usage demonstration (click label to toggle checkbox)
29
- </Label>
30
- </div>
31
- ),
32
- play: async () => {
33
- const label = screen.getByText(/Label for usage demonstration/)
34
- const checkbox = screen.getByRole('checkbox')
35
- await expect(checkbox).not.toBeChecked()
36
- await userEvent.click(label)
37
- await expect(checkbox).toBeChecked()
38
- await userEvent.click(label)
39
- await expect(checkbox).not.toBeChecked()
40
- },
41
- }
@@ -1,20 +0,0 @@
1
- import * as LabelPrimitive from '@radix-ui/react-label'
2
-
3
- import * as React from 'react'
4
-
5
- import { cn } from '@lib/utils'
6
-
7
- function Label({ className, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) {
8
- return (
9
- <LabelPrimitive.Root
10
- data-slot="label"
11
- className={cn(
12
- 'flex items-center gap-2 text-base leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50',
13
- className,
14
- )}
15
- {...props}
16
- />
17
- )
18
- }
19
-
20
- export { Label }
@@ -1,45 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite'
2
-
3
- import { Loader } from './loader'
4
-
5
- const meta = {
6
- title: 'Loader',
7
- component: Loader,
8
- tags: ['autodocs'],
9
- parameters: {
10
- layout: 'centered',
11
- },
12
- argTypes: {
13
- label: {
14
- control: 'text',
15
- },
16
- },
17
- } satisfies Meta<typeof Loader>
18
- export default meta
19
-
20
- type Story = StoryObj<typeof meta>
21
-
22
- export const Default: Story = {
23
- args: { label: 'Loading...' },
24
- render: (args) => (
25
- <div className="relative w-[350px] h-[150px] border">
26
- <span>Background, loader is applied on, which gets dimmed</span>
27
- <br />
28
- <span>needs position relative for correct loader placement</span>
29
- <Loader {...args} />
30
- </div>
31
- ),
32
- // play: async () => {
33
- // // Check that the loader label is visible
34
- // expect(screen.getByText('Loading...')).toBeVisible()
35
- // const loaderLabel = screen.getByText('Loading...')
36
- // // Find the SVG spinner within the loader
37
- // const svg = loaderLabel.closest('div')?.querySelector('svg')
38
- // expect(svg).toBeTruthy()
39
- // expect(svg).toBeVisible()
40
- // // Check that the SVG size is greater than 0
41
- // const rect = svg?.getBoundingClientRect()
42
- // expect(rect?.width).toBeGreaterThan(0)
43
- // expect(rect?.height).toBeGreaterThan(0)
44
- // },
45
- }