nexstruct 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/AGENTS.md +122 -0
  2. package/LICENSE +21 -0
  3. package/README.md +103 -0
  4. package/package.json +99 -0
  5. package/scaffold/generator.js +409 -0
  6. package/scaffold/index.js +20 -0
  7. package/scaffold/prompts.js +108 -0
  8. package/templates/api/axios/src/api/axios/client.api.ts +30 -0
  9. package/templates/api/axios/src/api/axios/users.api.ts +15 -0
  10. package/templates/api/fetch/src/api/fetch/client.api.ts +68 -0
  11. package/templates/api/fetch/src/api/fetch/users.api.ts +15 -0
  12. package/templates/api/trpc/src/api/trpc/client.api.ts +4 -0
  13. package/templates/api/trpc/src/api/trpc/router.api.ts +15 -0
  14. package/templates/api/trpc/src/api/trpc/server.client.api.ts +4 -0
  15. package/templates/api/trpc/src/providers/trpc.provider.tsx +24 -0
  16. package/templates/auth/clerk/src/auth/clerk/auth.service.ts +4 -0
  17. package/templates/auth/clerk/src/hooks/use-auth.hook.ts +13 -0
  18. package/templates/auth/clerk/src/middleware.ts +7 -0
  19. package/templates/auth/clerk/src/providers/auth.provider.tsx +6 -0
  20. package/templates/auth/next-auth/src/app/api/auth/[...nextauth]/route.ts +5 -0
  21. package/templates/auth/next-auth/src/auth/next-auth/auth.service.ts +45 -0
  22. package/templates/auth/next-auth/src/hooks/use-session.hook.ts +13 -0
  23. package/templates/auth/next-auth/src/providers/session.provider.tsx +6 -0
  24. package/templates/forms/formik/src/components/forms/login-form.component.tsx +30 -0
  25. package/templates/forms/formik/src/forms/formik/hooks/use-form-config.hook.ts +7 -0
  26. package/templates/forms/formik/src/forms/formik/schemas/example.schema.ts +8 -0
  27. package/templates/forms/react-hook-form/src/components/forms/login-form.component.tsx +27 -0
  28. package/templates/forms/react-hook-form/src/forms/react-hook-form/hooks/use-form.hook.ts +13 -0
  29. package/templates/forms/react-hook-form/src/forms/react-hook-form/schemas/example.schema.ts +15 -0
  30. package/templates/nextjs-base/next.config.ts +5 -0
  31. package/templates/nextjs-base/postcss.config.mjs +9 -0
  32. package/templates/nextjs-base/src/app/_components/navbar.tsx +88 -0
  33. package/templates/nextjs-base/src/app/_components/sidebar.tsx +223 -0
  34. package/templates/nextjs-base/src/app/error.tsx +39 -0
  35. package/templates/nextjs-base/src/app/globals.css +71 -0
  36. package/templates/nextjs-base/src/app/layout.tsx +21 -0
  37. package/templates/nextjs-base/src/app/loading.tsx +13 -0
  38. package/templates/nextjs-base/src/app/not-found.tsx +22 -0
  39. package/templates/nextjs-base/src/app/page.tsx +10 -0
  40. package/templates/nextjs-base/tailwind.config.ts +69 -0
  41. package/templates/shared/src/components/common/theme-toggle.component.tsx +31 -0
  42. package/templates/shared/src/components/common/toast/custom-message.component.tsx +18 -0
  43. package/templates/shared/src/components/common/toast/index.ts +8 -0
  44. package/templates/shared/src/components/common/toast/toast-message.component.tsx +112 -0
  45. package/templates/shared/src/hooks/use-debounce.hook.ts +12 -0
  46. package/templates/shared/src/hooks/use-fetch.hook.ts +42 -0
  47. package/templates/shared/src/hooks/use-intersection-observer.hook.ts +39 -0
  48. package/templates/shared/src/hooks/use-local-storage.hook.ts +30 -0
  49. package/templates/shared/src/hooks/use-media-query.hook.ts +26 -0
  50. package/templates/shared/src/hooks/use-toggle.hook.ts +12 -0
  51. package/templates/shared/src/lib/utils.util.ts +361 -0
  52. package/templates/shared/src/providers/theme.provider.tsx +17 -0
  53. package/templates/shared/src/providers/toast.provider.tsx +32 -0
  54. package/templates/shared/src/types/common.type.ts +34 -0
  55. package/templates/state/context/src/store/context/auth.context.tsx +47 -0
  56. package/templates/state/context/src/store/context/counter.context.tsx +41 -0
  57. package/templates/state/context/src/store/context/index.ts +2 -0
  58. package/templates/state/redux/src/providers/redux.provider.tsx +7 -0
  59. package/templates/state/redux/src/store/redux/hooks.store.ts +5 -0
  60. package/templates/state/redux/src/store/redux/index.ts +4 -0
  61. package/templates/state/redux/src/store/redux/slices/api.slice.ts +8 -0
  62. package/templates/state/redux/src/store/redux/slices/counter.slice.ts +24 -0
  63. package/templates/state/redux/src/store/redux/store.store.ts +13 -0
  64. package/templates/state/zustand/src/store/zustand/counter.store.ts +15 -0
  65. package/templates/state/zustand/src/store/zustand/index.ts +2 -0
  66. package/templates/state/zustand/src/store/zustand/user.store.ts +32 -0
  67. package/templates/ui/antd/COMPONENT_GUIDE.md +326 -0
  68. package/templates/ui/antd/src/app/examples/dialog/page.tsx +205 -0
  69. package/templates/ui/antd/src/app/examples/form/page.tsx +160 -0
  70. package/templates/ui/antd/src/app/examples/layout.tsx +125 -0
  71. package/templates/ui/antd/src/app/examples/page.tsx +64 -0
  72. package/templates/ui/antd/src/app/examples/table/page.tsx +118 -0
  73. package/templates/ui/antd/src/app/page.tsx +283 -0
  74. package/templates/ui/antd/src/components/common/DynamicTable/dynamic-table.component.tsx +79 -0
  75. package/templates/ui/antd/src/components/common/button/action-button.component.tsx +63 -0
  76. package/templates/ui/antd/src/components/common/dialog/dialog-wrapper.component.tsx +63 -0
  77. package/templates/ui/antd/src/components/common/fields/assets/components/check-field.component.tsx +55 -0
  78. package/templates/ui/antd/src/components/common/fields/assets/components/date-picker-field.component.tsx +80 -0
  79. package/templates/ui/antd/src/components/common/fields/assets/components/limit-field.component.tsx +26 -0
  80. package/templates/ui/antd/src/components/common/fields/assets/components/multi-check-field.component.tsx +56 -0
  81. package/templates/ui/antd/src/components/common/fields/assets/components/number-field.component.tsx +100 -0
  82. package/templates/ui/antd/src/components/common/fields/assets/components/otp-field.component.tsx +63 -0
  83. package/templates/ui/antd/src/components/common/fields/assets/components/password-field.component.tsx +106 -0
  84. package/templates/ui/antd/src/components/common/fields/assets/components/phone-number-field.component.tsx +78 -0
  85. package/templates/ui/antd/src/components/common/fields/assets/components/radio-field.component.tsx +55 -0
  86. package/templates/ui/antd/src/components/common/fields/assets/components/range-date-picker.component.tsx +66 -0
  87. package/templates/ui/antd/src/components/common/fields/assets/components/search-field.component.tsx +24 -0
  88. package/templates/ui/antd/src/components/common/fields/assets/components/select-field.component.tsx +82 -0
  89. package/templates/ui/antd/src/components/common/fields/assets/components/single-check-field.component.tsx +50 -0
  90. package/templates/ui/antd/src/components/common/fields/assets/components/single-select-field.component.tsx +86 -0
  91. package/templates/ui/antd/src/components/common/fields/assets/components/string-number-field.component.tsx +80 -0
  92. package/templates/ui/antd/src/components/common/fields/assets/components/switch-field.component.tsx +62 -0
  93. package/templates/ui/antd/src/components/common/fields/assets/components/text-area-field.component.tsx +85 -0
  94. package/templates/ui/antd/src/components/common/fields/assets/components/text-field.component.tsx +88 -0
  95. package/templates/ui/antd/src/components/common/fields/assets/interface/input-props.type.ts +233 -0
  96. package/templates/ui/antd/src/components/common/fields/cusInputField.component.tsx +40 -0
  97. package/templates/ui/antd/src/components/common/pagination/pagination.component.tsx +27 -0
  98. package/templates/ui/antd/src/components/ui/avatar.component.tsx +8 -0
  99. package/templates/ui/antd/src/components/ui/badge.component.tsx +8 -0
  100. package/templates/ui/antd/src/components/ui/button.component.tsx +8 -0
  101. package/templates/ui/antd/src/components/ui/card.component.tsx +8 -0
  102. package/templates/ui/antd/src/components/ui/checkbox.component.tsx +8 -0
  103. package/templates/ui/antd/src/components/ui/dialog.component.tsx +9 -0
  104. package/templates/ui/antd/src/components/ui/dropdown-menu.component.tsx +10 -0
  105. package/templates/ui/antd/src/components/ui/form.component.tsx +12 -0
  106. package/templates/ui/antd/src/components/ui/input.component.tsx +13 -0
  107. package/templates/ui/antd/src/components/ui/label.component.tsx +18 -0
  108. package/templates/ui/antd/src/components/ui/popover.component.tsx +8 -0
  109. package/templates/ui/antd/src/components/ui/progress.component.tsx +8 -0
  110. package/templates/ui/antd/src/components/ui/radio-group.component.tsx +10 -0
  111. package/templates/ui/antd/src/components/ui/scroll-area.component.tsx +25 -0
  112. package/templates/ui/antd/src/components/ui/select.component.tsx +8 -0
  113. package/templates/ui/antd/src/components/ui/separator.component.tsx +8 -0
  114. package/templates/ui/antd/src/components/ui/sheet.component.tsx +8 -0
  115. package/templates/ui/antd/src/components/ui/switch.component.tsx +8 -0
  116. package/templates/ui/antd/src/components/ui/table.component.tsx +8 -0
  117. package/templates/ui/antd/src/components/ui/tabs.component.tsx +8 -0
  118. package/templates/ui/antd/src/components/ui/textarea.component.tsx +9 -0
  119. package/templates/ui/antd/src/components/ui/tooltip.component.tsx +8 -0
  120. package/templates/ui/antd/src/lib/theme.util.ts +40 -0
  121. package/templates/ui/antd/src/providers/antd.provider.tsx +13 -0
  122. package/templates/ui/mui/src/app/examples/layout.tsx +113 -0
  123. package/templates/ui/mui/src/app/examples/page.tsx +716 -0
  124. package/templates/ui/mui/src/app/page.tsx +298 -0
  125. package/templates/ui/mui/src/components/common/DynamicTable/dynamic-table.component.tsx +131 -0
  126. package/templates/ui/mui/src/components/common/button/action-button.component.tsx +57 -0
  127. package/templates/ui/mui/src/components/common/dialog/dialog-wrapper.component.tsx +55 -0
  128. package/templates/ui/mui/src/components/common/fields/assets/components/check-field.component.tsx +51 -0
  129. package/templates/ui/mui/src/components/common/fields/assets/components/date-picker-field.component.tsx +50 -0
  130. package/templates/ui/mui/src/components/common/fields/assets/components/multi-check-field.component.tsx +14 -0
  131. package/templates/ui/mui/src/components/common/fields/assets/components/number-field.component.tsx +59 -0
  132. package/templates/ui/mui/src/components/common/fields/assets/components/password-field.component.tsx +87 -0
  133. package/templates/ui/mui/src/components/common/fields/assets/components/phone-number-field.component.tsx +48 -0
  134. package/templates/ui/mui/src/components/common/fields/assets/components/radio-field.component.tsx +37 -0
  135. package/templates/ui/mui/src/components/common/fields/assets/components/search-field.component.tsx +41 -0
  136. package/templates/ui/mui/src/components/common/fields/assets/components/select-field.component.tsx +77 -0
  137. package/templates/ui/mui/src/components/common/fields/assets/components/single-check-field.component.tsx +39 -0
  138. package/templates/ui/mui/src/components/common/fields/assets/components/single-select-field.component.tsx +56 -0
  139. package/templates/ui/mui/src/components/common/fields/assets/components/string-number-field.component.tsx +52 -0
  140. package/templates/ui/mui/src/components/common/fields/assets/components/switch-field.component.tsx +35 -0
  141. package/templates/ui/mui/src/components/common/fields/assets/components/text-area-field.component.tsx +46 -0
  142. package/templates/ui/mui/src/components/common/fields/assets/components/text-field.component.tsx +51 -0
  143. package/templates/ui/mui/src/components/common/fields/assets/interface/input-props.type.ts +193 -0
  144. package/templates/ui/mui/src/components/common/fields/cusInputField.component.tsx +34 -0
  145. package/templates/ui/mui/src/components/common/pagination/pagination.component.tsx +59 -0
  146. package/templates/ui/mui/src/components/ui/avatar.component.tsx +19 -0
  147. package/templates/ui/mui/src/components/ui/badge.component.tsx +18 -0
  148. package/templates/ui/mui/src/components/ui/button.component.tsx +22 -0
  149. package/templates/ui/mui/src/components/ui/card.component.tsx +39 -0
  150. package/templates/ui/mui/src/components/ui/checkbox.component.tsx +21 -0
  151. package/templates/ui/mui/src/components/ui/dialog.component.tsx +38 -0
  152. package/templates/ui/mui/src/components/ui/dropdown-menu.component.tsx +43 -0
  153. package/templates/ui/mui/src/components/ui/form.component.tsx +98 -0
  154. package/templates/ui/mui/src/components/ui/input.component.tsx +15 -0
  155. package/templates/ui/mui/src/components/ui/label.component.tsx +15 -0
  156. package/templates/ui/mui/src/components/ui/popover.component.tsx +20 -0
  157. package/templates/ui/mui/src/components/ui/progress.component.tsx +19 -0
  158. package/templates/ui/mui/src/components/ui/radio-group.component.tsx +25 -0
  159. package/templates/ui/mui/src/components/ui/scroll-area.component.tsx +27 -0
  160. package/templates/ui/mui/src/components/ui/select.component.tsx +26 -0
  161. package/templates/ui/mui/src/components/ui/separator.component.tsx +11 -0
  162. package/templates/ui/mui/src/components/ui/sheet.component.tsx +44 -0
  163. package/templates/ui/mui/src/components/ui/switch.component.tsx +23 -0
  164. package/templates/ui/mui/src/components/ui/table.component.tsx +34 -0
  165. package/templates/ui/mui/src/components/ui/tabs.component.tsx +38 -0
  166. package/templates/ui/mui/src/components/ui/textarea.component.tsx +18 -0
  167. package/templates/ui/mui/src/components/ui/tooltip.component.tsx +24 -0
  168. package/templates/ui/mui/src/lib/theme.util.ts +73 -0
  169. package/templates/ui/mui/src/providers/mui.provider.tsx +13 -0
  170. package/templates/ui/shadcn/COMPONENT_GUIDE.md +306 -0
  171. package/templates/ui/shadcn/src/app/examples/dialog/page.tsx +122 -0
  172. package/templates/ui/shadcn/src/app/examples/form/page.tsx +107 -0
  173. package/templates/ui/shadcn/src/app/examples/layout.tsx +24 -0
  174. package/templates/ui/shadcn/src/app/examples/page.tsx +30 -0
  175. package/templates/ui/shadcn/src/app/examples/table/page.tsx +77 -0
  176. package/templates/ui/shadcn/src/app/page.tsx +20 -0
  177. package/templates/ui/shadcn/src/components/common/DynamicTable/dynamic-table.component.tsx +136 -0
  178. package/templates/ui/shadcn/src/components/common/button/action-button.component.tsx +68 -0
  179. package/templates/ui/shadcn/src/components/common/dialog/dialog-wrapper.component.tsx +58 -0
  180. package/templates/ui/shadcn/src/components/common/fields/assets/components/check-field.component.tsx +52 -0
  181. package/templates/ui/shadcn/src/components/common/fields/assets/components/date-picker-field.component.tsx +62 -0
  182. package/templates/ui/shadcn/src/components/common/fields/assets/components/dynamic-file-upload-field.component.tsx +152 -0
  183. package/templates/ui/shadcn/src/components/common/fields/assets/components/limit-field.component.tsx +73 -0
  184. package/templates/ui/shadcn/src/components/common/fields/assets/components/multi-check-field.component.tsx +46 -0
  185. package/templates/ui/shadcn/src/components/common/fields/assets/components/number-field.component.tsx +124 -0
  186. package/templates/ui/shadcn/src/components/common/fields/assets/components/otp-field.component.tsx +61 -0
  187. package/templates/ui/shadcn/src/components/common/fields/assets/components/password-field.component.tsx +110 -0
  188. package/templates/ui/shadcn/src/components/common/fields/assets/components/phone-number-field.component.tsx +90 -0
  189. package/templates/ui/shadcn/src/components/common/fields/assets/components/radio-field.component.tsx +41 -0
  190. package/templates/ui/shadcn/src/components/common/fields/assets/components/range-date-picker.component.tsx +71 -0
  191. package/templates/ui/shadcn/src/components/common/fields/assets/components/rich-text-editor.component.tsx +91 -0
  192. package/templates/ui/shadcn/src/components/common/fields/assets/components/search-field.component.tsx +34 -0
  193. package/templates/ui/shadcn/src/components/common/fields/assets/components/select-field.component.tsx +231 -0
  194. package/templates/ui/shadcn/src/components/common/fields/assets/components/single-check-field.component.tsx +42 -0
  195. package/templates/ui/shadcn/src/components/common/fields/assets/components/single-select-field.component.tsx +82 -0
  196. package/templates/ui/shadcn/src/components/common/fields/assets/components/string-number-field.component.tsx +68 -0
  197. package/templates/ui/shadcn/src/components/common/fields/assets/components/switch-field.component.tsx +61 -0
  198. package/templates/ui/shadcn/src/components/common/fields/assets/components/text-area-field.component.tsx +62 -0
  199. package/templates/ui/shadcn/src/components/common/fields/assets/components/text-area-with-file.component.tsx +142 -0
  200. package/templates/ui/shadcn/src/components/common/fields/assets/components/text-field.component.tsx +80 -0
  201. package/templates/ui/shadcn/src/components/common/fields/assets/components/tiny-editor.component.tsx +51 -0
  202. package/templates/ui/shadcn/src/components/common/fields/assets/components/upload-profile-picture.component.tsx +103 -0
  203. package/templates/ui/shadcn/src/components/common/fields/assets/components/upload-video-file.component.tsx +86 -0
  204. package/templates/ui/shadcn/src/components/common/fields/assets/interface/input-props.type.ts +198 -0
  205. package/templates/ui/shadcn/src/components/common/fields/cusInputField.component.tsx +52 -0
  206. package/templates/ui/shadcn/src/components/common/pagination/pagination.component.tsx +68 -0
  207. package/templates/ui/shadcn/src/components/ui/avatar.component.tsx +37 -0
  208. package/templates/ui/shadcn/src/components/ui/badge.component.tsx +28 -0
  209. package/templates/ui/shadcn/src/components/ui/button.component.tsx +52 -0
  210. package/templates/ui/shadcn/src/components/ui/card.component.tsx +46 -0
  211. package/templates/ui/shadcn/src/components/ui/checkbox.component.tsx +25 -0
  212. package/templates/ui/shadcn/src/components/ui/dialog.component.tsx +98 -0
  213. package/templates/ui/shadcn/src/components/ui/dropdown-menu.component.tsx +163 -0
  214. package/templates/ui/shadcn/src/components/ui/form.component.tsx +110 -0
  215. package/templates/ui/shadcn/src/components/ui/input-otp.component.tsx +64 -0
  216. package/templates/ui/shadcn/src/components/ui/input.component.tsx +23 -0
  217. package/templates/ui/shadcn/src/components/ui/label.component.tsx +23 -0
  218. package/templates/ui/shadcn/src/components/ui/popover.component.tsx +27 -0
  219. package/templates/ui/shadcn/src/components/ui/progress.component.tsx +22 -0
  220. package/templates/ui/shadcn/src/components/ui/radio-group.component.tsx +33 -0
  221. package/templates/ui/shadcn/src/components/ui/scroll-area.component.tsx +37 -0
  222. package/templates/ui/shadcn/src/components/ui/select.component.tsx +139 -0
  223. package/templates/ui/shadcn/src/components/ui/separator.component.tsx +23 -0
  224. package/templates/ui/shadcn/src/components/ui/sheet.component.tsx +89 -0
  225. package/templates/ui/shadcn/src/components/ui/switch.component.tsx +26 -0
  226. package/templates/ui/shadcn/src/components/ui/table.component.tsx +71 -0
  227. package/templates/ui/shadcn/src/components/ui/tabs.component.tsx +52 -0
  228. package/templates/ui/shadcn/src/components/ui/textarea.component.tsx +20 -0
  229. package/templates/ui/shadcn/src/components/ui/tooltip.component.tsx +25 -0
@@ -0,0 +1,326 @@
1
+ # Ant Design Component System
2
+
3
+ This template includes a comprehensive reusable component system built on **Ant Design 5**.
4
+
5
+ ## Architecture
6
+
7
+ ```
8
+ src/components/
9
+ ├── common/
10
+ │ ├── button/
11
+ │ │ └── action-button.component.tsx # Button + Tooltip + Loading
12
+ │ ├── dialog/
13
+ │ │ └── dialog-wrapper.component.tsx # Scrollable modal wrapper
14
+ │ ├── DynamicTable/
15
+ │ │ └── dynamic-table.component.tsx # Config-driven table
16
+ │ ├── fields/
17
+ │ │ ├── assets/
18
+ │ │ │ ├── components/ # Individual field components
19
+ │ │ │ └── interface/
20
+ │ │ │ └── input-props.type.ts # Shared type definitions
21
+ │ │ └── cusInputField.component.tsx # CustomField barrel export
22
+ │ └── pagination/
23
+ │ └── pagination.component.tsx # Page navigation
24
+ └── ui/ # Base primitives (22 components)
25
+ ├── avatar.component.tsx
26
+ ├── badge.component.tsx
27
+ ├── button.component.tsx
28
+ ├── card.component.tsx
29
+ ├── checkbox.component.tsx
30
+ ├── dialog.component.tsx # Ant Design Modal wrapper
31
+ ├── dropdown-menu.component.tsx # Ant Design Dropdown wrapper
32
+ ├── form.component.tsx # Ant Design Form + Form.Item
33
+ ├── input.component.tsx # Input + TextArea + OTP + Password + Search
34
+ ├── label.component.tsx
35
+ ├── popover.component.tsx
36
+ ├── progress.component.tsx
37
+ ├── radio-group.component.tsx
38
+ ├── scroll-area.component.tsx
39
+ ├── select.component.tsx
40
+ ├── separator.component.tsx # Ant Design Divider wrapper
41
+ ├── sheet.component.tsx # Ant Design Drawer wrapper
42
+ ├── switch.component.tsx
43
+ ├── table.component.tsx
44
+ ├── tabs.component.tsx
45
+ ├── textarea.component.tsx
46
+ └── tooltip.component.tsx
47
+ ```
48
+
49
+ ---
50
+
51
+ ## CustomField System
52
+
53
+ The `CustomField` compound object provides 17 field types. Every field supports **dual-mode**:
54
+
55
+ - **With `form` prop**: Integrates with `react-hook-form` via `<Controller>` for validation/errors.
56
+ - **Without `form` prop**: Renders standalone using `value`/`setValue` props.
57
+
58
+ ### Import
59
+
60
+ ```tsx
61
+ import { CustomField } from '@/components/common/fields/cusInputField.component';
62
+ ```
63
+
64
+ ### Available Fields
65
+
66
+ | Field | Component | Description |
67
+ |-------|-----------|-------------|
68
+ | Text | `CustomField.Text` | Single-line text input |
69
+ | TextArea | `CustomField.TextArea` | Multi-line text area with optional `maxLength`/`showCount` |
70
+ | Number | `CustomField.Number` | Numeric input with `numberType` (`float`/`integer`), `min`, `max`, `step` |
71
+ | StringNumber | `CustomField.StringNumber` | Text input that only allows digits and decimals |
72
+ | Password | `CustomField.Password` | Password input with show/hide toggle; `mode="validate"` adds confirm field |
73
+ | SingleSelectField | `CustomField.SingleSelectField` | Dropdown select from string array |
74
+ | SelectField | `CustomField.SelectField` | Advanced select with `single`/`multiple`, search, images, flags |
75
+ | SwitchField | `CustomField.SwitchField` | Toggle switch with optional description and border |
76
+ | RadioField | `CustomField.RadioField` | Radio button group |
77
+ | CheckField | `CustomField.CheckField` | Checkbox group |
78
+ | MultiCheckField | `CustomField.MultiCheckField` | Multi-select checkbox group (alias for CheckField) |
79
+ | SingleCheckField | `CustomField.SingleCheckField` | Single checkbox with label |
80
+ | SearchField | `CustomField.SearchField` | Search input with clear and enter-button |
81
+ | DatePickerField | `CustomField.DatePickerField` | Date picker with `picker` prop (`date`, `week`, `month`, `quarter`, `year`) |
82
+ | RangeDatePicker | `CustomField.RangeDatePicker` | Date range picker |
83
+ | PhoneNumber | `CustomField.PhoneNumber` | Phone number text input (type="tel") |
84
+ | OTP | `CustomField.OTP` | OTP input with configurable `length` |
85
+ | LimitField | `CustomField.LimitField` | Per-page limit selector for pagination |
86
+
87
+ ### Dual-mode Example
88
+
89
+ ```tsx
90
+ // With react-hook-form (recommended)
91
+ <CustomField.Text
92
+ form={form}
93
+ name="fullName"
94
+ labelName="Full Name"
95
+ placeholder="Enter your name"
96
+ required
97
+ />
98
+
99
+ // Standalone (without form)
100
+ <CustomField.Text
101
+ labelName="Full Name"
102
+ value={name}
103
+ setValue={setName}
104
+ />
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Common Components
110
+
111
+ ### ActionButton
112
+
113
+ A button component with icon positions, loading spinner, and optional Ant Design Tooltip.
114
+
115
+ ```tsx
116
+ import { ActionButton } from '@/components/common/button/action-button.component';
117
+
118
+ // Basic
119
+ <ActionButton buttonContent="Save" variant="primary" />
120
+
121
+ // With loading state
122
+ <ActionButton buttonContent="Saving..." isPending variant="primary" />
123
+
124
+ // With icons
125
+ <ActionButton
126
+ buttonContent="Add User"
127
+ icon={<PlusOutlined />}
128
+ lastIcon={<ArrowRightOutlined />}
129
+ variant="primary"
130
+ />
131
+
132
+ // With tooltip
133
+ <ActionButton
134
+ buttonContent="Delete"
135
+ variant="primary"
136
+ danger
137
+ tooltipContent="Permanently delete this item"
138
+ side="top"
139
+ />
140
+
141
+ // Submit button
142
+ <ActionButton htmlType="submit" buttonContent="Submit" variant="primary" />
143
+ ```
144
+
145
+ **Props:**
146
+
147
+ | Prop | Type | Default | Description |
148
+ |------|------|---------|-------------|
149
+ | `variant` | `'primary' \| 'dashed' \| 'link' \| 'text' \| 'default'` | `'primary'` | Button variant |
150
+ | `btnSize` | `'small' \| 'middle' \| 'large'` | `'middle'` | Button size |
151
+ | `danger` | `boolean` | `false` | Danger styling |
152
+ | `isPending` | `boolean` | `false` | Show loading spinner |
153
+ | `icon` | `ReactNode` | - | Icon before content |
154
+ | `lastIcon` | `ReactNode` | - | Icon after content |
155
+ | `tooltipContent` | `string` | - | Tooltip text (wraps in Tooltip) |
156
+ | `side` | `'top' \| 'right' \| 'bottom' \| 'left'` | `'top'` | Tooltip placement |
157
+ | `htmlType` | `'submit' \| 'button' \| 'reset'` | `'button'` | HTML button type |
158
+ | `handleOpen` | `function` | - | Click handler |
159
+ | `disabled` | `boolean` | `false` | Disabled state |
160
+ | `ghost` | `boolean` | - | Ghost mode |
161
+ | `block` | `boolean` | - | Full-width block |
162
+
163
+ ---
164
+
165
+ ### DialogWrapper
166
+
167
+ A scrollable modal with sticky header, close button, optional trigger content, and footer slot.
168
+
169
+ ```tsx
170
+ import { DialogWrapper } from '@/components/common/dialog/dialog-wrapper.component';
171
+
172
+ const [open, setOpen] = useState(false);
173
+
174
+ <DialogWrapper
175
+ open={open}
176
+ setOpen={setOpen}
177
+ title="Dialog Title"
178
+ description="Optional description"
179
+ footer={
180
+ <Space>
181
+ <ActionButton variant="default" buttonContent="Cancel" handleOpen={() => setOpen(false)} />
182
+ <ActionButton variant="primary" buttonContent="Confirm" />
183
+ </Space>
184
+ }
185
+ >
186
+ <p>Your content here — scrollable if long.</p>
187
+ </DialogWrapper>
188
+ ```
189
+
190
+ **Props:**
191
+
192
+ | Prop | Type | Default | Description |
193
+ |------|------|---------|-------------|
194
+ | `open` | `boolean` | required | Visibility state |
195
+ | `setOpen` | `function` | required | State setter |
196
+ | `triggerContent` | `ReactNode` | - | Optional trigger element |
197
+ | `title` | `ReactNode` | - | Modal title |
198
+ | `description` | `string` | - | Subtitle text |
199
+ | `children` | `ReactNode` | required | Modal body content |
200
+ | `closer` | `boolean` | `true` | Show close button |
201
+ | `footer` | `ReactNode` | - | Footer content |
202
+ | `width` | `number \| string` | `520` | Modal width |
203
+
204
+ ---
205
+
206
+ ### DynamicTable
207
+
208
+ A config-driven table built on Ant Design Table.
209
+
210
+ ```tsx
211
+ import { DynamicTable, type TableColumn } from '@/components/common/DynamicTable/dynamic-table.component';
212
+
213
+ const columns: TableColumn[] = [
214
+ { key: 'name', header: 'Name' },
215
+ { key: 'email', header: 'Email' },
216
+ { key: 'role', header: 'Role', render: (item) => <Tag>{item.role}</Tag> },
217
+ ];
218
+
219
+ <DynamicTable
220
+ data={data}
221
+ isLoading={isLoading}
222
+ config={{ columns, emptyMessage: 'No users found' }}
223
+ isCheckBox
224
+ selectedIds={selectedIds}
225
+ setSelectedIds={setSelectedIds}
226
+ rowKey="id"
227
+ />
228
+ ```
229
+
230
+ **Props:**
231
+
232
+ | Prop | Type | Default | Description |
233
+ |------|------|---------|-------------|
234
+ | `data` | `any[]` | required | Table data |
235
+ | `isLoading` | `boolean` | required | Loading state |
236
+ | `config` | `TableConfig` | required | Column definitions |
237
+ | `isCheckBox` | `boolean` | `false` | Enable row checkbox selection |
238
+ | `selectedIds` | `string[]` | `[]` | Controlled selected row IDs |
239
+ | `setSelectedIds` | `function` | noop | Selected IDs setter |
240
+ | `setSelectObject` | `function` | noop | Full selected row objects setter |
241
+ | `rowKey` | `string` | `'id'` | Unique ID field name |
242
+
243
+ ---
244
+
245
+ ### Pagination
246
+
247
+ Page navigation using Ant Design Pagination.
248
+
249
+ ```tsx
250
+ import { Pagination } from '@/components/common/pagination/pagination.component';
251
+
252
+ <Pagination
253
+ currentPage={currentPage}
254
+ totalPages={totalPages}
255
+ setCurrentPage={setCurrentPage}
256
+ total={totalItems}
257
+ />
258
+ ```
259
+
260
+ **Props:**
261
+
262
+ | Prop | Type | Default | Description |
263
+ |------|------|---------|-------------|
264
+ | `currentPage` | `number` | required | Current active page |
265
+ | `totalPages` | `number` | required | Total number of pages |
266
+ | `setCurrentPage` | `function` | required | Page setter |
267
+ | `total` | `number` | - | Total items (for display) |
268
+
269
+ ---
270
+
271
+ ## UI Primitives
272
+
273
+ Each primitive in `src/components/ui/` is a thin re-export of an Ant Design component with consistent naming.
274
+ Import directly from their respective files:
275
+
276
+ ```tsx
277
+ import { Button } from '@/components/ui/button.component';
278
+ import { Card } from '@/components/ui/card.component';
279
+ import { Tabs } from '@/components/ui/tabs.component';
280
+ import { Table } from '@/components/ui/table.component';
281
+ // etc.
282
+ ```
283
+
284
+ ### Full List
285
+
286
+ | Component | Ant Design Equivalent | File |
287
+ |-----------|----------------------|------|
288
+ | `Avatar` | `Avatar` | `avatar.component.tsx` |
289
+ | `Badge` | `Badge` | `badge.component.tsx` |
290
+ | `Button` | `Button` | `button.component.tsx` |
291
+ | `Card` | `Card` | `card.component.tsx` |
292
+ | `Checkbox` | `Checkbox` | `checkbox.component.tsx` |
293
+ | `Dialog` | `Modal` | `dialog.component.tsx` |
294
+ | `DropdownMenu` | `Dropdown` | `dropdown-menu.component.tsx` |
295
+ | `Form`, `FormItem` | `Form`, `Form.Item` | `form.component.tsx` |
296
+ | `Input` | `Input` | `input.component.tsx` |
297
+ | `Label` | `Typography.Text` | `label.component.tsx` |
298
+ | `Popover` | `Popover` | `popover.component.tsx` |
299
+ | `Progress` | `Progress` | `progress.component.tsx` |
300
+ | `RadioGroup` | `Radio.Group` | `radio-group.component.tsx` |
301
+ | `ScrollArea` | Custom scrollable div | `scroll-area.component.tsx` |
302
+ | `Select` | `Select` | `select.component.tsx` |
303
+ | `Separator` | `Divider` | `separator.component.tsx` |
304
+ | `Sheet` | `Drawer` | `sheet.component.tsx` |
305
+ | `Switch` | `Switch` | `switch.component.tsx` |
306
+ | `Table` | `Table` | `table.component.tsx` |
307
+ | `Tabs` | `Tabs` | `tabs.component.tsx` |
308
+ | `Textarea` | `Input.TextArea` | `textarea.component.tsx` |
309
+ | `Tooltip` | `Tooltip` | `tooltip.component.tsx` |
310
+
311
+ ---
312
+
313
+ ## Theme
314
+
315
+ The Ant Design theme is configured in `src/lib/theme.util.ts` using the `ThemeConfig` API.
316
+ The `AntdProvider` in `src/providers/antd.provider.tsx` wraps the app with `<ConfigProvider>`.
317
+
318
+ ```tsx
319
+ // Customize in src/lib/theme.util.ts
320
+ export const themeConfig: ThemeConfig = {
321
+ token: {
322
+ colorPrimary: '#1677ff',
323
+ borderRadius: 6,
324
+ },
325
+ };
326
+ ```
@@ -0,0 +1,205 @@
1
+ 'use client';
2
+
3
+ import { useState } from 'react';
4
+ import { Typography, Space, Tag, Card, Row, Col, Divider, theme } from 'antd';
5
+ import {
6
+ EditOutlined, DeleteOutlined, PlusOutlined,
7
+ InfoCircleOutlined, CheckCircleOutlined, WarningOutlined,
8
+ } from '@ant-design/icons';
9
+ import { DialogWrapper } from '@/components/common/dialog/dialog-wrapper.component';
10
+ import { ActionButton } from '@/components/common/button/action-button.component';
11
+ import { Pagination } from '@/components/common/pagination/pagination.component';
12
+
13
+ const { Title, Text, Paragraph } = Typography;
14
+
15
+ const sampleItems = Array.from({ length: 25 }, (_, i) => ({
16
+ id: i + 1,
17
+ title: `Item ${i + 1}`,
18
+ status: ['Active', 'Pending', 'Archived'][i % 3],
19
+ }));
20
+
21
+ export default function DialogExamplePage() {
22
+ const { token } = theme.useToken();
23
+ const [basicOpen, setBasicOpen] = useState(false);
24
+ const [confirmOpen, setConfirmOpen] = useState(false);
25
+ const [currentPage, setCurrentPage] = useState(1);
26
+ const perPage = 5;
27
+ const totalPages = Math.ceil(sampleItems.length / perPage);
28
+ const paginatedItems = sampleItems.slice((currentPage - 1) * perPage, currentPage * perPage);
29
+
30
+ const getStatusColor = (status: string) => {
31
+ switch (status) {
32
+ case 'Active': return 'green';
33
+ case 'Pending': return 'orange';
34
+ case 'Archived': return 'default';
35
+ default: return 'default';
36
+ }
37
+ };
38
+
39
+ return (
40
+ <div style={{ maxWidth: 960, margin: '0 auto', padding: 32 }}>
41
+ <div style={{ marginBottom: 24 }}>
42
+ <Title level={2} style={{ fontWeight: 800, margin: 0 }}>Dialog, ActionButton & Pagination Demo</Title>
43
+ <Text type="secondary" style={{ fontSize: 15, display: 'block', marginTop: 4 }}>
44
+ Reusable DialogWrapper with sticky header, ActionButton variants with tooltips, and pagination.
45
+ </Text>
46
+ </div>
47
+
48
+ {/* ActionButton Variants */}
49
+ <Card title="ActionButton Variants" style={{ borderRadius: 12, marginBottom: 24 }} variant="outlined">
50
+ <Space wrap size="middle">
51
+ <ActionButton
52
+ variant="primary"
53
+ icon={<InfoCircleOutlined />}
54
+ buttonContent="Info"
55
+ tooltipContent="Default primary variant"
56
+ />
57
+ <ActionButton
58
+ variant="primary"
59
+ danger
60
+ icon={<DeleteOutlined />}
61
+ buttonContent="Delete"
62
+ tooltipContent="Danger variant"
63
+ />
64
+ <ActionButton
65
+ variant="default"
66
+ icon={<EditOutlined />}
67
+ buttonContent="Edit"
68
+ tooltipContent="Default variant"
69
+ />
70
+ <ActionButton
71
+ variant="dashed"
72
+ icon={<PlusOutlined />}
73
+ buttonContent="Add"
74
+ tooltipContent="Dashed variant"
75
+ />
76
+ <ActionButton
77
+ variant="text"
78
+ icon={<WarningOutlined />}
79
+ buttonContent="Warn"
80
+ tooltipContent="Text variant"
81
+ />
82
+ <ActionButton
83
+ variant="link"
84
+ icon={<CheckCircleOutlined />}
85
+ buttonContent="Confirm"
86
+ tooltipContent="Link variant"
87
+ />
88
+ </Space>
89
+ </Card>
90
+
91
+ {/* Loading State */}
92
+ <Card title="ActionButton States" style={{ borderRadius: 12, marginBottom: 24 }} variant="outlined">
93
+ <Space wrap size="middle">
94
+ <ActionButton
95
+ buttonContent="Save Changes"
96
+ isPending
97
+ variant="primary"
98
+ />
99
+ <ActionButton
100
+ buttonContent="Disabled"
101
+ disabled
102
+ variant="default"
103
+ />
104
+ <ActionButton
105
+ buttonContent="With Icon"
106
+ icon={<PlusOutlined />}
107
+ variant="primary"
108
+ />
109
+ <ActionButton
110
+ buttonContent="Icon After"
111
+ lastIcon={<EditOutlined />}
112
+ variant="default"
113
+ />
114
+ </Space>
115
+ </Card>
116
+
117
+ {/* Dialogs */}
118
+ <Row gutter={[16, 16]} style={{ marginBottom: 24 }}>
119
+ <Col xs={24} md={12}>
120
+ <Card title="Basic Dialog" style={{ borderRadius: 12 }} variant="outlined">
121
+ <ActionButton
122
+ buttonContent="Open Dialog"
123
+ variant="primary"
124
+ handleOpen={() => setBasicOpen(true)}
125
+ />
126
+ </Card>
127
+ </Col>
128
+ <Col xs={24} md={12}>
129
+ <Card title="Confirmation Dialog" style={{ borderRadius: 12 }} variant="outlined">
130
+ <ActionButton
131
+ buttonContent="Confirm Action"
132
+ variant="default"
133
+ danger
134
+ icon={<DeleteOutlined />}
135
+ handleOpen={() => setConfirmOpen(true)}
136
+ />
137
+ </Card>
138
+ </Col>
139
+ </Row>
140
+
141
+ <DialogWrapper
142
+ open={basicOpen}
143
+ setOpen={setBasicOpen}
144
+ title="Basic Dialog"
145
+ description="This is a reusable dialog wrapper with a sticky header and close button."
146
+ footer={
147
+ <Space>
148
+ <ActionButton variant="default" buttonContent="Cancel" handleOpen={() => setBasicOpen(false)} />
149
+ <ActionButton variant="primary" buttonContent="Confirm" handleOpen={() => { alert('Confirmed!'); setBasicOpen(false); }} />
150
+ </Space>
151
+ }
152
+ >
153
+ <Paragraph>
154
+ This dialog content area is scrollable. The header and footer remain sticky.
155
+ The close button in the top-right corner dismisses the dialog.
156
+ </Paragraph>
157
+ <Paragraph>
158
+ DialogWrapper uses Ant Design Modal under the hood with a polished scrollable body,
159
+ sticky header with title and description, and an optional footer slot.
160
+ </Paragraph>
161
+ </DialogWrapper>
162
+
163
+ <DialogWrapper
164
+ open={confirmOpen}
165
+ setOpen={setConfirmOpen}
166
+ title="Confirm Delete"
167
+ description="Are you sure you want to delete this item? This action cannot be undone."
168
+ footer={
169
+ <Space>
170
+ <ActionButton variant="default" buttonContent="Cancel" handleOpen={() => setConfirmOpen(false)} />
171
+ <ActionButton variant="primary" danger buttonContent="Delete" handleOpen={() => { alert('Deleted!'); setConfirmOpen(false); }} />
172
+ </Space>
173
+ }
174
+ >
175
+ <Paragraph>
176
+ <WarningOutlined style={{ color: token.colorWarning, marginRight: 8 }} />
177
+ This action is irreversible. All associated data will be permanently removed.
178
+ </Paragraph>
179
+ </DialogWrapper>
180
+
181
+ {/* Pagination */}
182
+ <Card title="Pagination" style={{ borderRadius: 12 }} variant="outlined">
183
+ <div style={{ marginBottom: 16 }}>
184
+ {paginatedItems.map((item) => (
185
+ <div key={item.id} style={{
186
+ display: 'flex', justifyContent: 'space-between',
187
+ alignItems: 'center', padding: '8px 12px',
188
+ borderBottom: `1px solid ${token.colorBorderSecondary}`,
189
+ }}>
190
+ <Text>{item.title}</Text>
191
+ <Tag color={getStatusColor(item.status)} style={{ borderRadius: 6 }}>
192
+ {item.status}
193
+ </Tag>
194
+ </div>
195
+ ))}
196
+ </div>
197
+ <Pagination
198
+ currentPage={currentPage}
199
+ totalPages={totalPages}
200
+ setCurrentPage={setCurrentPage}
201
+ />
202
+ </Card>
203
+ </div>
204
+ );
205
+ }
@@ -0,0 +1,160 @@
1
+ 'use client';
2
+
3
+ import { useForm } from 'react-hook-form';
4
+ import { zodResolver } from '@hookform/resolvers/zod';
5
+ import { z } from 'zod';
6
+ import { Typography, Divider, Row, Col, Card, Space, theme } from 'antd';
7
+ import { CustomField } from '@/components/common/fields/cusInputField.component';
8
+ import { ActionButton } from '@/components/common/button/action-button.component';
9
+
10
+ const { Title, Text } = Typography;
11
+
12
+ const formSchema = z.object({
13
+ fullName: z.string().min(2, 'Name must be at least 2 characters'),
14
+ bio: z.string().optional(),
15
+ age: z.coerce.number().min(1, 'Required').max(150),
16
+ phone: z.string().optional(),
17
+ password: z.string().min(6, 'Min 6 characters'),
18
+ role: z.string().min(1, 'Select a role'),
19
+ notify: z.boolean().optional(),
20
+ acceptTerms: z.boolean().refine((v) => v === true, 'You must accept'),
21
+ });
22
+
23
+ type FormValues = z.infer<typeof formSchema>;
24
+
25
+ export default function FormExamplePage() {
26
+ const { token } = theme.useToken();
27
+ const form = useForm<FormValues>({
28
+ resolver: zodResolver(formSchema),
29
+ defaultValues: {
30
+ fullName: '', bio: '', age: undefined, phone: '',
31
+ password: '', role: '', notify: false, acceptTerms: false,
32
+ },
33
+ });
34
+
35
+ const onSubmit = (data: FormValues) => alert(JSON.stringify(data, null, 2));
36
+
37
+ return (
38
+ <div style={{ maxWidth: 900, margin: '0 auto', padding: 32 }}>
39
+ <div style={{ marginBottom: 24 }}>
40
+ <Title level={2} style={{ fontWeight: 800, margin: 0 }}>CustomField Form Demo</Title>
41
+ <Text type="secondary" style={{ fontSize: 15, display: 'block', marginTop: 4 }}>
42
+ All field types with react-hook-form + Zod validation.
43
+ </Text>
44
+ </div>
45
+
46
+ <Card style={{ borderRadius: 12 }} variant="outlined">
47
+ <form onSubmit={form.handleSubmit(onSubmit)}>
48
+ <Row gutter={[24, 0]}>
49
+ <Col xs={24} md={12}>
50
+ <CustomField.Text
51
+ form={form}
52
+ name="fullName"
53
+ labelName="Full Name"
54
+ placeholder="Enter your name"
55
+ required
56
+ />
57
+ </Col>
58
+ <Col xs={24} md={12}>
59
+ <CustomField.Number
60
+ form={form}
61
+ name="age"
62
+ labelName="Age"
63
+ numberType="integer"
64
+ placeholder="Enter age"
65
+ required
66
+ />
67
+ </Col>
68
+ <Col xs={24}>
69
+ <CustomField.TextArea
70
+ form={form}
71
+ name="bio"
72
+ labelName="Biography"
73
+ placeholder="Tell us about yourself"
74
+ rows={3}
75
+ />
76
+ </Col>
77
+ <Col xs={24} md={12}>
78
+ <CustomField.PhoneNumber
79
+ form={form}
80
+ name="phone"
81
+ labelName="Phone Number"
82
+ placeholder="+1 (555) 123-4567"
83
+ />
84
+ </Col>
85
+ <Col xs={24} md={12}>
86
+ <CustomField.Password
87
+ form={form}
88
+ name="password"
89
+ labelName="Password"
90
+ placeholder="Min 6 characters"
91
+ required
92
+ />
93
+ </Col>
94
+ <Col xs={24} md={12}>
95
+ <CustomField.SelectField
96
+ form={form}
97
+ name="role"
98
+ labelName="Role"
99
+ placeholder="Select role"
100
+ required
101
+ options={[
102
+ { value: 'admin', label: 'Admin' },
103
+ { value: 'editor', label: 'Editor' },
104
+ { value: 'viewer', label: 'Viewer' },
105
+ ]}
106
+ />
107
+ </Col>
108
+ <Col xs={24} md={12}>
109
+ <CustomField.SingleSelectField
110
+ form={form}
111
+ name="department"
112
+ labelName="Department"
113
+ placeholder="Select department"
114
+ options={['Engineering', 'Design', 'Marketing', 'Sales']}
115
+ />
116
+ </Col>
117
+ </Row>
118
+
119
+ <Divider />
120
+
121
+ <Row gutter={[24, 0]}>
122
+ <Col xs={24} md={12}>
123
+ <CustomField.SwitchField
124
+ form={form}
125
+ name="notify"
126
+ labelName="Enable Notifications"
127
+ description="Receive email updates about your account"
128
+ border
129
+ />
130
+ </Col>
131
+ <Col xs={24} md={12}>
132
+ <CustomField.SingleCheckField
133
+ form={form}
134
+ name="acceptTerms"
135
+ labelName="I accept the terms and conditions"
136
+ required
137
+ />
138
+ </Col>
139
+ </Row>
140
+
141
+ <Divider />
142
+
143
+ <Space>
144
+ <ActionButton
145
+ htmlType="submit"
146
+ buttonContent="Submit"
147
+ variant="primary"
148
+ isPending={form.formState.isSubmitting}
149
+ />
150
+ <ActionButton
151
+ buttonContent="Reset"
152
+ variant="default"
153
+ handleOpen={() => form.reset()}
154
+ />
155
+ </Space>
156
+ </form>
157
+ </Card>
158
+ </div>
159
+ );
160
+ }