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.
- package/AGENTS.md +122 -0
- package/LICENSE +21 -0
- package/README.md +103 -0
- package/package.json +99 -0
- package/scaffold/generator.js +409 -0
- package/scaffold/index.js +20 -0
- package/scaffold/prompts.js +108 -0
- package/templates/api/axios/src/api/axios/client.api.ts +30 -0
- package/templates/api/axios/src/api/axios/users.api.ts +15 -0
- package/templates/api/fetch/src/api/fetch/client.api.ts +68 -0
- package/templates/api/fetch/src/api/fetch/users.api.ts +15 -0
- package/templates/api/trpc/src/api/trpc/client.api.ts +4 -0
- package/templates/api/trpc/src/api/trpc/router.api.ts +15 -0
- package/templates/api/trpc/src/api/trpc/server.client.api.ts +4 -0
- package/templates/api/trpc/src/providers/trpc.provider.tsx +24 -0
- package/templates/auth/clerk/src/auth/clerk/auth.service.ts +4 -0
- package/templates/auth/clerk/src/hooks/use-auth.hook.ts +13 -0
- package/templates/auth/clerk/src/middleware.ts +7 -0
- package/templates/auth/clerk/src/providers/auth.provider.tsx +6 -0
- package/templates/auth/next-auth/src/app/api/auth/[...nextauth]/route.ts +5 -0
- package/templates/auth/next-auth/src/auth/next-auth/auth.service.ts +45 -0
- package/templates/auth/next-auth/src/hooks/use-session.hook.ts +13 -0
- package/templates/auth/next-auth/src/providers/session.provider.tsx +6 -0
- package/templates/forms/formik/src/components/forms/login-form.component.tsx +30 -0
- package/templates/forms/formik/src/forms/formik/hooks/use-form-config.hook.ts +7 -0
- package/templates/forms/formik/src/forms/formik/schemas/example.schema.ts +8 -0
- package/templates/forms/react-hook-form/src/components/forms/login-form.component.tsx +27 -0
- package/templates/forms/react-hook-form/src/forms/react-hook-form/hooks/use-form.hook.ts +13 -0
- package/templates/forms/react-hook-form/src/forms/react-hook-form/schemas/example.schema.ts +15 -0
- package/templates/nextjs-base/next.config.ts +5 -0
- package/templates/nextjs-base/postcss.config.mjs +9 -0
- package/templates/nextjs-base/src/app/_components/navbar.tsx +88 -0
- package/templates/nextjs-base/src/app/_components/sidebar.tsx +223 -0
- package/templates/nextjs-base/src/app/error.tsx +39 -0
- package/templates/nextjs-base/src/app/globals.css +71 -0
- package/templates/nextjs-base/src/app/layout.tsx +21 -0
- package/templates/nextjs-base/src/app/loading.tsx +13 -0
- package/templates/nextjs-base/src/app/not-found.tsx +22 -0
- package/templates/nextjs-base/src/app/page.tsx +10 -0
- package/templates/nextjs-base/tailwind.config.ts +69 -0
- package/templates/shared/src/components/common/theme-toggle.component.tsx +31 -0
- package/templates/shared/src/components/common/toast/custom-message.component.tsx +18 -0
- package/templates/shared/src/components/common/toast/index.ts +8 -0
- package/templates/shared/src/components/common/toast/toast-message.component.tsx +112 -0
- package/templates/shared/src/hooks/use-debounce.hook.ts +12 -0
- package/templates/shared/src/hooks/use-fetch.hook.ts +42 -0
- package/templates/shared/src/hooks/use-intersection-observer.hook.ts +39 -0
- package/templates/shared/src/hooks/use-local-storage.hook.ts +30 -0
- package/templates/shared/src/hooks/use-media-query.hook.ts +26 -0
- package/templates/shared/src/hooks/use-toggle.hook.ts +12 -0
- package/templates/shared/src/lib/utils.util.ts +361 -0
- package/templates/shared/src/providers/theme.provider.tsx +17 -0
- package/templates/shared/src/providers/toast.provider.tsx +32 -0
- package/templates/shared/src/types/common.type.ts +34 -0
- package/templates/state/context/src/store/context/auth.context.tsx +47 -0
- package/templates/state/context/src/store/context/counter.context.tsx +41 -0
- package/templates/state/context/src/store/context/index.ts +2 -0
- package/templates/state/redux/src/providers/redux.provider.tsx +7 -0
- package/templates/state/redux/src/store/redux/hooks.store.ts +5 -0
- package/templates/state/redux/src/store/redux/index.ts +4 -0
- package/templates/state/redux/src/store/redux/slices/api.slice.ts +8 -0
- package/templates/state/redux/src/store/redux/slices/counter.slice.ts +24 -0
- package/templates/state/redux/src/store/redux/store.store.ts +13 -0
- package/templates/state/zustand/src/store/zustand/counter.store.ts +15 -0
- package/templates/state/zustand/src/store/zustand/index.ts +2 -0
- package/templates/state/zustand/src/store/zustand/user.store.ts +32 -0
- package/templates/ui/antd/COMPONENT_GUIDE.md +326 -0
- package/templates/ui/antd/src/app/examples/dialog/page.tsx +205 -0
- package/templates/ui/antd/src/app/examples/form/page.tsx +160 -0
- package/templates/ui/antd/src/app/examples/layout.tsx +125 -0
- package/templates/ui/antd/src/app/examples/page.tsx +64 -0
- package/templates/ui/antd/src/app/examples/table/page.tsx +118 -0
- package/templates/ui/antd/src/app/page.tsx +283 -0
- package/templates/ui/antd/src/components/common/DynamicTable/dynamic-table.component.tsx +79 -0
- package/templates/ui/antd/src/components/common/button/action-button.component.tsx +63 -0
- package/templates/ui/antd/src/components/common/dialog/dialog-wrapper.component.tsx +63 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/check-field.component.tsx +55 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/date-picker-field.component.tsx +80 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/limit-field.component.tsx +26 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/multi-check-field.component.tsx +56 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/number-field.component.tsx +100 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/otp-field.component.tsx +63 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/password-field.component.tsx +106 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/phone-number-field.component.tsx +78 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/radio-field.component.tsx +55 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/range-date-picker.component.tsx +66 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/search-field.component.tsx +24 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/select-field.component.tsx +82 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/single-check-field.component.tsx +50 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/single-select-field.component.tsx +86 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/string-number-field.component.tsx +80 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/switch-field.component.tsx +62 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/text-area-field.component.tsx +85 -0
- package/templates/ui/antd/src/components/common/fields/assets/components/text-field.component.tsx +88 -0
- package/templates/ui/antd/src/components/common/fields/assets/interface/input-props.type.ts +233 -0
- package/templates/ui/antd/src/components/common/fields/cusInputField.component.tsx +40 -0
- package/templates/ui/antd/src/components/common/pagination/pagination.component.tsx +27 -0
- package/templates/ui/antd/src/components/ui/avatar.component.tsx +8 -0
- package/templates/ui/antd/src/components/ui/badge.component.tsx +8 -0
- package/templates/ui/antd/src/components/ui/button.component.tsx +8 -0
- package/templates/ui/antd/src/components/ui/card.component.tsx +8 -0
- package/templates/ui/antd/src/components/ui/checkbox.component.tsx +8 -0
- package/templates/ui/antd/src/components/ui/dialog.component.tsx +9 -0
- package/templates/ui/antd/src/components/ui/dropdown-menu.component.tsx +10 -0
- package/templates/ui/antd/src/components/ui/form.component.tsx +12 -0
- package/templates/ui/antd/src/components/ui/input.component.tsx +13 -0
- package/templates/ui/antd/src/components/ui/label.component.tsx +18 -0
- package/templates/ui/antd/src/components/ui/popover.component.tsx +8 -0
- package/templates/ui/antd/src/components/ui/progress.component.tsx +8 -0
- package/templates/ui/antd/src/components/ui/radio-group.component.tsx +10 -0
- package/templates/ui/antd/src/components/ui/scroll-area.component.tsx +25 -0
- package/templates/ui/antd/src/components/ui/select.component.tsx +8 -0
- package/templates/ui/antd/src/components/ui/separator.component.tsx +8 -0
- package/templates/ui/antd/src/components/ui/sheet.component.tsx +8 -0
- package/templates/ui/antd/src/components/ui/switch.component.tsx +8 -0
- package/templates/ui/antd/src/components/ui/table.component.tsx +8 -0
- package/templates/ui/antd/src/components/ui/tabs.component.tsx +8 -0
- package/templates/ui/antd/src/components/ui/textarea.component.tsx +9 -0
- package/templates/ui/antd/src/components/ui/tooltip.component.tsx +8 -0
- package/templates/ui/antd/src/lib/theme.util.ts +40 -0
- package/templates/ui/antd/src/providers/antd.provider.tsx +13 -0
- package/templates/ui/mui/src/app/examples/layout.tsx +113 -0
- package/templates/ui/mui/src/app/examples/page.tsx +716 -0
- package/templates/ui/mui/src/app/page.tsx +298 -0
- package/templates/ui/mui/src/components/common/DynamicTable/dynamic-table.component.tsx +131 -0
- package/templates/ui/mui/src/components/common/button/action-button.component.tsx +57 -0
- package/templates/ui/mui/src/components/common/dialog/dialog-wrapper.component.tsx +55 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/check-field.component.tsx +51 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/date-picker-field.component.tsx +50 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/multi-check-field.component.tsx +14 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/number-field.component.tsx +59 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/password-field.component.tsx +87 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/phone-number-field.component.tsx +48 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/radio-field.component.tsx +37 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/search-field.component.tsx +41 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/select-field.component.tsx +77 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/single-check-field.component.tsx +39 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/single-select-field.component.tsx +56 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/string-number-field.component.tsx +52 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/switch-field.component.tsx +35 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/text-area-field.component.tsx +46 -0
- package/templates/ui/mui/src/components/common/fields/assets/components/text-field.component.tsx +51 -0
- package/templates/ui/mui/src/components/common/fields/assets/interface/input-props.type.ts +193 -0
- package/templates/ui/mui/src/components/common/fields/cusInputField.component.tsx +34 -0
- package/templates/ui/mui/src/components/common/pagination/pagination.component.tsx +59 -0
- package/templates/ui/mui/src/components/ui/avatar.component.tsx +19 -0
- package/templates/ui/mui/src/components/ui/badge.component.tsx +18 -0
- package/templates/ui/mui/src/components/ui/button.component.tsx +22 -0
- package/templates/ui/mui/src/components/ui/card.component.tsx +39 -0
- package/templates/ui/mui/src/components/ui/checkbox.component.tsx +21 -0
- package/templates/ui/mui/src/components/ui/dialog.component.tsx +38 -0
- package/templates/ui/mui/src/components/ui/dropdown-menu.component.tsx +43 -0
- package/templates/ui/mui/src/components/ui/form.component.tsx +98 -0
- package/templates/ui/mui/src/components/ui/input.component.tsx +15 -0
- package/templates/ui/mui/src/components/ui/label.component.tsx +15 -0
- package/templates/ui/mui/src/components/ui/popover.component.tsx +20 -0
- package/templates/ui/mui/src/components/ui/progress.component.tsx +19 -0
- package/templates/ui/mui/src/components/ui/radio-group.component.tsx +25 -0
- package/templates/ui/mui/src/components/ui/scroll-area.component.tsx +27 -0
- package/templates/ui/mui/src/components/ui/select.component.tsx +26 -0
- package/templates/ui/mui/src/components/ui/separator.component.tsx +11 -0
- package/templates/ui/mui/src/components/ui/sheet.component.tsx +44 -0
- package/templates/ui/mui/src/components/ui/switch.component.tsx +23 -0
- package/templates/ui/mui/src/components/ui/table.component.tsx +34 -0
- package/templates/ui/mui/src/components/ui/tabs.component.tsx +38 -0
- package/templates/ui/mui/src/components/ui/textarea.component.tsx +18 -0
- package/templates/ui/mui/src/components/ui/tooltip.component.tsx +24 -0
- package/templates/ui/mui/src/lib/theme.util.ts +73 -0
- package/templates/ui/mui/src/providers/mui.provider.tsx +13 -0
- package/templates/ui/shadcn/COMPONENT_GUIDE.md +306 -0
- package/templates/ui/shadcn/src/app/examples/dialog/page.tsx +122 -0
- package/templates/ui/shadcn/src/app/examples/form/page.tsx +107 -0
- package/templates/ui/shadcn/src/app/examples/layout.tsx +24 -0
- package/templates/ui/shadcn/src/app/examples/page.tsx +30 -0
- package/templates/ui/shadcn/src/app/examples/table/page.tsx +77 -0
- package/templates/ui/shadcn/src/app/page.tsx +20 -0
- package/templates/ui/shadcn/src/components/common/DynamicTable/dynamic-table.component.tsx +136 -0
- package/templates/ui/shadcn/src/components/common/button/action-button.component.tsx +68 -0
- package/templates/ui/shadcn/src/components/common/dialog/dialog-wrapper.component.tsx +58 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/check-field.component.tsx +52 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/date-picker-field.component.tsx +62 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/dynamic-file-upload-field.component.tsx +152 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/limit-field.component.tsx +73 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/multi-check-field.component.tsx +46 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/number-field.component.tsx +124 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/otp-field.component.tsx +61 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/password-field.component.tsx +110 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/phone-number-field.component.tsx +90 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/radio-field.component.tsx +41 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/range-date-picker.component.tsx +71 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/rich-text-editor.component.tsx +91 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/search-field.component.tsx +34 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/select-field.component.tsx +231 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/single-check-field.component.tsx +42 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/single-select-field.component.tsx +82 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/string-number-field.component.tsx +68 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/switch-field.component.tsx +61 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/text-area-field.component.tsx +62 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/text-area-with-file.component.tsx +142 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/text-field.component.tsx +80 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/tiny-editor.component.tsx +51 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/upload-profile-picture.component.tsx +103 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/components/upload-video-file.component.tsx +86 -0
- package/templates/ui/shadcn/src/components/common/fields/assets/interface/input-props.type.ts +198 -0
- package/templates/ui/shadcn/src/components/common/fields/cusInputField.component.tsx +52 -0
- package/templates/ui/shadcn/src/components/common/pagination/pagination.component.tsx +68 -0
- package/templates/ui/shadcn/src/components/ui/avatar.component.tsx +37 -0
- package/templates/ui/shadcn/src/components/ui/badge.component.tsx +28 -0
- package/templates/ui/shadcn/src/components/ui/button.component.tsx +52 -0
- package/templates/ui/shadcn/src/components/ui/card.component.tsx +46 -0
- package/templates/ui/shadcn/src/components/ui/checkbox.component.tsx +25 -0
- package/templates/ui/shadcn/src/components/ui/dialog.component.tsx +98 -0
- package/templates/ui/shadcn/src/components/ui/dropdown-menu.component.tsx +163 -0
- package/templates/ui/shadcn/src/components/ui/form.component.tsx +110 -0
- package/templates/ui/shadcn/src/components/ui/input-otp.component.tsx +64 -0
- package/templates/ui/shadcn/src/components/ui/input.component.tsx +23 -0
- package/templates/ui/shadcn/src/components/ui/label.component.tsx +23 -0
- package/templates/ui/shadcn/src/components/ui/popover.component.tsx +27 -0
- package/templates/ui/shadcn/src/components/ui/progress.component.tsx +22 -0
- package/templates/ui/shadcn/src/components/ui/radio-group.component.tsx +33 -0
- package/templates/ui/shadcn/src/components/ui/scroll-area.component.tsx +37 -0
- package/templates/ui/shadcn/src/components/ui/select.component.tsx +139 -0
- package/templates/ui/shadcn/src/components/ui/separator.component.tsx +23 -0
- package/templates/ui/shadcn/src/components/ui/sheet.component.tsx +89 -0
- package/templates/ui/shadcn/src/components/ui/switch.component.tsx +26 -0
- package/templates/ui/shadcn/src/components/ui/table.component.tsx +71 -0
- package/templates/ui/shadcn/src/components/ui/tabs.component.tsx +52 -0
- package/templates/ui/shadcn/src/components/ui/textarea.component.tsx +20 -0
- package/templates/ui/shadcn/src/components/ui/tooltip.component.tsx +25 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
export interface TextInputProps {
|
|
2
|
+
form?: any;
|
|
3
|
+
name?: string;
|
|
4
|
+
placeholder?: string;
|
|
5
|
+
labelName?: string;
|
|
6
|
+
required?: boolean;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
viewOnly?: boolean;
|
|
9
|
+
disableLabelFormatting?: boolean;
|
|
10
|
+
customMessage?: React.ReactNode;
|
|
11
|
+
isArray?: boolean;
|
|
12
|
+
leftIcon?: React.ReactNode;
|
|
13
|
+
rightIcon?: React.ReactNode;
|
|
14
|
+
value?: string;
|
|
15
|
+
setValue?: (value: string) => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface TextAreaInputProps {
|
|
19
|
+
form?: any;
|
|
20
|
+
name?: string;
|
|
21
|
+
labelName?: string;
|
|
22
|
+
placeholder?: string;
|
|
23
|
+
required?: boolean;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
viewOnly?: boolean;
|
|
26
|
+
rows?: number;
|
|
27
|
+
disableLabelFormatting?: boolean;
|
|
28
|
+
customMessage?: React.ReactNode;
|
|
29
|
+
value?: string;
|
|
30
|
+
setValue?: (value: string) => void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface NumberInputProps {
|
|
34
|
+
form?: any;
|
|
35
|
+
name?: string;
|
|
36
|
+
labelName?: string;
|
|
37
|
+
placeholder?: string;
|
|
38
|
+
required?: boolean;
|
|
39
|
+
disabled?: boolean;
|
|
40
|
+
viewOnly?: boolean;
|
|
41
|
+
disableLabelFormatting?: boolean;
|
|
42
|
+
numberType?: 'float' | 'integer';
|
|
43
|
+
customMessage?: React.ReactNode;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface PasswordInputProps {
|
|
47
|
+
form?: any;
|
|
48
|
+
name?: string;
|
|
49
|
+
labelName?: string;
|
|
50
|
+
placeholder?: string;
|
|
51
|
+
required?: boolean;
|
|
52
|
+
disabled?: boolean;
|
|
53
|
+
disableLabelFormatting?: boolean;
|
|
54
|
+
mode?: 'normal' | 'validate';
|
|
55
|
+
customMessage?: React.ReactNode;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface SingleSelectProps {
|
|
59
|
+
form?: any;
|
|
60
|
+
name?: string;
|
|
61
|
+
labelName?: string;
|
|
62
|
+
placeholder?: string;
|
|
63
|
+
required?: boolean;
|
|
64
|
+
disabled?: boolean;
|
|
65
|
+
options?: string[];
|
|
66
|
+
viewOnly?: boolean;
|
|
67
|
+
isLoading?: boolean;
|
|
68
|
+
defaultValue?: any;
|
|
69
|
+
onValueChange?: (value: any) => void;
|
|
70
|
+
disableLabelFormatting?: boolean;
|
|
71
|
+
customMessage?: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface SelectFieldProps {
|
|
75
|
+
form: any;
|
|
76
|
+
name: string;
|
|
77
|
+
labelName?: string;
|
|
78
|
+
required?: boolean;
|
|
79
|
+
disabled?: boolean;
|
|
80
|
+
options?: { value: string; label: string; image?: string; flag?: string; disabled?: boolean }[] | string[];
|
|
81
|
+
placeholder?: string;
|
|
82
|
+
showSearch?: boolean;
|
|
83
|
+
type?: 'single' | 'multiple';
|
|
84
|
+
viewOnly?: boolean;
|
|
85
|
+
onValueChange?: (value: string | string[]) => void;
|
|
86
|
+
isLoading?: boolean;
|
|
87
|
+
onSearch?: (query: string) => void;
|
|
88
|
+
customMessage?: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface SwitchProps {
|
|
92
|
+
form?: any;
|
|
93
|
+
name?: string;
|
|
94
|
+
labelName?: string;
|
|
95
|
+
required?: boolean;
|
|
96
|
+
disabled?: boolean;
|
|
97
|
+
viewOnly?: boolean;
|
|
98
|
+
disableLabelFormatting?: boolean;
|
|
99
|
+
customMessage?: React.ReactNode;
|
|
100
|
+
description?: string;
|
|
101
|
+
border?: boolean;
|
|
102
|
+
value?: boolean;
|
|
103
|
+
setValue?: (value: boolean) => void;
|
|
104
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface CheckboxProps {
|
|
108
|
+
form?: any;
|
|
109
|
+
name: string;
|
|
110
|
+
labelName?: string;
|
|
111
|
+
required?: boolean;
|
|
112
|
+
disabled?: boolean;
|
|
113
|
+
options?: { label: string; value: string }[];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface RadioProps {
|
|
117
|
+
form?: any;
|
|
118
|
+
name: string;
|
|
119
|
+
labelName?: string;
|
|
120
|
+
required?: boolean;
|
|
121
|
+
disabled?: boolean;
|
|
122
|
+
options?: { label: string; value: string }[];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface DatePickerProps {
|
|
126
|
+
form?: any;
|
|
127
|
+
name?: string;
|
|
128
|
+
labelName?: string;
|
|
129
|
+
placeholder?: string;
|
|
130
|
+
required?: boolean;
|
|
131
|
+
disabled?: boolean;
|
|
132
|
+
viewOnly?: boolean;
|
|
133
|
+
disableLabelFormatting?: boolean;
|
|
134
|
+
customMessage?: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface PhoneNumberProps {
|
|
138
|
+
form?: any;
|
|
139
|
+
name?: string;
|
|
140
|
+
labelName?: string;
|
|
141
|
+
placeholder?: string;
|
|
142
|
+
required?: boolean;
|
|
143
|
+
disabled?: boolean;
|
|
144
|
+
viewOnly?: boolean;
|
|
145
|
+
disableLabelFormatting?: boolean;
|
|
146
|
+
customMessage?: string;
|
|
147
|
+
onValueChange?: (value: string) => void;
|
|
148
|
+
hasPhone?: boolean;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface SearchFieldProps {
|
|
152
|
+
form?: any;
|
|
153
|
+
name?: string;
|
|
154
|
+
placeholder?: string;
|
|
155
|
+
onSearch?: (value: string) => void;
|
|
156
|
+
value?: string;
|
|
157
|
+
setValue?: (value: string) => void;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface InputInterface {
|
|
161
|
+
Text: TextInputProps;
|
|
162
|
+
TextArea: TextAreaInputProps;
|
|
163
|
+
Number: NumberInputProps;
|
|
164
|
+
Password: PasswordInputProps;
|
|
165
|
+
SingleSelect: SingleSelectProps;
|
|
166
|
+
PhoneNumber: PhoneNumberProps;
|
|
167
|
+
Switch: SwitchProps;
|
|
168
|
+
DatePicker: DatePickerProps;
|
|
169
|
+
Search: SearchFieldProps;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export interface FieldPropsInterface {
|
|
173
|
+
form?: any;
|
|
174
|
+
name: string;
|
|
175
|
+
placeholder?: string;
|
|
176
|
+
labelName?: string;
|
|
177
|
+
description?: string;
|
|
178
|
+
border?: boolean;
|
|
179
|
+
options?: string[];
|
|
180
|
+
required?: boolean;
|
|
181
|
+
disabled?: boolean;
|
|
182
|
+
isArray?: boolean;
|
|
183
|
+
defaultValue?: any;
|
|
184
|
+
viewOnly?: boolean;
|
|
185
|
+
rows?: number;
|
|
186
|
+
disableLabelFormatting?: boolean;
|
|
187
|
+
maxLength?: number;
|
|
188
|
+
suffix?: string;
|
|
189
|
+
mode?: 'normal' | 'validate';
|
|
190
|
+
customMessage?: React.ReactNode;
|
|
191
|
+
onValueChange?: (value: any) => void;
|
|
192
|
+
isLoading?: boolean;
|
|
193
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Text } from './assets/components/text-field.component';
|
|
2
|
+
import { TextArea } from './assets/components/text-area-field.component';
|
|
3
|
+
import { Number } from './assets/components/number-field.component';
|
|
4
|
+
import { StringNumber } from './assets/components/string-number-field.component';
|
|
5
|
+
import { Password } from './assets/components/password-field.component';
|
|
6
|
+
import { SingleSelectField } from './assets/components/single-select-field.component';
|
|
7
|
+
import { SelectField } from './assets/components/select-field.component';
|
|
8
|
+
import { SwitchField } from './assets/components/switch-field.component';
|
|
9
|
+
import { RadioField } from './assets/components/radio-field.component';
|
|
10
|
+
import { CheckField } from './assets/components/check-field.component';
|
|
11
|
+
import { MultiCheckField } from './assets/components/multi-check-field.component';
|
|
12
|
+
import { SingleCheckField } from './assets/components/single-check-field.component';
|
|
13
|
+
import { SearchField } from './assets/components/search-field.component';
|
|
14
|
+
import { DatePickerField } from './assets/components/date-picker-field.component';
|
|
15
|
+
import { PhoneNumber } from './assets/components/phone-number-field.component';
|
|
16
|
+
|
|
17
|
+
export const CustomField = {
|
|
18
|
+
Text,
|
|
19
|
+
TextArea,
|
|
20
|
+
Number,
|
|
21
|
+
StringNumber,
|
|
22
|
+
Password,
|
|
23
|
+
SingleSelectField,
|
|
24
|
+
SelectField,
|
|
25
|
+
SwitchField,
|
|
26
|
+
RadioField,
|
|
27
|
+
CheckField,
|
|
28
|
+
MultiCheckField,
|
|
29
|
+
SingleCheckField,
|
|
30
|
+
SearchField,
|
|
31
|
+
CommonSearch: SearchField,
|
|
32
|
+
DatePickerField,
|
|
33
|
+
PhoneNumber,
|
|
34
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import IconButton from '@mui/material/IconButton';
|
|
4
|
+
import Typography from '@mui/material/Typography';
|
|
5
|
+
import Box from '@mui/material/Box';
|
|
6
|
+
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
|
|
7
|
+
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
|
8
|
+
import Button from '@mui/material/Button';
|
|
9
|
+
|
|
10
|
+
interface PaginationProps {
|
|
11
|
+
currentPage: number;
|
|
12
|
+
totalPages: number;
|
|
13
|
+
setCurrentPage: (page: number) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function Pagination({ currentPage, totalPages, setCurrentPage }: PaginationProps) {
|
|
17
|
+
if (totalPages <= 1) return null;
|
|
18
|
+
|
|
19
|
+
const getPageNumbers = () => {
|
|
20
|
+
const pages: (number | 'ellipsis')[] = [];
|
|
21
|
+
const delta = 2;
|
|
22
|
+
const left = Math.max(2, currentPage - delta);
|
|
23
|
+
const right = Math.min(totalPages - 1, currentPage + delta);
|
|
24
|
+
pages.push(1);
|
|
25
|
+
if (left > 2) pages.push('ellipsis');
|
|
26
|
+
for (let i = left; i <= right; i++) pages.push(i);
|
|
27
|
+
if (right < totalPages - 1) pages.push('ellipsis');
|
|
28
|
+
if (totalPages > 1) pages.push(totalPages);
|
|
29
|
+
return pages;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 0.5 }}>
|
|
34
|
+
<IconButton size="small" disabled={currentPage <= 1} onClick={() => setCurrentPage(currentPage - 1)}>
|
|
35
|
+
<ChevronLeftIcon />
|
|
36
|
+
</IconButton>
|
|
37
|
+
{getPageNumbers().map((page, idx) =>
|
|
38
|
+
page === 'ellipsis' ? (
|
|
39
|
+
<Typography key={`ellipsis-${idx}`} variant="body2" color="text.secondary" sx={{ px: 1 }}>
|
|
40
|
+
...
|
|
41
|
+
</Typography>
|
|
42
|
+
) : (
|
|
43
|
+
<Button
|
|
44
|
+
key={page}
|
|
45
|
+
size="small"
|
|
46
|
+
variant={currentPage === page ? 'contained' : 'outlined'}
|
|
47
|
+
onClick={() => setCurrentPage(page)}
|
|
48
|
+
sx={{ minWidth: 36, height: 36 }}
|
|
49
|
+
>
|
|
50
|
+
{page}
|
|
51
|
+
</Button>
|
|
52
|
+
)
|
|
53
|
+
)}
|
|
54
|
+
<IconButton size="small" disabled={currentPage >= totalPages} onClick={() => setCurrentPage(currentPage + 1)}>
|
|
55
|
+
<ChevronRightIcon />
|
|
56
|
+
</IconButton>
|
|
57
|
+
</Box>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import MuiAvatar, { AvatarProps as MuiAvatarProps } from '@mui/material/Avatar';
|
|
3
|
+
import MuiAvatarGroup from '@mui/material/AvatarGroup';
|
|
4
|
+
import { styled } from '@mui/material/styles';
|
|
5
|
+
|
|
6
|
+
const StyledAvatar = styled(MuiAvatar)(({ theme }) => ({
|
|
7
|
+
backgroundColor: theme.palette.primary.main,
|
|
8
|
+
color: theme.palette.primary.contrastText,
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
export type AvatarProps = MuiAvatarProps;
|
|
12
|
+
|
|
13
|
+
export function Avatar(props: AvatarProps) {
|
|
14
|
+
return <StyledAvatar {...props} />;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const AvatarImage = MuiAvatar;
|
|
18
|
+
export const AvatarFallback = MuiAvatar;
|
|
19
|
+
export const AvatarGroup = MuiAvatarGroup;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import MuiChip, { ChipProps as MuiChipProps } from '@mui/material/Chip';
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
|
+
|
|
5
|
+
const StyledBadge = styled(MuiChip)(({ theme }) => ({
|
|
6
|
+
fontWeight: 600,
|
|
7
|
+
fontSize: '0.75rem',
|
|
8
|
+
height: 24,
|
|
9
|
+
'& .MuiChip-label': {
|
|
10
|
+
padding: '0 8px',
|
|
11
|
+
},
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
export type BadgeProps = MuiChipProps;
|
|
15
|
+
|
|
16
|
+
export function Badge(props: BadgeProps) {
|
|
17
|
+
return <StyledBadge size="small" {...props} />;
|
|
18
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import MuiButton, { ButtonProps as MuiButtonProps } from '@mui/material/Button';
|
|
4
|
+
import CircularProgress from '@mui/material/CircularProgress';
|
|
5
|
+
|
|
6
|
+
export type ButtonProps = MuiButtonProps & {
|
|
7
|
+
isLoading?: boolean;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
|
11
|
+
({ children, isLoading, disabled, ...props }, ref) => {
|
|
12
|
+
return (
|
|
13
|
+
<MuiButton ref={ref} disabled={isLoading || disabled} {...props}>
|
|
14
|
+
{isLoading ? <CircularProgress size={18} color="inherit" sx={{ mr: 1 }} /> : null}
|
|
15
|
+
{children}
|
|
16
|
+
</MuiButton>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
Button.displayName = 'Button';
|
|
21
|
+
|
|
22
|
+
export { Button };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import MuiCard, { CardProps as MuiCardProps } from '@mui/material/Card';
|
|
3
|
+
import MuiCardContent from '@mui/material/CardContent';
|
|
4
|
+
import MuiCardActions from '@mui/material/CardActions';
|
|
5
|
+
import MuiCardHeader from '@mui/material/CardHeader';
|
|
6
|
+
import Typography from '@mui/material/Typography';
|
|
7
|
+
import { styled } from '@mui/material/styles';
|
|
8
|
+
|
|
9
|
+
const StyledCard = styled(MuiCard)(({ theme }) => ({
|
|
10
|
+
borderRadius: theme.shape.borderRadius,
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
export type CardProps = MuiCardProps;
|
|
14
|
+
|
|
15
|
+
export function Card(props: CardProps) {
|
|
16
|
+
return <StyledCard {...props} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const CardContent = MuiCardContent;
|
|
20
|
+
export const CardActions = MuiCardActions;
|
|
21
|
+
export const CardHeader = MuiCardHeader;
|
|
22
|
+
|
|
23
|
+
export function CardTitle({ children, ...props }: { children: React.ReactNode } & React.ComponentPropsWithoutRef<typeof Typography>) {
|
|
24
|
+
return (
|
|
25
|
+
<Typography variant="h5" fontWeight={600} {...props}>
|
|
26
|
+
{children}
|
|
27
|
+
</Typography>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function CardDescription({ children, ...props }: { children: React.ReactNode } & React.ComponentPropsWithoutRef<typeof Typography>) {
|
|
32
|
+
return (
|
|
33
|
+
<Typography variant="body2" color="text.secondary" {...props}>
|
|
34
|
+
{children}
|
|
35
|
+
</Typography>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const CardFooter = MuiCardActions;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import MuiCheckbox, { CheckboxProps as MuiCheckboxProps } from '@mui/material/Checkbox';
|
|
3
|
+
import FormControlLabel from '@mui/material/FormControlLabel';
|
|
4
|
+
import { styled } from '@mui/material/styles';
|
|
5
|
+
|
|
6
|
+
const StyledCheckbox = styled(MuiCheckbox)(({ theme }) => ({
|
|
7
|
+
color: theme.palette.text.secondary,
|
|
8
|
+
'&.Mui-checked': {
|
|
9
|
+
color: theme.palette.primary.main,
|
|
10
|
+
},
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
export type CheckboxProps = MuiCheckboxProps;
|
|
14
|
+
|
|
15
|
+
export function Checkbox(props: CheckboxProps) {
|
|
16
|
+
return <StyledCheckbox {...props} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function CheckboxLabel({ label, ...props }: CheckboxProps & { label?: React.ReactNode }) {
|
|
20
|
+
return <FormControlLabel control={<Checkbox {...props} />} label={label} />;
|
|
21
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import MuiDialog, { DialogProps as MuiDialogProps } from '@mui/material/Dialog';
|
|
3
|
+
import MuiDialogTitle from '@mui/material/DialogTitle';
|
|
4
|
+
import MuiDialogContent from '@mui/material/DialogContent';
|
|
5
|
+
import MuiDialogActions from '@mui/material/DialogActions';
|
|
6
|
+
import IconButton from '@mui/material/IconButton';
|
|
7
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
8
|
+
import { styled } from '@mui/material/styles';
|
|
9
|
+
|
|
10
|
+
const StyledDialog = styled(MuiDialog)(({ theme }) => ({
|
|
11
|
+
'& .MuiDialog-paper': {
|
|
12
|
+
borderRadius: theme.shape.borderRadius,
|
|
13
|
+
},
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
export type DialogProps = MuiDialogProps;
|
|
17
|
+
|
|
18
|
+
export function Dialog({ children, ...props }: DialogProps) {
|
|
19
|
+
return <StyledDialog {...props}>{children}</StyledDialog>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const DialogTitle = MuiDialogTitle;
|
|
23
|
+
export const DialogContent = MuiDialogContent;
|
|
24
|
+
export const DialogActions = MuiDialogActions;
|
|
25
|
+
|
|
26
|
+
export function DialogClose({ onClick }: { onClick?: () => void }) {
|
|
27
|
+
return (
|
|
28
|
+
<IconButton
|
|
29
|
+
onClick={onClick}
|
|
30
|
+
sx={{
|
|
31
|
+
position: 'absolute', right: 8, top: 8,
|
|
32
|
+
color: 'text.secondary',
|
|
33
|
+
}}
|
|
34
|
+
>
|
|
35
|
+
<CloseIcon />
|
|
36
|
+
</IconButton>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import MuiMenu, { MenuProps as MuiMenuProps } from '@mui/material/Menu';
|
|
3
|
+
import MuiMenuItem from '@mui/material/MenuItem';
|
|
4
|
+
import MuiListSubheader from '@mui/material/ListSubheader';
|
|
5
|
+
import Divider from '@mui/material/Divider';
|
|
6
|
+
import { styled } from '@mui/material/styles';
|
|
7
|
+
|
|
8
|
+
const StyledMenu = styled(MuiMenu)(({ theme }) => ({
|
|
9
|
+
'& .MuiPaper-root': {
|
|
10
|
+
borderRadius: theme.shape.borderRadius,
|
|
11
|
+
minWidth: 180,
|
|
12
|
+
},
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
const StyledMenuItem = styled(MuiMenuItem)(({ theme }) => ({
|
|
16
|
+
fontSize: '0.875rem',
|
|
17
|
+
'&:hover': {
|
|
18
|
+
backgroundColor: theme.palette.action.hover,
|
|
19
|
+
},
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
export type DropdownMenuProps = MuiMenuProps;
|
|
23
|
+
|
|
24
|
+
export function DropdownMenu(props: DropdownMenuProps) {
|
|
25
|
+
return <StyledMenu {...props} />;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const DropdownMenuTrigger = ({ children, onClick }: { children: React.ReactNode; onClick?: () => void }) => <>{children}</>;
|
|
29
|
+
export const DropdownMenuContent = StyledMenu;
|
|
30
|
+
export const DropdownMenuItem = StyledMenuItem;
|
|
31
|
+
export const DropdownMenuLabel = MuiListSubheader;
|
|
32
|
+
export const DropdownMenuSeparator = Divider;
|
|
33
|
+
export const DropdownMenuGroup = ({ children }: { children: React.ReactNode }) => <>{children}</>;
|
|
34
|
+
export const DropdownMenuCheckboxItem = StyledMenuItem;
|
|
35
|
+
export const DropdownMenuRadioItem = StyledMenuItem;
|
|
36
|
+
export const DropdownMenuRadioGroup = ({ children }: { children: React.ReactNode }) => <>{children}</>;
|
|
37
|
+
export const DropdownMenuSub = ({ children }: { children: React.ReactNode }) => <>{children}</>;
|
|
38
|
+
export const DropdownMenuSubContent = StyledMenu;
|
|
39
|
+
export const DropdownMenuSubTrigger = StyledMenuItem;
|
|
40
|
+
export const DropdownMenuPortal = ({ children }: { children: React.ReactNode }) => <>{children}</>;
|
|
41
|
+
export const DropdownMenuShortcut = ({ children }: { children: React.ReactNode }) => (
|
|
42
|
+
<span style={{ marginLeft: 'auto', fontSize: '0.75rem', opacity: 0.6 }}>{children}</span>
|
|
43
|
+
);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import {
|
|
4
|
+
Controller, type ControllerProps, type FieldPath, type FieldValues,
|
|
5
|
+
FormProvider, useFormContext,
|
|
6
|
+
} from 'react-hook-form';
|
|
7
|
+
|
|
8
|
+
const Form = FormProvider;
|
|
9
|
+
|
|
10
|
+
type FormFieldContextValue<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> = { name: TName };
|
|
11
|
+
const FormFieldContext = React.createContext<FormFieldContextValue>({} as FormFieldContextValue);
|
|
12
|
+
|
|
13
|
+
const FormField = <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>(
|
|
14
|
+
props: ControllerProps<TFieldValues, TName>
|
|
15
|
+
) => (
|
|
16
|
+
<FormFieldContext.Provider value={{ name: props.name }}>
|
|
17
|
+
<Controller {...props} />
|
|
18
|
+
</FormFieldContext.Provider>
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
const useFormField = () => {
|
|
22
|
+
const fieldContext = React.useContext(FormFieldContext);
|
|
23
|
+
const itemContext = React.useContext(FormItemContext);
|
|
24
|
+
if (!fieldContext) throw new Error('useFormField should be used within <FormField>');
|
|
25
|
+
const formContext = useFormContext();
|
|
26
|
+
const fieldState = formContext
|
|
27
|
+
? formContext.getFieldState(fieldContext.name, formContext.formState)
|
|
28
|
+
: { invalid: false, isDirty: false, isTouched: false, error: undefined };
|
|
29
|
+
const { id } = itemContext;
|
|
30
|
+
return {
|
|
31
|
+
id, name: fieldContext.name, formItemId: `${id}-form-item`,
|
|
32
|
+
formDescriptionId: `${id}-form-item-description`,
|
|
33
|
+
formMessageId: `${id}-form-item-message`, ...fieldState,
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
type FormItemContextValue = { id: string };
|
|
38
|
+
const FormItemContext = React.createContext<FormItemContextValue>({} as FormItemContextValue);
|
|
39
|
+
|
|
40
|
+
const FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
41
|
+
({ ...props }, ref) => {
|
|
42
|
+
const id = React.useId();
|
|
43
|
+
return (
|
|
44
|
+
<FormItemContext.Provider value={{ id }}>
|
|
45
|
+
<div ref={ref} style={{ marginBottom: 16 }} {...props} />
|
|
46
|
+
</FormItemContext.Provider>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
FormItem.displayName = 'FormItem';
|
|
51
|
+
|
|
52
|
+
const FormLabel = React.forwardRef<HTMLLabelElement, React.LabelHTMLAttributes<HTMLLabelElement>>(
|
|
53
|
+
({ ...props }, ref) => {
|
|
54
|
+
const { error, formItemId } = useFormField();
|
|
55
|
+
return <label ref={ref} htmlFor={formItemId} style={{ fontWeight: 500, fontSize: '0.875rem', color: error ? '#d32f2f' : undefined, display: 'block', marginBottom: 4 }} {...props} />;
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
FormLabel.displayName = 'FormLabel';
|
|
59
|
+
|
|
60
|
+
const FormControl = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
61
|
+
({ ...props }, ref) => {
|
|
62
|
+
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
|
|
63
|
+
return (
|
|
64
|
+
<div
|
|
65
|
+
ref={ref}
|
|
66
|
+
id={formItemId}
|
|
67
|
+
aria-describedby={!error ? formDescriptionId : `${formDescriptionId} ${formMessageId}`}
|
|
68
|
+
aria-invalid={!!error}
|
|
69
|
+
{...props}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
FormControl.displayName = 'FormControl';
|
|
75
|
+
|
|
76
|
+
const FormDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
|
|
77
|
+
({ ...props }, ref) => {
|
|
78
|
+
const { formDescriptionId } = useFormField();
|
|
79
|
+
return <p ref={ref} id={formDescriptionId} style={{ fontSize: '0.75rem', color: 'text.secondary', marginTop: 4 }} {...props} />;
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
FormDescription.displayName = 'FormDescription';
|
|
83
|
+
|
|
84
|
+
const FormMessage = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
|
|
85
|
+
({ children, ...props }, ref) => {
|
|
86
|
+
const { error, formMessageId } = useFormField();
|
|
87
|
+
const body = error ? String(error?.message) : children;
|
|
88
|
+
if (!body) return null;
|
|
89
|
+
return (
|
|
90
|
+
<p ref={ref} id={formMessageId} style={{ fontSize: '0.75rem', color: '#d32f2f', marginTop: 4, fontWeight: 500 }} {...props}>
|
|
91
|
+
{body}
|
|
92
|
+
</p>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
FormMessage.displayName = 'FormMessage';
|
|
97
|
+
|
|
98
|
+
export { useFormField, Form, FormItem, FormLabel, FormControl, FormDescription, FormMessage, FormField };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import MuiTextField, { TextFieldProps as MuiTextFieldProps } from '@mui/material/TextField';
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
|
+
|
|
5
|
+
const StyledTextField = styled(MuiTextField)(({ theme }) => ({
|
|
6
|
+
'& .MuiOutlinedInput-root': {
|
|
7
|
+
borderRadius: theme.shape.borderRadius,
|
|
8
|
+
},
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
export type InputProps = MuiTextFieldProps;
|
|
12
|
+
|
|
13
|
+
export function Input(props: InputProps) {
|
|
14
|
+
return <StyledTextField variant="outlined" fullWidth {...props} />;
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import MuiFormLabel, { FormLabelProps as MuiFormLabelProps } from '@mui/material/FormLabel';
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
|
+
|
|
5
|
+
const StyledLabel = styled(MuiFormLabel)(({ theme }) => ({
|
|
6
|
+
fontWeight: 500,
|
|
7
|
+
fontSize: '0.875rem',
|
|
8
|
+
marginBottom: theme.spacing(0.5),
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
export type LabelProps = MuiFormLabelProps;
|
|
12
|
+
|
|
13
|
+
export function Label(props: LabelProps) {
|
|
14
|
+
return <StyledLabel {...props} />;
|
|
15
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import MuiPopover, { PopoverProps as MuiPopoverProps } from '@mui/material/Popover';
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
|
+
|
|
5
|
+
const StyledPopover = styled(MuiPopover)(({ theme }) => ({
|
|
6
|
+
'& .MuiPopover-paper': {
|
|
7
|
+
borderRadius: theme.shape.borderRadius,
|
|
8
|
+
padding: theme.spacing(2),
|
|
9
|
+
marginTop: 4,
|
|
10
|
+
},
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
export type PopoverProps = MuiPopoverProps;
|
|
14
|
+
|
|
15
|
+
export function Popover(props: PopoverProps) {
|
|
16
|
+
return <StyledPopover {...props} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const PopoverTrigger = ({ children, onClick }: { children: React.ReactNode; onClick?: () => void }) => <>{children}</>;
|
|
20
|
+
export const PopoverContent = StyledPopover;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import MuiLinearProgress, { LinearProgressProps as MuiLinearProgressProps } from '@mui/material/LinearProgress';
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
|
+
|
|
5
|
+
const StyledProgress = styled(MuiLinearProgress)(({ theme }) => ({
|
|
6
|
+
backgroundColor: theme.palette.action.hover,
|
|
7
|
+
borderRadius: theme.shape.borderRadius,
|
|
8
|
+
height: 8,
|
|
9
|
+
'& .MuiLinearProgress-bar': {
|
|
10
|
+
borderRadius: theme.shape.borderRadius,
|
|
11
|
+
backgroundColor: theme.palette.primary.main,
|
|
12
|
+
},
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
export type ProgressProps = MuiLinearProgressProps;
|
|
16
|
+
|
|
17
|
+
export function Progress(props: ProgressProps) {
|
|
18
|
+
return <StyledProgress {...props} />;
|
|
19
|
+
}
|