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 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
- export interface ICustomUpload {
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 {};
@@ -10,6 +10,7 @@ export interface IField {
10
10
  id?: string;
11
11
  label?: string;
12
12
  style?: CSSProperties;
13
+ customProperties?: Record<string, any>;
13
14
  placeholder?: string;
14
15
  defaultValue?: any;
15
16
  renderIf?: IModalRenderCondition;
@@ -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
- export interface IMakeButton {
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
- export interface IMakeCustomUpload extends IField {
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
- export interface IMakeDescription {
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
- export interface IMakeFieldGroup {
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
- export interface IMakeInput extends IField {
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
- export interface IMakeSelect extends IField {
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
- export interface IMakeTable extends Omit<IField, 'label' | 'defaultValue' | 'validation' | 'disabled' | 'enableIf' | 'id'> {
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
- export interface IMakeTextarea extends IField {
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
- export interface IMakeToggle extends IField {
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
- export interface IMakeUpload extends Omit<IField, 'defaultValue'> {
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
- export interface IMakeWatcher extends Pick<IField, 'style' | 'label'> {
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
- return (_jsx("div", { className: "flex flex-col gap-4 py-4", style: {
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
- return (_jsxs("div", { className: "flex gap-4 items-center justify-center border-t p-2", style: modalReady.actions.containerStyle, 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" }))] }));
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
- return (_jsx(Portal, { closeTime: 200, portalOpen: open, portalTag: '#modal-portal', useBlur: modalReady.useBlur, children: _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'}`, style: modalReady.style, children: _jsxs("form", { className: "flex flex-col p-4 gap-4", autoComplete: "off", onSubmit: handleSubmit(actionHandler), children: [_jsx("h2", { className: "text-bold text-center border-b pb-4 font-semibold", children: modalReady.title }), _jsx(ModalFields, { modalReady: modalReady, fieldProps: fieldProps, getValues: getValues }), _jsx(ModalActions, { modalReady: modalReady, closeHandler: closeHandler, manualSubmit: manualSubmit })] }) }) }));
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dynamic-modal",
3
- "version": "1.1.25",
3
+ "version": "1.1.26",
4
4
  "description": "The dynamic-modal is a solution of creation different modals into project using a json configuration file",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",