dynamic-modal 1.1.4 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README-ES.md +217 -217
  2. package/README.md +216 -216
  3. package/dist/components/input-upload/input-upload.js +1 -1
  4. package/dist/components/make-button/make-button.js +7 -17
  5. package/dist/components/make-input/make-input.js +7 -17
  6. package/dist/components/make-select/make-select.js +7 -17
  7. package/dist/components/make-textarea/make-textarea.js +7 -17
  8. package/dist/components/make-toggle/make-toggle.js +7 -17
  9. package/dist/components/portal/portal.js +7 -17
  10. package/dist/context/component/component-state.js +7 -17
  11. package/dist/interfaces/modal.d.ts +1 -0
  12. package/dist/modal.js +38 -19
  13. package/eslint.config.mjs +14 -14
  14. package/examples/enable-if.ts +127 -127
  15. package/examples/live-data.ts +61 -61
  16. package/examples/render-if.ts +128 -128
  17. package/examples/simple.ts +74 -74
  18. package/index.ts +5 -5
  19. package/package.json +46 -47
  20. package/src/components/input-upload/input-upload.tsx +67 -67
  21. package/src/components/make-button/make-button.tsx +18 -18
  22. package/src/components/make-description/make-description.tsx +15 -15
  23. package/src/components/make-input/make-input.tsx +53 -53
  24. package/src/components/make-select/make-select.tsx +55 -55
  25. package/src/components/make-textarea/make-textarea.tsx +53 -53
  26. package/src/components/make-toggle/make-toggle.tsx +53 -53
  27. package/src/components/make-upload/make-upload.tsx +40 -40
  28. package/src/components/portal/portal.tsx +37 -37
  29. package/src/context/component/component-state.tsx +17 -17
  30. package/src/hooks/field-render.ts +109 -109
  31. package/src/hooks/modal-handler.ts +38 -38
  32. package/src/interfaces/component-state.ts +33 -33
  33. package/src/interfaces/field.ts +37 -37
  34. package/src/interfaces/input-upload.ts +21 -21
  35. package/src/interfaces/make-button.ts +19 -19
  36. package/src/interfaces/make-description.ts +14 -14
  37. package/src/interfaces/make-field-group.ts +14 -14
  38. package/src/interfaces/make-input.ts +14 -14
  39. package/src/interfaces/make-select.ts +15 -15
  40. package/src/interfaces/make-textarea.ts +11 -11
  41. package/src/interfaces/make-toggle.ts +9 -9
  42. package/src/interfaces/make-upload.ts +14 -14
  43. package/src/interfaces/modal.ts +47 -46
  44. package/src/interfaces/option.ts +3 -3
  45. package/src/interfaces/portal.ts +8 -8
  46. package/src/modal.tsx +196 -164
  47. package/src/tools/general.ts +8 -8
  48. package/tsconfig.json +13 -13
@@ -1,18 +1,18 @@
1
- 'use client'
2
-
3
- import React, { FC, useContext, useMemo } from 'react'
4
- import { IMakeButtonProps } from '../../interfaces/make-button'
5
- import { ComponentStateContext } from '../../context/component/component-state'
6
- import { generateId } from '../../tools/general'
7
-
8
- const MakeButton: FC<IMakeButtonProps> = ({ element }) => {
9
- const { Button } = useContext(ComponentStateContext)
10
-
11
- const elementId = useMemo(() => element.id ?? generateId(), [])
12
-
13
- return (
14
- <Button {...element} id={elementId} />
15
- )
16
- }
17
-
18
- export default MakeButton
1
+ 'use client'
2
+
3
+ import React, { FC, useContext, useMemo } from 'react'
4
+ import { IMakeButtonProps } from '../../interfaces/make-button'
5
+ import { ComponentStateContext } from '../../context/component/component-state'
6
+ import { generateId } from '../../tools/general'
7
+
8
+ const MakeButton: FC<IMakeButtonProps> = ({ element }) => {
9
+ const { Button } = useContext(ComponentStateContext)
10
+
11
+ const elementId = useMemo(() => element.id ?? generateId(), [])
12
+
13
+ return (
14
+ <Button {...element} id={elementId} />
15
+ )
16
+ }
17
+
18
+ export default MakeButton
@@ -1,15 +1,15 @@
1
- 'use client'
2
-
3
- import React, { FC } from 'react'
4
- import { IMakeDescriptionProps } from '../../interfaces/make-description'
5
-
6
- const MakeDescription: FC<IMakeDescriptionProps> = ({ element: { text, Icon, containerStyle, textStyle } }) => {
7
- return (
8
- <div className='flex gap-4 w-full h-auto text-xs text-center p-2 border-1 rounded-md' style={containerStyle}>
9
- {Icon && <Icon />}
10
- <p style={textStyle}>{text}</p>
11
- </div>
12
- )
13
- }
14
-
15
- export default MakeDescription
1
+ 'use client'
2
+
3
+ import React, { FC } from 'react'
4
+ import { IMakeDescriptionProps } from '../../interfaces/make-description'
5
+
6
+ const MakeDescription: FC<IMakeDescriptionProps> = ({ element: { text, Icon, containerStyle, textStyle } }) => {
7
+ return (
8
+ <div className='flex gap-4 w-full h-auto text-xs text-center p-2 border-1 rounded-md' style={containerStyle}>
9
+ {Icon && <Icon />}
10
+ <p style={textStyle}>{text}</p>
11
+ </div>
12
+ )
13
+ }
14
+
15
+ export default MakeDescription
@@ -1,53 +1,53 @@
1
- 'use client'
2
-
3
- import React, { FC, useContext, useEffect, useMemo } from 'react'
4
- import { Controller } from 'react-hook-form'
5
- import { useFieldRender } from '../../hooks/field-render'
6
- import { IMakeInputProps } from '../../interfaces/make-input'
7
- import { ComponentStateContext } from '../../context/component/component-state'
8
- import { generateId } from '../../tools/general'
9
-
10
- const MakeInput: FC<IMakeInputProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
11
- const { Input } = useContext(ComponentStateContext)
12
- const { render, enable, checkField } = useFieldRender({ ...props, element: { enableIf, renderIf, ...element} })
13
-
14
- const elementId = useMemo(() => element.id ?? generateId(), [])
15
-
16
- useEffect(() => {
17
- const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
18
- return () => subscription.unsubscribe()
19
- }, [checkField, props])
20
-
21
- return (
22
- render
23
- ? <Controller
24
- control={props.control}
25
- name={element.name}
26
- rules={{
27
- required: {
28
- value: required,
29
- message: validation.message ?? ''
30
- },
31
- pattern: validation.regex ? {
32
- value: validation.regex,
33
- message: validation.message ?? ''
34
- } : undefined,
35
- ...validation
36
- }}
37
- render={({ field: { onChange, value }, fieldState: { invalid, error } }) => (
38
- <Input
39
- {...element}
40
- id={elementId}
41
- onChange={onChange}
42
- value={value ?? ''}
43
- invalid={invalid}
44
- error={error}
45
- disabled={element.disabled ?? !enable}
46
- />
47
- )}
48
- />
49
- : null
50
- )
51
- }
52
-
53
- export default MakeInput
1
+ 'use client'
2
+
3
+ import React, { FC, useContext, useEffect, useMemo } from 'react'
4
+ import { Controller } from 'react-hook-form'
5
+ import { useFieldRender } from '../../hooks/field-render'
6
+ import { IMakeInputProps } from '../../interfaces/make-input'
7
+ import { ComponentStateContext } from '../../context/component/component-state'
8
+ import { generateId } from '../../tools/general'
9
+
10
+ const MakeInput: FC<IMakeInputProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
11
+ const { Input } = useContext(ComponentStateContext)
12
+ const { render, enable, checkField } = useFieldRender({ ...props, element: { enableIf, renderIf, ...element} })
13
+
14
+ const elementId = useMemo(() => element.id ?? generateId(), [])
15
+
16
+ useEffect(() => {
17
+ const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
18
+ return () => subscription.unsubscribe()
19
+ }, [checkField, props])
20
+
21
+ return (
22
+ render
23
+ ? <Controller
24
+ control={props.control}
25
+ name={element.name}
26
+ rules={{
27
+ required: {
28
+ value: required,
29
+ message: validation.message ?? ''
30
+ },
31
+ pattern: validation.regex ? {
32
+ value: validation.regex,
33
+ message: validation.message ?? ''
34
+ } : undefined,
35
+ ...validation
36
+ }}
37
+ render={({ field: { onChange, value }, fieldState: { invalid, error } }) => (
38
+ <Input
39
+ {...element}
40
+ id={elementId}
41
+ onChange={onChange}
42
+ value={value ?? ''}
43
+ invalid={invalid}
44
+ error={error}
45
+ disabled={element.disabled ?? !enable}
46
+ />
47
+ )}
48
+ />
49
+ : null
50
+ )
51
+ }
52
+
53
+ export default MakeInput
@@ -1,55 +1,55 @@
1
- 'use client'
2
-
3
- import React, { FC, useContext, useEffect, useMemo } from 'react'
4
- import { Controller } from 'react-hook-form'
5
- import { useFieldRender } from '../../hooks/field-render'
6
- import { generateId } from '../../tools/general'
7
- import { IMakeSelectProps } from '../../interfaces/make-select'
8
- import { ComponentStateContext } from '../../context/component/component-state'
9
-
10
- const MakeSelect: FC<IMakeSelectProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
11
- const { Select } = useContext(ComponentStateContext)
12
- const { render, enable, checkField, liveData, liveSearching } = useFieldRender({ ...props, element: { renderIf, enableIf, ...element} })
13
-
14
- const elementId = useMemo(() => element.id ?? generateId(), [])
15
-
16
- useEffect(() => {
17
- const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
18
- return () => subscription.unsubscribe()
19
- }, [checkField, props, props.watch])
20
-
21
- return (
22
- render
23
- ? <Controller
24
- control={props.control}
25
- name={element.name}
26
- rules={{
27
- required: {
28
- value: required,
29
- message: validation.message ?? ''
30
- },
31
- pattern: validation.regex ? {
32
- value: validation.regex,
33
- message: validation.message ?? ''
34
- } : undefined,
35
- ...validation
36
- }}
37
- render={({ field: { onChange, value }, fieldState: { invalid, error } }) => (
38
- <Select
39
- {...element}
40
- id={elementId}
41
- onChange={onChange}
42
- value={value}
43
- invalid={invalid}
44
- error={error}
45
- disabled={element.disabled ?? !enable}
46
- liveSearching={liveSearching}
47
- options={liveData || (element.options ?? [])}
48
- />
49
- )}
50
- />
51
- : <></>
52
- )
53
- }
54
-
55
- export default MakeSelect
1
+ 'use client'
2
+
3
+ import React, { FC, useContext, useEffect, useMemo } from 'react'
4
+ import { Controller } from 'react-hook-form'
5
+ import { useFieldRender } from '../../hooks/field-render'
6
+ import { generateId } from '../../tools/general'
7
+ import { IMakeSelectProps } from '../../interfaces/make-select'
8
+ import { ComponentStateContext } from '../../context/component/component-state'
9
+
10
+ const MakeSelect: FC<IMakeSelectProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
11
+ const { Select } = useContext(ComponentStateContext)
12
+ const { render, enable, checkField, liveData, liveSearching } = useFieldRender({ ...props, element: { renderIf, enableIf, ...element} })
13
+
14
+ const elementId = useMemo(() => element.id ?? generateId(), [])
15
+
16
+ useEffect(() => {
17
+ const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
18
+ return () => subscription.unsubscribe()
19
+ }, [checkField, props, props.watch])
20
+
21
+ return (
22
+ render
23
+ ? <Controller
24
+ control={props.control}
25
+ name={element.name}
26
+ rules={{
27
+ required: {
28
+ value: required,
29
+ message: validation.message ?? ''
30
+ },
31
+ pattern: validation.regex ? {
32
+ value: validation.regex,
33
+ message: validation.message ?? ''
34
+ } : undefined,
35
+ ...validation
36
+ }}
37
+ render={({ field: { onChange, value }, fieldState: { invalid, error } }) => (
38
+ <Select
39
+ {...element}
40
+ id={elementId}
41
+ onChange={onChange}
42
+ value={value}
43
+ invalid={invalid}
44
+ error={error}
45
+ disabled={element.disabled ?? !enable}
46
+ liveSearching={liveSearching}
47
+ options={liveData || (element.options ?? [])}
48
+ />
49
+ )}
50
+ />
51
+ : <></>
52
+ )
53
+ }
54
+
55
+ export default MakeSelect
@@ -1,53 +1,53 @@
1
- 'use client'
2
-
3
- import React, { FC, useContext, useEffect, useMemo } from 'react'
4
- import { Controller } from 'react-hook-form'
5
- import { useFieldRender } from '../../hooks/field-render'
6
- import { generateId } from '../../tools/general'
7
- import { IMakeTextareaProps } from '../../interfaces/make-textarea'
8
- import { ComponentStateContext } from '../../context/component/component-state'
9
-
10
- const MakeTextarea: FC<IMakeTextareaProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
11
- const { Textarea } = useContext(ComponentStateContext)
12
- const { render, enable, checkField } = useFieldRender({ ...props, element: { enableIf, renderIf, ...element } })
13
-
14
- const elementId = useMemo(() => element.id ?? generateId(), [])
15
-
16
- useEffect(() => {
17
- const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
18
- return () => subscription.unsubscribe()
19
- }, [checkField, props, props.watch])
20
-
21
- return (
22
- render
23
- ? <Controller
24
- name={element.name}
25
- control={props.control}
26
- rules={{
27
- required: {
28
- value: required,
29
- message: validation.message ?? ''
30
- },
31
- pattern: validation.regex ? {
32
- value: validation.regex,
33
- message: validation.message ?? ''
34
- } : undefined,
35
- ...validation
36
- }}
37
- render={({ field: { onChange, value }, fieldState: { invalid, error } }) => (
38
- <Textarea
39
- {...element}
40
- id={elementId}
41
- onChange={onChange}
42
- value={value ?? ''}
43
- invalid={invalid}
44
- error={error}
45
- disabled={element.disabled ?? !enable}
46
- />
47
- )}
48
- />
49
- : null
50
- )
51
- }
52
-
53
- export default MakeTextarea
1
+ 'use client'
2
+
3
+ import React, { FC, useContext, useEffect, useMemo } from 'react'
4
+ import { Controller } from 'react-hook-form'
5
+ import { useFieldRender } from '../../hooks/field-render'
6
+ import { generateId } from '../../tools/general'
7
+ import { IMakeTextareaProps } from '../../interfaces/make-textarea'
8
+ import { ComponentStateContext } from '../../context/component/component-state'
9
+
10
+ const MakeTextarea: FC<IMakeTextareaProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
11
+ const { Textarea } = useContext(ComponentStateContext)
12
+ const { render, enable, checkField } = useFieldRender({ ...props, element: { enableIf, renderIf, ...element } })
13
+
14
+ const elementId = useMemo(() => element.id ?? generateId(), [])
15
+
16
+ useEffect(() => {
17
+ const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
18
+ return () => subscription.unsubscribe()
19
+ }, [checkField, props, props.watch])
20
+
21
+ return (
22
+ render
23
+ ? <Controller
24
+ name={element.name}
25
+ control={props.control}
26
+ rules={{
27
+ required: {
28
+ value: required,
29
+ message: validation.message ?? ''
30
+ },
31
+ pattern: validation.regex ? {
32
+ value: validation.regex,
33
+ message: validation.message ?? ''
34
+ } : undefined,
35
+ ...validation
36
+ }}
37
+ render={({ field: { onChange, value }, fieldState: { invalid, error } }) => (
38
+ <Textarea
39
+ {...element}
40
+ id={elementId}
41
+ onChange={onChange}
42
+ value={value ?? ''}
43
+ invalid={invalid}
44
+ error={error}
45
+ disabled={element.disabled ?? !enable}
46
+ />
47
+ )}
48
+ />
49
+ : null
50
+ )
51
+ }
52
+
53
+ export default MakeTextarea
@@ -1,53 +1,53 @@
1
- 'use client'
2
-
3
- import React, { FC, useContext, useEffect, useMemo } from 'react'
4
- import { Controller } from 'react-hook-form'
5
- import { useFieldRender } from '../../hooks/field-render'
6
- import { IMakeToggleProps } from '../../interfaces/make-toggle'
7
- import { generateId } from '../../tools/general'
8
- import { ComponentStateContext } from '../../context/component/component-state'
9
-
10
- const MakeToggle: FC<IMakeToggleProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
11
- const { Toggle } = useContext(ComponentStateContext)
12
- const { render, enable, checkField } = useFieldRender({ ...props, element: { enableIf, renderIf, ...element } })
13
-
14
- const elementId = useMemo(() => element.id ?? generateId(), [])
15
-
16
- useEffect(() => {
17
- const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
18
- return () => subscription.unsubscribe()
19
- }, [checkField, props, props.watch])
20
-
21
- return (
22
- render
23
- ? <Controller
24
- control={props.control}
25
- name={element.name}
26
- rules={{
27
- required: {
28
- value: required,
29
- message: validation.message ?? ''
30
- },
31
- pattern: validation.regex ? {
32
- value: validation.regex,
33
- message: validation.message ?? ''
34
- } : undefined,
35
- ...validation
36
- }}
37
- render={({ field: { onChange, value }, fieldState: { invalid, error } }) => (
38
- <Toggle
39
- {...element}
40
- id={elementId}
41
- onChange={onChange}
42
- value={value ?? ''}
43
- invalid={invalid}
44
- error={error}
45
- disabled={element.disabled ?? !enable}
46
- />
47
- )}
48
- />
49
- : null
50
- )
51
- }
52
-
53
- export default MakeToggle
1
+ 'use client'
2
+
3
+ import React, { FC, useContext, useEffect, useMemo } from 'react'
4
+ import { Controller } from 'react-hook-form'
5
+ import { useFieldRender } from '../../hooks/field-render'
6
+ import { IMakeToggleProps } from '../../interfaces/make-toggle'
7
+ import { generateId } from '../../tools/general'
8
+ import { ComponentStateContext } from '../../context/component/component-state'
9
+
10
+ const MakeToggle: FC<IMakeToggleProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
11
+ const { Toggle } = useContext(ComponentStateContext)
12
+ const { render, enable, checkField } = useFieldRender({ ...props, element: { enableIf, renderIf, ...element } })
13
+
14
+ const elementId = useMemo(() => element.id ?? generateId(), [])
15
+
16
+ useEffect(() => {
17
+ const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
18
+ return () => subscription.unsubscribe()
19
+ }, [checkField, props, props.watch])
20
+
21
+ return (
22
+ render
23
+ ? <Controller
24
+ control={props.control}
25
+ name={element.name}
26
+ rules={{
27
+ required: {
28
+ value: required,
29
+ message: validation.message ?? ''
30
+ },
31
+ pattern: validation.regex ? {
32
+ value: validation.regex,
33
+ message: validation.message ?? ''
34
+ } : undefined,
35
+ ...validation
36
+ }}
37
+ render={({ field: { onChange, value }, fieldState: { invalid, error } }) => (
38
+ <Toggle
39
+ {...element}
40
+ id={elementId}
41
+ onChange={onChange}
42
+ value={value ?? ''}
43
+ invalid={invalid}
44
+ error={error}
45
+ disabled={element.disabled ?? !enable}
46
+ />
47
+ )}
48
+ />
49
+ : null
50
+ )
51
+ }
52
+
53
+ export default MakeToggle
@@ -1,40 +1,40 @@
1
- 'use client'
2
-
3
- import React,{ FC } from 'react'
4
- import { Controller } from 'react-hook-form'
5
- import InputUpload from '../input-upload/input-upload'
6
- import { useFieldRender } from '../../hooks/field-render'
7
- import { IMakeUploadProps } from '../../interfaces/make-upload'
8
-
9
- const MakeUpload : FC<IMakeUploadProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
10
- const { render, enable } = useFieldRender({ ...props, element: { enableIf, renderIf, ...element} })
11
-
12
- return (
13
- render
14
- ? <Controller
15
- control={props.control}
16
- name={element.name}
17
- rules={{
18
- required: {
19
- value: required,
20
- message: validation.message ?? ''
21
- },
22
- pattern: validation.regex ? {
23
- value: validation.regex,
24
- message: validation.message ?? ''
25
- } : undefined,
26
- ...validation
27
- }}
28
- render={({ field: { onChange } }) => (
29
- <InputUpload
30
- {...element}
31
- onChange={onChange}
32
- disabled={element.disabled ?? !enable}
33
- />
34
- )}
35
- />
36
- : null
37
- )
38
- }
39
-
40
- export default MakeUpload
1
+ 'use client'
2
+
3
+ import React,{ FC } from 'react'
4
+ import { Controller } from 'react-hook-form'
5
+ import InputUpload from '../input-upload/input-upload'
6
+ import { useFieldRender } from '../../hooks/field-render'
7
+ import { IMakeUploadProps } from '../../interfaces/make-upload'
8
+
9
+ const MakeUpload : FC<IMakeUploadProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
10
+ const { render, enable } = useFieldRender({ ...props, element: { enableIf, renderIf, ...element} })
11
+
12
+ return (
13
+ render
14
+ ? <Controller
15
+ control={props.control}
16
+ name={element.name}
17
+ rules={{
18
+ required: {
19
+ value: required,
20
+ message: validation.message ?? ''
21
+ },
22
+ pattern: validation.regex ? {
23
+ value: validation.regex,
24
+ message: validation.message ?? ''
25
+ } : undefined,
26
+ ...validation
27
+ }}
28
+ render={({ field: { onChange } }) => (
29
+ <InputUpload
30
+ {...element}
31
+ onChange={onChange}
32
+ disabled={element.disabled ?? !enable}
33
+ />
34
+ )}
35
+ />
36
+ : null
37
+ )
38
+ }
39
+
40
+ export default MakeUpload
@@ -1,37 +1,37 @@
1
- 'use client'
2
-
3
- import React, { useRef, useEffect, useState, FC } from 'react'
4
- import { createPortal } from 'react-dom'
5
- import { IPortal } from '../../interfaces/portal'
6
-
7
- export const Portal: FC<IPortal> = (props) => {
8
- const ref = useRef<Element | null>(null)
9
- const [mounted, setMounted] = useState(false)
10
-
11
- useEffect(() => {
12
- if (mounted && !props.portalOpen && props.closeTime > 0) {
13
- const timeoutId = setTimeout(() => {
14
- setMounted(false)
15
- ref.current = null
16
- }, props.closeTime)
17
-
18
- return () => clearTimeout(timeoutId)
19
- } else if (mounted && !props.portalOpen) {
20
- setMounted(false)
21
- ref.current = null
22
- } else if (!mounted && props.portalOpen) {
23
- ref.current = document.querySelector<HTMLElement>(props.portalTag ?? '#portal')
24
- setMounted(true)
25
- }
26
- }, [mounted, props.closeTime, props.portalOpen, props.portalTag])
27
-
28
- return (
29
- mounted && ref.current
30
- ? createPortal(
31
- <div className='transition-all delay-100 fixed top-0 left-0 w-full h-full grid place-items-center bg-black bg-opacity-40 z-20'>
32
- {props.children}
33
- </div>
34
- , ref.current)
35
- : null
36
- )
37
- }
1
+ 'use client'
2
+
3
+ import React, { useRef, useEffect, useState, FC } from 'react'
4
+ import { createPortal } from 'react-dom'
5
+ import { IPortal } from '../../interfaces/portal'
6
+
7
+ export const Portal: FC<IPortal> = (props) => {
8
+ const ref = useRef<Element | null>(null)
9
+ const [mounted, setMounted] = useState(false)
10
+
11
+ useEffect(() => {
12
+ if (mounted && !props.portalOpen && props.closeTime > 0) {
13
+ const timeoutId = setTimeout(() => {
14
+ setMounted(false)
15
+ ref.current = null
16
+ }, props.closeTime)
17
+
18
+ return () => clearTimeout(timeoutId)
19
+ } else if (mounted && !props.portalOpen) {
20
+ setMounted(false)
21
+ ref.current = null
22
+ } else if (!mounted && props.portalOpen) {
23
+ ref.current = document.querySelector<HTMLElement>(props.portalTag ?? '#portal')
24
+ setMounted(true)
25
+ }
26
+ }, [mounted, props.closeTime, props.portalOpen, props.portalTag])
27
+
28
+ return (
29
+ mounted && ref.current
30
+ ? createPortal(
31
+ <div className='transition-all delay-100 fixed top-0 left-0 w-full h-full grid place-items-center bg-black bg-opacity-40 z-20'>
32
+ {props.children}
33
+ </div>
34
+ , ref.current)
35
+ : null
36
+ )
37
+ }