proje-react-panel 1.7.0 → 1.9.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/.vscode/settings.json +1 -1
- package/README.md +43 -3
- package/dist/__tests__/components/form/CustomField.test.d.ts +4 -0
- package/dist/__tests__/components/form/FormGroups.test.d.ts +1 -0
- package/dist/__tests__/components/form/RichTextField.test.d.ts +4 -0
- package/dist/__tests__/optionalTiptap.test.d.ts +4 -0
- package/dist/components/form/CustomField.d.ts +9 -0
- package/dist/components/form/RichTextField.d.ts +7 -0
- package/dist/decorators/form/Form.d.ts +8 -0
- package/dist/decorators/form/Input.d.ts +5 -1
- package/dist/decorators/form/inputs/CustomInput.d.ts +16 -0
- package/dist/decorators/form/inputs/RichTextInput.d.ts +13 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.esm.js +2 -2
- package/{DASHBOARD_GUIDE.md → guides/DASHBOARD_GUIDE.md} +1 -1
- package/guides/USAGE.md +85 -0
- package/how_to.md +302 -0
- package/jest.config.js +1 -0
- package/package.json +17 -1
- package/src/__tests__/components/form/CustomField.test.tsx +92 -0
- package/src/__tests__/components/form/FormGroups.test.tsx +194 -0
- package/src/__tests__/components/form/RichTextField.test.tsx +181 -0
- package/src/__tests__/optionalTiptap.test.tsx +89 -0
- package/src/components/form/CustomField.tsx +34 -0
- package/src/components/form/FormField.tsx +13 -2
- package/src/components/form/InnerForm.tsx +101 -19
- package/src/components/form/RichTextField.tsx +218 -0
- package/src/components/layout/Layout.tsx +18 -2
- package/src/components/list/ListPage.tsx +1 -1
- package/src/decorators/form/Form.ts +11 -0
- package/src/decorators/form/Input.ts +6 -1
- package/src/decorators/form/inputs/CustomInput.ts +26 -0
- package/src/decorators/form/inputs/RichTextInput.ts +38 -0
- package/src/index.ts +13 -1
- package/src/styles/components/rich-text.scss +115 -0
- package/src/styles/form.scss +48 -0
- package/src/styles/index.scss +1 -0
- package/dist/components/DashboardContainer.d.ts +0 -7
- package/dist/components/DashboardGrid.d.ts +0 -9
- package/dist/components/DashboardItem.d.ts +0 -10
- package/dist/components/ThemeSwitcher.d.ts +0 -7
- package/dist/store/themeStore.d.ts +0 -23
- /package/{AUTH_LAYOUT_EXAMPLE.md → guides/AUTH_LAYOUT_EXAMPLE.md} +0 -0
- /package/{AUTH_LAYOUT_GUIDE.md → guides/AUTH_LAYOUT_GUIDE.md} +0 -0
- /package/{COLOR_SYSTEM_GUIDE.md → guides/COLOR_SYSTEM_GUIDE.md} +0 -0
- /package/{IMPLEMENTATION_GUIDE.md → guides/IMPLEMENTATION_GUIDE.md} +0 -0
package/.vscode/settings.json
CHANGED
package/README.md
CHANGED
|
@@ -26,6 +26,9 @@ The library provides several decorators for enhanced functionality:
|
|
|
26
26
|
### Form Decorators
|
|
27
27
|
|
|
28
28
|
- `@Input`: Form input decorator
|
|
29
|
+
- `@SelectInput`: Select input decorator
|
|
30
|
+
- `@RichTextInput`: Rich text (TipTap) input decorator — needs the optional `@tiptap/react` + `@tiptap/starter-kit` peers
|
|
31
|
+
- `@CustomInput`: Render your own component in place of a field
|
|
29
32
|
- `@Crud`: CRUD operations decorator
|
|
30
33
|
|
|
31
34
|
## Installation
|
|
@@ -61,11 +64,48 @@ const panel = new Panel({
|
|
|
61
64
|
</DashboardGrid>
|
|
62
65
|
```
|
|
63
66
|
|
|
67
|
+
## Custom Form Fields
|
|
68
|
+
|
|
69
|
+
When a field needs a control the library does not ship, `@CustomInput` lets your app render
|
|
70
|
+
it. The library only wires the field into `react-hook-form` and renders the label and the
|
|
71
|
+
error message like any other field — everything inside is yours.
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import { CustomInput, type CustomRenderProps } from 'proje-react-panel';
|
|
75
|
+
|
|
76
|
+
class Product {
|
|
77
|
+
@Input({ label: 'Name' })
|
|
78
|
+
name: string;
|
|
79
|
+
|
|
80
|
+
@CustomInput({
|
|
81
|
+
label: 'Cover image',
|
|
82
|
+
render: ({ value, onChange, error }: CustomRenderProps) => (
|
|
83
|
+
<MyImagePicker value={value as string} onSelect={onChange} invalid={!!error} />
|
|
84
|
+
),
|
|
85
|
+
})
|
|
86
|
+
coverImage: string;
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The render function receives:
|
|
91
|
+
|
|
92
|
+
| Prop | Type | Description |
|
|
93
|
+
| ----------- | -------------------------- | --------------------------------------------------- |
|
|
94
|
+
| `fieldName` | `string` | Full form path of the field (nested paths included) |
|
|
95
|
+
| `value` | `unknown` | Current form value |
|
|
96
|
+
| `onChange` | `(value: unknown) => void` | Writes a new value into the form |
|
|
97
|
+
| `error` | `string \| undefined` | Validation message for this field, if any |
|
|
98
|
+
|
|
99
|
+
Because the value is whatever you pass to `onChange`, a custom field can hold an id, an
|
|
100
|
+
object or a file reference — validation and submit treat it like any other form value.
|
|
101
|
+
|
|
64
102
|
## Guides
|
|
65
103
|
|
|
66
|
-
- **[Dashboard Guide](./DASHBOARD_GUIDE.md)** - Complete guide for using Dashboard components
|
|
67
|
-
- **[Auth Layout Guide](./AUTH_LAYOUT_GUIDE.md)** - Guide for implementing authentication layouts with sidebar
|
|
68
|
-
- **[
|
|
104
|
+
- **[Dashboard Guide](./guides/DASHBOARD_GUIDE.md)** - Complete guide for using Dashboard components
|
|
105
|
+
- **[Auth Layout Guide](./guides/AUTH_LAYOUT_GUIDE.md)** - Guide for implementing authentication layouts with sidebar
|
|
106
|
+
- **[Auth Layout Example](./guides/AUTH_LAYOUT_EXAMPLE.md)** - Complete working example of AuthLayout implementation
|
|
107
|
+
- **[Color System Guide](./guides/COLOR_SYSTEM_GUIDE.md)** - Complete documentation of the color system, SCSS variables, and CSS custom properties
|
|
108
|
+
- **[Implementation Guide](./guides/IMPLEMENTATION_GUIDE.md)** - Comprehensive guide for implementing the library in your React applications
|
|
69
109
|
|
|
70
110
|
## Type Definitions
|
|
71
111
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { InputConfiguration } from '../../decorators/form/Input';
|
|
3
|
+
interface CustomFieldProps {
|
|
4
|
+
input: InputConfiguration;
|
|
5
|
+
fieldName: string;
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function CustomField({ input, fieldName, error }: CustomFieldProps): React.JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { InputConfiguration } from '../../decorators/form/Input';
|
|
3
|
+
export interface RichTextFieldProps {
|
|
4
|
+
input: InputConfiguration;
|
|
5
|
+
fieldName: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function RichTextField({ input, fieldName }: RichTextFieldProps): React.JSX.Element;
|
|
@@ -2,12 +2,19 @@ import 'reflect-metadata';
|
|
|
2
2
|
import { AnyClass, AnyClassConstructor } from '../../types/AnyClass';
|
|
3
3
|
import { GetDetailsDataFN } from '../details/Details';
|
|
4
4
|
export type OnSubmitFN<T, L = T> = (data: T | FormData) => Promise<L>;
|
|
5
|
+
export interface FormGroup {
|
|
6
|
+
key: string;
|
|
7
|
+
label: string;
|
|
8
|
+
collapsible?: boolean;
|
|
9
|
+
defaultCollapsed?: boolean;
|
|
10
|
+
}
|
|
5
11
|
interface FormOptions<T extends AnyClass, L = T> {
|
|
6
12
|
onSubmit: OnSubmitFN<T, L>;
|
|
7
13
|
onSubmitSuccess?: (data: L) => void;
|
|
8
14
|
getDetailsData?: GetDetailsDataFN<T>;
|
|
9
15
|
type?: 'json' | 'formData';
|
|
10
16
|
redirectSuccessUrl?: string;
|
|
17
|
+
groups?: FormGroup[];
|
|
11
18
|
}
|
|
12
19
|
export interface FormConfiguration<T extends AnyClass, L = T> {
|
|
13
20
|
onSubmit: OnSubmitFN<T, L>;
|
|
@@ -15,6 +22,7 @@ export interface FormConfiguration<T extends AnyClass, L = T> {
|
|
|
15
22
|
getDetailsData?: GetDetailsDataFN<T>;
|
|
16
23
|
type: 'json' | 'formData';
|
|
17
24
|
redirectSuccessUrl?: string;
|
|
25
|
+
groups?: FormGroup[];
|
|
18
26
|
}
|
|
19
27
|
export declare function Form<T extends AnyClass, L = T>(options?: FormOptions<T, L>): ClassDecorator;
|
|
20
28
|
export declare function getFormConfiguration<T extends AnyClass, K extends AnyClassConstructor<T>, L = T>(entityClass: K): FormConfiguration<T, L>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import { AnyClass, AnyClassConstructor } from '../../types/AnyClass';
|
|
3
3
|
export type InputTypes = 'input' | 'textarea' | 'file-upload' | 'checkbox' | 'hidden' | 'nested';
|
|
4
|
-
export type ExtendedInputTypes = InputTypes | 'select';
|
|
4
|
+
export type ExtendedInputTypes = InputTypes | 'select' | 'custom' | 'richtext';
|
|
5
5
|
export interface InputOptions {
|
|
6
6
|
type?: InputTypes;
|
|
7
7
|
inputType?: 'text' | 'email' | 'tel' | 'password' | 'number' | 'date';
|
|
@@ -11,6 +11,8 @@ export interface InputOptions {
|
|
|
11
11
|
defaultValue?: string;
|
|
12
12
|
includeInCSV?: boolean;
|
|
13
13
|
includeInJSON?: boolean;
|
|
14
|
+
group?: string;
|
|
15
|
+
rows?: number;
|
|
14
16
|
}
|
|
15
17
|
export interface ExtendedInputOptions extends Omit<InputOptions, 'type'> {
|
|
16
18
|
type: ExtendedInputTypes;
|
|
@@ -26,6 +28,8 @@ export interface InputConfiguration {
|
|
|
26
28
|
defaultValue?: string;
|
|
27
29
|
includeInCSV: boolean;
|
|
28
30
|
includeInJSON: boolean;
|
|
31
|
+
group?: string;
|
|
32
|
+
rows?: number;
|
|
29
33
|
}
|
|
30
34
|
export declare function Input(options?: InputOptions): PropertyDecorator;
|
|
31
35
|
export declare function ExtendedInput(options?: ExtendedInputOptions): PropertyDecorator;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { InputConfiguration, InputOptions } from '../Input';
|
|
3
|
+
export interface CustomRenderProps {
|
|
4
|
+
fieldName: string;
|
|
5
|
+
value: unknown;
|
|
6
|
+
onChange: (value: unknown) => void;
|
|
7
|
+
error?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface CustomInputOptions extends Omit<InputOptions, 'type'> {
|
|
10
|
+
render: (props: CustomRenderProps) => ReactNode;
|
|
11
|
+
}
|
|
12
|
+
export interface CustomInputConfiguration extends InputConfiguration {
|
|
13
|
+
type: 'custom';
|
|
14
|
+
render: (props: CustomRenderProps) => ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export declare function CustomInput(options: CustomInputOptions): PropertyDecorator;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { InputConfiguration, InputOptions } from '../Input';
|
|
2
|
+
export type RichTextToolbarItem = 'bold' | 'italic' | 'heading' | 'bulletList' | 'orderedList' | 'link';
|
|
3
|
+
export declare const DEFAULT_RICH_TEXT_TOOLBAR: RichTextToolbarItem[];
|
|
4
|
+
export interface RichTextInputOptions extends InputOptions {
|
|
5
|
+
toolbar?: RichTextToolbarItem[];
|
|
6
|
+
minHeight?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface RichTextInputConfiguration extends InputConfiguration {
|
|
9
|
+
type: 'richtext';
|
|
10
|
+
toolbar?: RichTextToolbarItem[];
|
|
11
|
+
minHeight?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function RichTextInput(options?: RichTextInputOptions): PropertyDecorator;
|