@inertiaui/modal-react 0.14.0 → 0.15.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/dist/inertiaui-modal.js +1834 -1851
- package/dist/inertiaui-modal.umd.cjs +20 -13
- package/package.json +4 -5
- package/src/Modal.jsx +13 -6
- package/src/ModalContent.jsx +24 -15
- package/src/SlideoverContent.jsx +24 -15
- package/src/helpers.js +2 -2
- package/src/useFocusTrap.js +25 -0
package/src/ModalContent.jsx
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { TransitionChild
|
|
1
|
+
import { TransitionChild } from '@headlessui/react'
|
|
2
2
|
import CloseButton from './CloseButton'
|
|
3
3
|
import clsx from 'clsx'
|
|
4
|
+
import { useFocusTrap } from './useFocusTrap'
|
|
4
5
|
|
|
5
6
|
const ModalContent = ({ modalContext, config, children }) => {
|
|
7
|
+
const wrapper = useFocusTrap(config?.closeExplicitly, () => modalContext.close())
|
|
8
|
+
|
|
6
9
|
return (
|
|
7
10
|
<div className="im-modal-container fixed inset-0 z-40 overflow-y-auto p-4">
|
|
8
11
|
<div
|
|
@@ -13,32 +16,38 @@ const ModalContent = ({ modalContext, config, children }) => {
|
|
|
13
16
|
})}
|
|
14
17
|
>
|
|
15
18
|
<TransitionChild
|
|
19
|
+
as="div"
|
|
20
|
+
ref={wrapper}
|
|
16
21
|
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
|
17
22
|
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
|
18
23
|
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
|
19
24
|
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
|
20
25
|
afterLeave={modalContext.afterLeave}
|
|
21
|
-
className={clsx(
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
className={clsx(
|
|
27
|
+
'im-modal-wrapper pointer-events-auto w-full transition duration-300 ease-in-out',
|
|
28
|
+
modalContext.onTopOfStack ? '' : 'blur-sm',
|
|
29
|
+
{
|
|
30
|
+
'sm:max-w-sm': config.maxWidth === 'sm',
|
|
31
|
+
'sm:max-w-md': config.maxWidth === 'md',
|
|
32
|
+
'sm:max-w-md md:max-w-lg': config.maxWidth === 'lg',
|
|
33
|
+
'sm:max-w-md md:max-w-xl': config.maxWidth === 'xl',
|
|
34
|
+
'sm:max-w-md md:max-w-xl lg:max-w-2xl': config.maxWidth === '2xl',
|
|
35
|
+
'sm:max-w-md md:max-w-xl lg:max-w-3xl': config.maxWidth === '3xl',
|
|
36
|
+
'sm:max-w-md md:max-w-xl lg:max-w-3xl xl:max-w-4xl': config.maxWidth === '4xl',
|
|
37
|
+
'sm:max-w-md md:max-w-xl lg:max-w-3xl xl:max-w-5xl': config.maxWidth === '5xl',
|
|
38
|
+
'sm:max-w-md md:max-w-xl lg:max-w-3xl xl:max-w-5xl 2xl:max-w-6xl': config.maxWidth === '6xl',
|
|
39
|
+
'sm:max-w-md md:max-w-xl lg:max-w-3xl xl:max-w-5xl 2xl:max-w-7xl': config.maxWidth === '7xl',
|
|
40
|
+
},
|
|
41
|
+
)}
|
|
33
42
|
>
|
|
34
|
-
<
|
|
43
|
+
<div className={`im-modal-content relative ${config.paddingClasses} ${config.panelClasses}`}>
|
|
35
44
|
{config.closeButton && (
|
|
36
45
|
<div className="absolute right-0 top-0 pr-3 pt-3">
|
|
37
46
|
<CloseButton onClick={modalContext.close} />
|
|
38
47
|
</div>
|
|
39
48
|
)}
|
|
40
49
|
{typeof children === 'function' ? children({ modalContext, config }) : children}
|
|
41
|
-
</
|
|
50
|
+
</div>
|
|
42
51
|
</TransitionChild>
|
|
43
52
|
</div>
|
|
44
53
|
</div>
|
package/src/SlideoverContent.jsx
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { TransitionChild
|
|
1
|
+
import { TransitionChild } from '@headlessui/react'
|
|
2
2
|
import CloseButton from './CloseButton'
|
|
3
3
|
import clsx from 'clsx'
|
|
4
|
+
import { useFocusTrap } from './useFocusTrap'
|
|
4
5
|
|
|
5
6
|
const SlideoverContent = ({ modalContext, config, children }) => {
|
|
7
|
+
const wrapper = useFocusTrap(config?.closeExplicitly, () => modalContext.close())
|
|
8
|
+
|
|
6
9
|
return (
|
|
7
10
|
<div className="im-slideover-container fixed inset-0 z-40 overflow-y-auto overflow-x-hidden">
|
|
8
11
|
<div
|
|
@@ -12,32 +15,38 @@ const SlideoverContent = ({ modalContext, config, children }) => {
|
|
|
12
15
|
})}
|
|
13
16
|
>
|
|
14
17
|
<TransitionChild
|
|
18
|
+
as="div"
|
|
19
|
+
ref={wrapper}
|
|
15
20
|
enterFrom={`opacity-0 ${config.position === 'left' ? '-translate-x-full' : 'translate-x-full'}`}
|
|
16
21
|
enterTo="opacity-100 translate-x-0"
|
|
17
22
|
leaveFrom="opacity-100 translate-x-0"
|
|
18
23
|
leaveTo={`opacity-0 ${config.position === 'left' ? '-translate-x-full' : 'translate-x-full'}`}
|
|
19
24
|
afterLeave={modalContext.afterLeave}
|
|
20
|
-
className={clsx(
|
|
21
|
-
'
|
|
22
|
-
'
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
className={clsx(
|
|
26
|
+
'im-slideover-wrapper pointer-events-auto w-full transition duration-300 ease-in-out',
|
|
27
|
+
modalContext.onTopOfStack ? '' : 'blur-sm',
|
|
28
|
+
{
|
|
29
|
+
'sm:max-w-sm': config.maxWidth === 'sm',
|
|
30
|
+
'sm:max-w-md': config.maxWidth === 'md',
|
|
31
|
+
'sm:max-w-md md:max-w-lg': config.maxWidth === 'lg',
|
|
32
|
+
'sm:max-w-md md:max-w-xl': config.maxWidth === 'xl',
|
|
33
|
+
'sm:max-w-md md:max-w-xl lg:max-w-2xl': config.maxWidth === '2xl',
|
|
34
|
+
'sm:max-w-md md:max-w-xl lg:max-w-3xl': config.maxWidth === '3xl',
|
|
35
|
+
'sm:max-w-md md:max-w-xl lg:max-w-3xl xl:max-w-4xl': config.maxWidth === '4xl',
|
|
36
|
+
'sm:max-w-md md:max-w-xl lg:max-w-3xl xl:max-w-5xl': config.maxWidth === '5xl',
|
|
37
|
+
'sm:max-w-md md:max-w-xl lg:max-w-3xl xl:max-w-5xl 2xl:max-w-6xl': config.maxWidth === '6xl',
|
|
38
|
+
'sm:max-w-md md:max-w-xl lg:max-w-3xl xl:max-w-5xl 2xl:max-w-7xl': config.maxWidth === '7xl',
|
|
39
|
+
},
|
|
40
|
+
)}
|
|
32
41
|
>
|
|
33
|
-
<
|
|
42
|
+
<div className={`im-slideover-content relative ${config.paddingClasses} ${config.panelClasses}`}>
|
|
34
43
|
{config.closeButton && (
|
|
35
44
|
<div className="absolute right-0 top-0 pr-3 pt-3">
|
|
36
45
|
<CloseButton onClick={modalContext.close} />
|
|
37
46
|
</div>
|
|
38
47
|
)}
|
|
39
48
|
{typeof children === 'function' ? children({ modalContext, config }) : children}
|
|
40
|
-
</
|
|
49
|
+
</div>
|
|
41
50
|
</TransitionChild>
|
|
42
51
|
</div>
|
|
43
52
|
</div>
|
package/src/helpers.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { except, only, rejectNullValues, waitFor, kebabCase } from './../../vue/src/helpers.js'
|
|
2
|
-
export { except, only, rejectNullValues, waitFor, kebabCase }
|
|
1
|
+
import { modalDOMHandler, except, only, rejectNullValues, waitFor, kebabCase } from './../../vue/src/helpers.js'
|
|
2
|
+
export { modalDOMHandler, except, only, rejectNullValues, waitFor, kebabCase }
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react'
|
|
2
|
+
import { createFocusTrap } from 'focus-trap'
|
|
3
|
+
|
|
4
|
+
export function useFocusTrap(closeExplicitly, onDeactivateCallback) {
|
|
5
|
+
const wrapperRef = useRef(null)
|
|
6
|
+
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (!wrapperRef.current) {
|
|
9
|
+
return
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const trap = createFocusTrap(wrapperRef.current, {
|
|
13
|
+
clickOutsideDeactivates: !closeExplicitly,
|
|
14
|
+
escapeDeactivates: !closeExplicitly,
|
|
15
|
+
onDeactivate: () => onDeactivateCallback?.(),
|
|
16
|
+
fallbackFocus: () => wrapperRef.current,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
trap.activate()
|
|
20
|
+
|
|
21
|
+
return () => trap.deactivate()
|
|
22
|
+
}, [])
|
|
23
|
+
|
|
24
|
+
return wrapperRef
|
|
25
|
+
}
|