dynamic-modal 1.1.25 → 1.1.26
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/README.md +59 -0
- package/dist/src/interfaces/component-state.d.ts +11 -1
- package/dist/src/interfaces/custom-upload.d.ts +4 -2
- package/dist/src/interfaces/field.d.ts +1 -0
- package/dist/src/interfaces/input-upload.d.ts +5 -3
- package/dist/src/interfaces/make-button.d.ts +6 -3
- package/dist/src/interfaces/make-custom-upload.d.ts +4 -1
- package/dist/src/interfaces/make-description.d.ts +5 -2
- package/dist/src/interfaces/make-field-group.d.ts +5 -2
- package/dist/src/interfaces/make-input.d.ts +6 -4
- package/dist/src/interfaces/make-select.d.ts +4 -1
- package/dist/src/interfaces/make-table.d.ts +4 -2
- package/dist/src/interfaces/make-textarea.d.ts +4 -1
- package/dist/src/interfaces/make-toggle.d.ts +4 -1
- package/dist/src/interfaces/make-upload.d.ts +4 -1
- package/dist/src/interfaces/make-watcher.d.ts +5 -1
- package/dist/src/interfaces/modal.d.ts +16 -0
- package/dist/src/modal.js +35 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -490,6 +490,52 @@ renderIf: {
|
|
|
490
490
|
|
|
491
491
|
The same shape works for `enableIf`.
|
|
492
492
|
|
|
493
|
+
## Variants and combinations (`renderIf`, `enableIf`, `liveData`)
|
|
494
|
+
|
|
495
|
+
The library supports these variants:
|
|
496
|
+
|
|
497
|
+
| Feature | Variant | Shape |
|
|
498
|
+
| --- | --- | --- |
|
|
499
|
+
| `renderIf` | static criteria | `renderIf: { fieldName: ['value1', 'value2'] }` |
|
|
500
|
+
| `renderIf` | wildcard | `renderIf: { fieldName: ['*'] }` |
|
|
501
|
+
| `renderIf` | async action | `renderIf: { condition: ['fieldName'], action: async (...) => boolean }` |
|
|
502
|
+
| `enableIf` | static criteria | `enableIf: { fieldName: ['value1', 'value2'] }` |
|
|
503
|
+
| `enableIf` | wildcard | `enableIf: { fieldName: ['*'] }` |
|
|
504
|
+
| `enableIf` | async action | `enableIf: { condition: ['fieldName'], action: async (...) => boolean }` |
|
|
505
|
+
| `liveData` | single trigger field | `liveData: { condition: ['fieldName'], action: async (...) => IOption[] }` |
|
|
506
|
+
| `liveData` | multiple trigger fields | `liveData: { condition: ['fieldA', 'fieldB'], action: async (...) => IOption[] }` |
|
|
507
|
+
|
|
508
|
+
Supported combinations by field type:
|
|
509
|
+
|
|
510
|
+
- `input`, `textarea`, `toggle`, `upload`, `custom-upload`: `renderIf` + `enableIf`
|
|
511
|
+
- `select`: `renderIf` + `enableIf` + `liveData`
|
|
512
|
+
- `table`: `renderIf` + `liveData`
|
|
513
|
+
- `watcher`: no `renderIf`/`enableIf`/`liveData` contract in its interface
|
|
514
|
+
|
|
515
|
+
Behavior note about multiple observed fields:
|
|
516
|
+
|
|
517
|
+
- In static mode (`Record<field, values>`), conditions are evaluated per field-change event.
|
|
518
|
+
- In async mode (`condition: [...]`), `action` receives the changed field value as first argument and the whole form as second argument.
|
|
519
|
+
- For `liveData`, when options refresh, the target field value is reset to its default (`defaultValue`) or `[]` in multi-select mode.
|
|
520
|
+
|
|
521
|
+
Minimal combination example (`select` with all three):
|
|
522
|
+
|
|
523
|
+
```ts
|
|
524
|
+
{
|
|
525
|
+
elementType: 'select',
|
|
526
|
+
label: 'Options',
|
|
527
|
+
name: 'optionId',
|
|
528
|
+
options: [],
|
|
529
|
+
validation: { required: true, message: 'Required' },
|
|
530
|
+
renderIf: { typeId: ['*'] },
|
|
531
|
+
enableIf: { statusId: ['approved'] },
|
|
532
|
+
liveData: {
|
|
533
|
+
condition: ['typeId', 'statusId'],
|
|
534
|
+
action: async (changedValue, formData) => readOptions(changedValue, formData),
|
|
535
|
+
},
|
|
536
|
+
}
|
|
537
|
+
```
|
|
538
|
+
|
|
493
539
|
## Examples by use case
|
|
494
540
|
|
|
495
541
|
### 1. Basic modal
|
|
@@ -660,6 +706,13 @@ Common properties of `IModalConfigProps`:
|
|
|
660
706
|
- `minHeightBody`: minimum body height
|
|
661
707
|
- `useSubmit`: if `false`, action button uses manual validation mode
|
|
662
708
|
- `useBlur`: enables backdrop blur style
|
|
709
|
+
- `layout`: section-level customization for:
|
|
710
|
+
- `container`
|
|
711
|
+
- `header` (`showDivider?: boolean`)
|
|
712
|
+
- `title`
|
|
713
|
+
- `body`
|
|
714
|
+
- `footer` (`showDivider?: boolean`)
|
|
715
|
+
Each section supports `className` and `style`.
|
|
663
716
|
- `actions.action`: main action button props
|
|
664
717
|
- `actions.cancel`: optional cancel button props
|
|
665
718
|
- `actions.containerStyle`: style for the action buttons container
|
|
@@ -673,15 +726,21 @@ Most form fields share:
|
|
|
673
726
|
- `placeholder`
|
|
674
727
|
- `defaultValue`
|
|
675
728
|
- `style`
|
|
729
|
+
- `customProperties`
|
|
676
730
|
- `disabled`
|
|
677
731
|
- `validation`
|
|
678
732
|
- `renderIf`
|
|
679
733
|
- `enableIf`
|
|
680
734
|
|
|
735
|
+
Most field interfaces now also accept native HTML attributes according to the
|
|
736
|
+
element type (`input`, `textarea`, `button`, `select`, etc.). These extra props
|
|
737
|
+
are forwarded with the rest of the field config.
|
|
738
|
+
|
|
681
739
|
`watcher` uses:
|
|
682
740
|
|
|
683
741
|
- `label`
|
|
684
742
|
- `style`
|
|
743
|
+
- `customProperties`
|
|
685
744
|
- `watchList`
|
|
686
745
|
|
|
687
746
|
Validation supports:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FC, PropsWithChildren } from 'react';
|
|
1
|
+
import { CSSProperties, FC, PropsWithChildren, ReactNode } from 'react';
|
|
2
2
|
import { FieldError } from 'react-hook-form';
|
|
3
3
|
import { IOption } from './option';
|
|
4
4
|
import { IMakeInput } from './make-input';
|
|
@@ -14,7 +14,17 @@ export interface IComponentAditionalProps {
|
|
|
14
14
|
error?: FieldError;
|
|
15
15
|
liveSearching?: boolean;
|
|
16
16
|
}
|
|
17
|
+
export interface IModalSectionComponentProps {
|
|
18
|
+
children: ReactNode;
|
|
19
|
+
className?: string;
|
|
20
|
+
style?: CSSProperties;
|
|
21
|
+
}
|
|
17
22
|
export interface IComponentState {
|
|
23
|
+
ModalContainer?: FC<IModalSectionComponentProps>;
|
|
24
|
+
ModalHeader?: FC<IModalSectionComponentProps>;
|
|
25
|
+
ModalTitle?: FC<IModalSectionComponentProps>;
|
|
26
|
+
ModalBody?: FC<IModalSectionComponentProps>;
|
|
27
|
+
ModalFooter?: FC<IModalSectionComponentProps>;
|
|
18
28
|
ModalButtonCancel: FC<Omit<IMakeButton, 'elementType'>>;
|
|
19
29
|
ModalButtonAction: FC<Omit<IMakeButton, 'elementType'>>;
|
|
20
30
|
Button: FC<Omit<IMakeButton, 'elementType'>>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { ChangeEvent, CSSProperties } from 'react';
|
|
2
|
-
|
|
1
|
+
import { ChangeEvent, CSSProperties, InputHTMLAttributes } from 'react';
|
|
2
|
+
type ICustomUploadHtmlProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'id' | 'style' | 'name' | 'disabled' | 'value' | 'onChange' | 'type'>;
|
|
3
|
+
export interface ICustomUpload extends ICustomUploadHtmlProps {
|
|
3
4
|
id?: string;
|
|
4
5
|
value?: string;
|
|
5
6
|
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
@@ -10,3 +11,4 @@ export interface ICustomUpload {
|
|
|
10
11
|
name: string;
|
|
11
12
|
disabled?: boolean;
|
|
12
13
|
}
|
|
14
|
+
export {};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { ChangeEvent, CSSProperties } from 'react';
|
|
1
|
+
import { ChangeEvent, CSSProperties, InputHTMLAttributes } from 'react';
|
|
2
|
+
type IInputUploadHtmlProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'id' | 'style' | 'name' | 'disabled' | 'value' | 'onChange' | 'type'>;
|
|
2
3
|
export interface IFileResult {
|
|
3
4
|
name: string;
|
|
4
5
|
size: number;
|
|
5
6
|
data: string;
|
|
6
7
|
}
|
|
7
|
-
export interface IInputUpload {
|
|
8
|
+
export interface IInputUpload extends IInputUploadHtmlProps {
|
|
8
9
|
id?: string;
|
|
9
|
-
value?: string;
|
|
10
|
+
value?: string | number | readonly string[];
|
|
10
11
|
onChange: (event: ChangeEvent<HTMLInputElement> | IFileResult | FileList | null) => void;
|
|
11
12
|
accept?: string;
|
|
12
13
|
label?: string;
|
|
@@ -17,3 +18,4 @@ export interface IInputUpload {
|
|
|
17
18
|
disabled?: boolean;
|
|
18
19
|
read?: boolean;
|
|
19
20
|
}
|
|
21
|
+
export {};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
-
import { IFieldProps } from './field';
|
|
1
|
+
import { ButtonHTMLAttributes, CSSProperties, ReactNode } from 'react';
|
|
3
2
|
import { FieldValues, UseFormGetValues } from 'react-hook-form';
|
|
4
|
-
|
|
3
|
+
import { IFieldProps } from './field';
|
|
4
|
+
type IButtonHtmlProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'id' | 'disabled' | 'className' | 'style' | 'type' | 'onClick' | 'children' | 'color'>;
|
|
5
|
+
export interface IMakeButton extends IButtonHtmlProps {
|
|
5
6
|
id?: string;
|
|
6
7
|
elementType: 'button';
|
|
7
8
|
disabled?: boolean;
|
|
8
9
|
className?: string;
|
|
9
10
|
style?: CSSProperties;
|
|
11
|
+
customProperties?: Record<string, any>;
|
|
10
12
|
variant?: string;
|
|
11
13
|
text?: string;
|
|
12
14
|
type?: 'button' | 'submit' | 'reset';
|
|
@@ -18,3 +20,4 @@ export interface IMakeButtonProps extends IFieldProps {
|
|
|
18
20
|
element: Omit<IMakeButton, 'elementType'>;
|
|
19
21
|
getValues: UseFormGetValues<FieldValues>;
|
|
20
22
|
}
|
|
23
|
+
export {};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { InputHTMLAttributes } from 'react';
|
|
1
2
|
import { IField, IFieldProps } from './field';
|
|
2
|
-
|
|
3
|
+
type ICustomUploadHtmlProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'name' | 'id' | 'style' | 'onChange' | 'value' | 'defaultValue' | 'disabled' | 'type'>;
|
|
4
|
+
export interface IMakeCustomUpload extends IField, ICustomUploadHtmlProps {
|
|
3
5
|
elementType: 'custom-upload';
|
|
4
6
|
}
|
|
5
7
|
export interface IMakeCustomUploadProps extends IFieldProps {
|
|
6
8
|
element: Omit<IMakeCustomUpload, 'elementType'>;
|
|
7
9
|
}
|
|
10
|
+
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { CSSProperties, FC } from 'react';
|
|
1
|
+
import { CSSProperties, FC, HTMLAttributes } from 'react';
|
|
2
2
|
import { IFieldProps } from './field';
|
|
3
|
-
|
|
3
|
+
type IDescriptionHtmlProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'>;
|
|
4
|
+
export interface IMakeDescription extends IDescriptionHtmlProps {
|
|
4
5
|
elementType: 'text';
|
|
6
|
+
customProperties?: Record<string, any>;
|
|
5
7
|
text?: string;
|
|
6
8
|
containerStyle?: CSSProperties;
|
|
7
9
|
textStyle?: CSSProperties;
|
|
@@ -11,3 +13,4 @@ export interface IMakeDescription {
|
|
|
11
13
|
export interface IMakeDescriptionProps extends IFieldProps {
|
|
12
14
|
element: Omit<IMakeDescription, 'elementType'>;
|
|
13
15
|
}
|
|
16
|
+
export {};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { CSSProperties } from 'react';
|
|
1
|
+
import { CSSProperties, HTMLAttributes } from 'react';
|
|
2
2
|
import { IFieldProps } from './field';
|
|
3
3
|
import { IModalField } from './modal';
|
|
4
|
-
|
|
4
|
+
type IFieldGroupHtmlProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'>;
|
|
5
|
+
export interface IMakeFieldGroup extends IFieldGroupHtmlProps {
|
|
5
6
|
elementType: 'group';
|
|
7
|
+
customProperties?: Record<string, any>;
|
|
6
8
|
groups: Array<IModalField>;
|
|
7
9
|
style?: CSSProperties;
|
|
8
10
|
title?: string;
|
|
@@ -10,3 +12,4 @@ export interface IMakeFieldGroup {
|
|
|
10
12
|
export interface IMakeFieldGroupProps extends IFieldProps {
|
|
11
13
|
element: IMakeFieldGroup;
|
|
12
14
|
}
|
|
15
|
+
export {};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { HTMLInputTypeAttribute } from 'react';
|
|
1
|
+
import { HTMLInputTypeAttribute, InputHTMLAttributes } from 'react';
|
|
2
2
|
import { IField, IFieldProps } from './field';
|
|
3
|
-
|
|
3
|
+
type IInputHtmlProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'name' | 'id' | 'style' | 'onChange' | 'value' | 'placeholder' | 'defaultValue' | 'disabled' | 'type' | 'min' | 'max'>;
|
|
4
|
+
export interface IMakeInput extends IField, IInputHtmlProps {
|
|
4
5
|
elementType: 'input';
|
|
5
6
|
placeholder?: string;
|
|
6
|
-
min?: string;
|
|
7
|
-
max?: string;
|
|
7
|
+
min?: string | number;
|
|
8
|
+
max?: string | number;
|
|
8
9
|
type?: HTMLInputTypeAttribute;
|
|
9
10
|
}
|
|
10
11
|
export interface IMakeInputProps extends IFieldProps {
|
|
11
12
|
element: Omit<IMakeInput, 'elementType'>;
|
|
12
13
|
}
|
|
14
|
+
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { SelectHTMLAttributes } from 'react';
|
|
1
2
|
import { IField, IFieldProps } from './field';
|
|
2
3
|
import { IModalLiveDataCondition } from './modal';
|
|
3
4
|
import { IOption } from './option';
|
|
4
|
-
|
|
5
|
+
type ISelectHtmlProps = Omit<SelectHTMLAttributes<HTMLSelectElement>, 'name' | 'id' | 'style' | 'onChange' | 'value' | 'defaultValue' | 'disabled'>;
|
|
6
|
+
export interface IMakeSelect extends IField, ISelectHtmlProps {
|
|
5
7
|
elementType: 'select';
|
|
6
8
|
options: Array<IOption>;
|
|
7
9
|
liveData?: IModalLiveDataCondition;
|
|
@@ -11,3 +13,4 @@ export interface IMakeSelect extends IField {
|
|
|
11
13
|
export interface IMakeSelectProps extends IFieldProps {
|
|
12
14
|
element: Omit<IMakeSelect, 'elementType'>;
|
|
13
15
|
}
|
|
16
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSSProperties, JSX } from 'react';
|
|
1
|
+
import { CSSProperties, JSX, TableHTMLAttributes } from 'react';
|
|
2
2
|
import { IField, IFieldProps } from './field';
|
|
3
3
|
import { IModalLiveDataCondition } from './modal';
|
|
4
4
|
export interface ITableColumn extends Pick<IField, 'style'> {
|
|
@@ -9,7 +9,8 @@ export interface ITableColumn extends Pick<IField, 'style'> {
|
|
|
9
9
|
Icon?: (props: any) => JSX.Element;
|
|
10
10
|
action?: (row: any) => void;
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
type ITableHtmlProps = Omit<TableHTMLAttributes<HTMLTableElement>, 'style'>;
|
|
13
|
+
export interface IMakeTable extends Omit<IField, 'label' | 'defaultValue' | 'validation' | 'disabled' | 'enableIf' | 'id'>, ITableHtmlProps {
|
|
13
14
|
elementType: 'table';
|
|
14
15
|
selectValueName: string;
|
|
15
16
|
selectTitleName: string;
|
|
@@ -24,3 +25,4 @@ export interface IMakeTable extends Omit<IField, 'label' | 'defaultValue' | 'val
|
|
|
24
25
|
export interface IMakeTableProps extends Omit<IFieldProps, 'unregister'> {
|
|
25
26
|
element: Omit<IMakeTable, 'elementType'>;
|
|
26
27
|
}
|
|
28
|
+
export {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { TextareaHTMLAttributes } from 'react';
|
|
1
2
|
import { IField, IFieldProps } from './field';
|
|
2
|
-
|
|
3
|
+
type ITextareaHtmlProps = Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'name' | 'id' | 'style' | 'onChange' | 'value' | 'placeholder' | 'defaultValue' | 'disabled' | 'cols' | 'rows'>;
|
|
4
|
+
export interface IMakeTextarea extends IField, ITextareaHtmlProps {
|
|
3
5
|
elementType: 'textarea';
|
|
4
6
|
cols?: number;
|
|
5
7
|
rows?: number;
|
|
@@ -7,3 +9,4 @@ export interface IMakeTextarea extends IField {
|
|
|
7
9
|
export interface IMakeTextareaProps extends IFieldProps {
|
|
8
10
|
element: Omit<IMakeTextarea, 'elementType'>;
|
|
9
11
|
}
|
|
12
|
+
export {};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { InputHTMLAttributes } from 'react';
|
|
1
2
|
import { IField, IFieldProps } from './field';
|
|
2
|
-
|
|
3
|
+
type IToggleHtmlProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'name' | 'id' | 'style' | 'onChange' | 'value' | 'checked' | 'defaultValue' | 'disabled' | 'type'>;
|
|
4
|
+
export interface IMakeToggle extends IField, IToggleHtmlProps {
|
|
3
5
|
elementType: 'toggle';
|
|
4
6
|
}
|
|
5
7
|
export interface IMakeToggleProps extends IFieldProps {
|
|
6
8
|
element: Omit<IMakeToggle, 'elementType'>;
|
|
7
9
|
}
|
|
10
|
+
export {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { InputHTMLAttributes } from 'react';
|
|
1
2
|
import { IField, IFieldProps } from './field';
|
|
2
|
-
|
|
3
|
+
type IUploadHtmlProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'name' | 'id' | 'style' | 'onChange' | 'value' | 'defaultValue' | 'disabled' | 'type' | 'accept'>;
|
|
4
|
+
export interface IMakeUpload extends Omit<IField, 'defaultValue'>, IUploadHtmlProps {
|
|
3
5
|
elementType: 'upload';
|
|
4
6
|
helpText?: string;
|
|
5
7
|
read: boolean;
|
|
@@ -10,3 +12,4 @@ export interface IMakeUpload extends Omit<IField, 'defaultValue'> {
|
|
|
10
12
|
export interface IMakeUploadProps extends IFieldProps {
|
|
11
13
|
element: Omit<IMakeUpload, 'elementType'>;
|
|
12
14
|
}
|
|
15
|
+
export {};
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import { InputHTMLAttributes } from 'react';
|
|
1
2
|
import { IField, IFieldProps } from './field';
|
|
2
|
-
|
|
3
|
+
type IWatcherBaseProps = Pick<IField, 'style' | 'label' | 'customProperties'>;
|
|
4
|
+
type IWatcherHtmlProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'name' | 'id' | 'style' | 'onChange' | 'value' | 'defaultValue' | 'disabled' | 'type'>;
|
|
5
|
+
export interface IMakeWatcher extends IWatcherBaseProps, IWatcherHtmlProps {
|
|
3
6
|
elementType: 'watcher';
|
|
4
7
|
watchList: Array<string>;
|
|
5
8
|
}
|
|
6
9
|
export interface IMakeWatcherProps extends IFieldProps {
|
|
7
10
|
element: Omit<IMakeWatcher, 'elementType'>;
|
|
8
11
|
}
|
|
12
|
+
export {};
|
|
@@ -23,9 +23,25 @@ export type IModalLiveDataCondition = {
|
|
|
23
23
|
action: (data: string, ...args: any[]) => Promise<Array<IOption>>;
|
|
24
24
|
condition: Array<string>;
|
|
25
25
|
};
|
|
26
|
+
export interface IModalSectionStyleConfig {
|
|
27
|
+
className?: string;
|
|
28
|
+
style?: CSSProperties;
|
|
29
|
+
}
|
|
30
|
+
export interface IModalLayoutConfig {
|
|
31
|
+
container?: IModalSectionStyleConfig;
|
|
32
|
+
header?: IModalSectionStyleConfig & {
|
|
33
|
+
showDivider?: boolean;
|
|
34
|
+
};
|
|
35
|
+
title?: IModalSectionStyleConfig;
|
|
36
|
+
body?: IModalSectionStyleConfig;
|
|
37
|
+
footer?: IModalSectionStyleConfig & {
|
|
38
|
+
showDivider?: boolean;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
26
41
|
export interface IModalConfigProps {
|
|
27
42
|
reservedData?: Record<string, any>;
|
|
28
43
|
title: string;
|
|
44
|
+
layout?: IModalLayoutConfig;
|
|
29
45
|
fields: Array<IModalField>;
|
|
30
46
|
out: (data: any) => void;
|
|
31
47
|
onClose?: () => void;
|
package/dist/src/modal.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { createElement as _createElement } from "react";
|
|
4
4
|
import { useContext, useEffect, useMemo, useState } from 'react';
|
|
5
5
|
import { useForm } from 'react-hook-form';
|
|
@@ -35,12 +35,8 @@ const renderModalField = (field, index, { fieldProps, getValues }) => {
|
|
|
35
35
|
const fieldKey = getFieldKey(field, index);
|
|
36
36
|
return elementType === 'input' ? (_createElement(MakeInput, { ...fieldProps, key: fieldKey, element: element })) : elementType === 'select' ? (_createElement(MakeSelect, { ...fieldProps, key: fieldKey, element: element })) : elementType === 'textarea' ? (_createElement(MakeTextarea, { ...fieldProps, key: fieldKey, element: element })) : elementType === 'toggle' ? (_createElement(MakeToggle, { ...fieldProps, key: fieldKey, element: element })) : elementType === 'text' ? (_createElement(MakeDescription, { ...fieldProps, key: fieldKey, element: element })) : elementType === 'upload' ? (_createElement(MakeUpload, { ...fieldProps, key: fieldKey, element: element })) : elementType === 'custom-upload' ? (_createElement(MakeCustomUpload, { ...fieldProps, key: fieldKey, element: element })) : elementType === 'watcher' ? (_createElement(MakeWatcher, { ...fieldProps, key: fieldKey, element: element })) : elementType === 'button' ? (_createElement(MakeButton, { ...fieldProps, key: fieldKey, element: element, getValues: getValues })) : elementType === 'table' ? (_createElement(MakeTable, { ...fieldProps, key: fieldKey, element: element })) : null;
|
|
37
37
|
};
|
|
38
|
-
const ModalFields = ({ modalReady, fieldProps, getValues, }) => {
|
|
39
|
-
|
|
40
|
-
overflowY: modalReady.overFlowBody ? 'auto' : undefined,
|
|
41
|
-
height: modalReady.overFlowBody,
|
|
42
|
-
minHeight: modalReady.minHeightBody,
|
|
43
|
-
}, children: modalReady.fields.map((element, index) => {
|
|
38
|
+
const ModalFields = ({ modalReady, fieldProps, getValues, BodyComponent, bodyClassName, bodyStyle, }) => {
|
|
39
|
+
const bodyContent = (_jsx(_Fragment, { children: modalReady.fields.map((element, index) => {
|
|
44
40
|
if (element.elementType !== 'group') {
|
|
45
41
|
return renderModalField(element, index, { fieldProps, getValues });
|
|
46
42
|
}
|
|
@@ -50,15 +46,36 @@ const ModalFields = ({ modalReady, fieldProps, getValues, }) => {
|
|
|
50
46
|
const hideDiv = groupElements.every((component) => component === null);
|
|
51
47
|
return (_jsxs("div", { className: `flex flex-col w-full gap-2 ${hideDiv && 'hidden'}`, children: [element.title && (_jsx("h3", { className: "font-bold border-b-2 pb-2 mb-2", children: element.title })), _jsx("div", { className: "flex gap-4 w-full", style: element.style, children: groupElements })] }, getFieldKey(element, index)));
|
|
52
48
|
}) }));
|
|
49
|
+
const currentBodyClassName = `flex flex-col gap-4 py-4${bodyClassName ? ` ${bodyClassName}` : ''}`;
|
|
50
|
+
const currentBodyStyle = {
|
|
51
|
+
overflowY: modalReady.overFlowBody ? 'auto' : undefined,
|
|
52
|
+
height: modalReady.overFlowBody,
|
|
53
|
+
minHeight: modalReady.minHeightBody,
|
|
54
|
+
...bodyStyle,
|
|
55
|
+
};
|
|
56
|
+
if (BodyComponent) {
|
|
57
|
+
return (_jsx(BodyComponent, { className: currentBodyClassName, style: currentBodyStyle, children: bodyContent }));
|
|
58
|
+
}
|
|
59
|
+
return (_jsx("div", { className: currentBodyClassName, style: currentBodyStyle, children: bodyContent }));
|
|
53
60
|
};
|
|
54
|
-
const ModalActions = ({ modalReady, closeHandler, manualSubmit, }) => {
|
|
61
|
+
const ModalActions = ({ modalReady, closeHandler, manualSubmit, FooterComponent, footerClassName, footerStyle, showFooterDivider = true, }) => {
|
|
55
62
|
const { ModalButtonAction, ModalButtonCancel } = useContext(ComponentStateContext);
|
|
56
|
-
|
|
63
|
+
const footerContent = (_jsxs(_Fragment, { children: [modalReady.actions.cancel && (_jsx(ModalButtonCancel, { ...modalReady.actions.cancel, onClick: closeHandler })), getUseSubmit(modalReady) ? (_jsx(ModalButtonAction, { ...modalReady.actions.action, type: "submit" })) : (_jsx(ModalButtonAction, { ...modalReady.actions.action, onClick: manualSubmit, type: "button" }))] }));
|
|
64
|
+
const currentFooterClassName = `flex gap-4 items-center justify-center p-2${showFooterDivider ? ' border-t' : ''}${footerClassName ? ` ${footerClassName}` : ''}`;
|
|
65
|
+
const currentFooterStyle = {
|
|
66
|
+
...footerStyle,
|
|
67
|
+
...modalReady.actions.containerStyle,
|
|
68
|
+
};
|
|
69
|
+
if (FooterComponent) {
|
|
70
|
+
return (_jsx(FooterComponent, { className: currentFooterClassName, style: currentFooterStyle, children: footerContent }));
|
|
71
|
+
}
|
|
72
|
+
return (_jsx("div", { className: currentFooterClassName, style: currentFooterStyle, children: footerContent }));
|
|
57
73
|
};
|
|
58
74
|
export const Modal = ({ open, close, config }) => {
|
|
59
75
|
const [modalReady, setModalReady] = useState(undefined);
|
|
60
76
|
const [defaultLoaded, setDefaultLoaded] = useState(false);
|
|
61
77
|
const { control, handleSubmit, getValues, unregister, setValue, watch, trigger, reset, getFieldState, } = useForm();
|
|
78
|
+
const { ModalContainer, ModalHeader, ModalTitle, ModalBody, ModalFooter } = useContext(ComponentStateContext);
|
|
62
79
|
const formValueHandler = (element) => {
|
|
63
80
|
if ([
|
|
64
81
|
'group',
|
|
@@ -148,6 +165,14 @@ export const Modal = ({ open, close, config }) => {
|
|
|
148
165
|
}, [defaultLoaded, modalReady]);
|
|
149
166
|
if (!modalReady)
|
|
150
167
|
return null;
|
|
151
|
-
|
|
168
|
+
const { container: containerLayout, header: headerLayout, title: titleLayout, body: bodyLayout, footer: footerLayout, } = modalReady.layout ?? {};
|
|
169
|
+
const showHeaderDivider = headerLayout?.showDivider !== false;
|
|
170
|
+
const showFooterDivider = footerLayout?.showDivider !== false;
|
|
171
|
+
const headerClassName = `w-full text-center${showHeaderDivider ? ' border-b pb-4' : ''}${headerLayout?.className ? ` ${headerLayout.className}` : ''}`;
|
|
172
|
+
const titleClassName = `font-semibold${titleLayout?.className ? ` ${titleLayout.className}` : ''}`;
|
|
173
|
+
const titleContent = ModalTitle ? (_jsx(ModalTitle, { className: titleClassName, style: titleLayout?.style, children: modalReady.title })) : (_jsx("h2", { className: titleClassName, style: titleLayout?.style, children: modalReady.title }));
|
|
174
|
+
const headerContent = ModalHeader ? (_jsx(ModalHeader, { className: headerClassName, style: headerLayout?.style, children: titleContent })) : (_jsx("div", { className: headerClassName, style: headerLayout?.style, children: titleContent }));
|
|
175
|
+
const modalContent = (_jsxs("form", { className: "flex flex-col p-4 gap-4", autoComplete: "off", onSubmit: handleSubmit(actionHandler), children: [headerContent, _jsx(ModalFields, { modalReady: modalReady, fieldProps: fieldProps, getValues: getValues, BodyComponent: ModalBody, bodyClassName: bodyLayout?.className, bodyStyle: bodyLayout?.style }), _jsx(ModalActions, { modalReady: modalReady, closeHandler: closeHandler, manualSubmit: manualSubmit, FooterComponent: ModalFooter, footerClassName: footerLayout?.className, footerStyle: footerLayout?.style, showFooterDivider: showFooterDivider })] }));
|
|
176
|
+
return (_jsx(Portal, { closeTime: 200, portalOpen: open, portalTag: '#modal-portal', useBlur: modalReady.useBlur, children: ModalContainer ? (_jsx(ModalContainer, { className: `rounded bg-white relative w-auto h-auto min-h-[200px] min-w-[500px]${modalReady.useBlur ? ' shadow-md border border-gray-200' : ''}${containerLayout?.className ? ` ${containerLayout.className}` : ''}`, style: { ...modalReady.style, ...containerLayout?.style }, children: modalContent })) : (_jsx("div", { className: `rounded bg-white relative w-auto h-auto min-h-[200px] min-w-[500px]${modalReady.useBlur ? ' shadow-md border border-gray-200' : ''}${containerLayout?.className ? ` ${containerLayout.className}` : ''}`, style: { ...modalReady.style, ...containerLayout?.style }, children: modalContent })) }));
|
|
152
177
|
};
|
|
153
178
|
export default Modal;
|
package/package.json
CHANGED