Skip to content

Commit d15e705

Browse files
committed
feat(CModal): the container and teleport properties to enable appending the modal to a specific element
1 parent 7626e30 commit d15e705

File tree

2 files changed

+64
-32
lines changed

2 files changed

+64
-32
lines changed

packages/coreui-vue/src/components/modal/CModal.ts

+49-19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
defineComponent,
33
h,
4+
PropType,
45
provide,
56
ref,
67
RendererElement,
@@ -11,6 +12,7 @@ import {
1112
} from 'vue'
1213

1314
import { CBackdrop } from '../backdrop/CBackdrop'
15+
import { CConditionalTeleport } from '../conditional-teleport'
1416

1517
import { executeAfterTransition } from '../../utils/transition'
1618

@@ -47,14 +49,23 @@ const CModal = defineComponent({
4749
return false
4850
},
4951
},
52+
/**
53+
* Appends the vue popover to a specific element. You can pass an HTML element or function that returns a single element. By default `document.body`.
54+
*
55+
* @since 5.3.0
56+
*/
57+
container: {
58+
type: [Object, String] as PropType<HTMLElement | (() => HTMLElement) | string>,
59+
default: 'body',
60+
},
5061
/**
5162
* A string of all className you want applied to the modal content component.
5263
*/
5364
contentClassName: String,
5465
/**
5566
* Puts the focus on the modal when shown.
5667
*
57-
* @since v5.0.0
68+
* @since 5.0.0
5869
*/
5970
focus: {
6071
type: Boolean,
@@ -99,6 +110,15 @@ const CModal = defineComponent({
99110
return ['sm', 'lg', 'xl'].includes(value)
100111
},
101112
},
113+
/**
114+
* Generates modal using Teleport.
115+
*
116+
* @since 5.3.0
117+
*/
118+
teleport: {
119+
type: Boolean,
120+
default: false,
121+
},
102122
/**
103123
* Remove animation to create modal that simply appear rather than fade in to view.
104124
*/
@@ -264,27 +284,37 @@ const CModal = defineComponent({
264284
),
265285
)
266286

267-
return () => [
287+
return () =>
268288
h(
269-
Transition,
289+
CConditionalTeleport,
270290
{
271-
css: false,
272-
onEnter: (el, done) => handleEnter(el, done),
273-
onAfterEnter: () => handleAfterEnter(),
274-
onLeave: (el, done) => handleLeave(el, done),
275-
onAfterLeave: (el) => handleAfterLeave(el),
291+
container: props.container,
292+
teleport: props.teleport,
276293
},
277-
() =>
278-
props.unmountOnClose
279-
? visible.value && modal()
280-
: withDirectives(modal(), [[vShow, visible.value]]),
281-
),
282-
props.backdrop &&
283-
h(CBackdrop, {
284-
class: 'modal-backdrop',
285-
visible: visible.value,
286-
}),
287-
]
294+
{
295+
default: () => [
296+
h(
297+
Transition,
298+
{
299+
css: false,
300+
onEnter: (el, done) => handleEnter(el, done),
301+
onAfterEnter: () => handleAfterEnter(),
302+
onLeave: (el, done) => handleLeave(el, done),
303+
onAfterLeave: (el) => handleAfterLeave(el),
304+
},
305+
() =>
306+
props.unmountOnClose
307+
? visible.value && modal()
308+
: withDirectives(modal(), [[vShow, visible.value]]),
309+
),
310+
props.backdrop &&
311+
h(CBackdrop, {
312+
class: 'modal-backdrop',
313+
visible: visible.value,
314+
}),
315+
],
316+
},
317+
)
288318
},
289319
})
290320

packages/docs/api/modal/CModal.api.md

+15-13
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,21 @@ import CModal from '@coreui/vue/src/components/modal/CModal'
88

99
#### Props
1010

11-
| Prop name | Description | Type | Values | Default |
12-
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | --------------- | -------------------------------------------------- | ------- |
13-
| **alignment** | Align the modal in the center or top of the screen. | string | `'top'`, `'center'` | 'top' |
14-
| **backdrop** | Apply a backdrop on body while offcanvas is open. | boolean\|string | `boolean \| 'static'` | true |
15-
| **content-class-name** | A string of all className you want applied to the modal content component. | string | - | - |
16-
| **focus** <br><div class="badge bg-primary">v5.0.0+</div> | Puts the focus on the modal when shown. | boolean | - | true |
17-
| **fullscreen** | Set modal to covers the entire user viewport | boolean\|string | `boolean`, `'sm'`, `'md'`, `'lg'`, `'xl'`, `'xxl'` | - |
18-
| **keyboard** | Closes the modal when escape key is pressed. | boolean | - | true |
19-
| **scrollable** | Create a scrollable modal that allows scrolling the modal body. | boolean | - | - |
20-
| **size** | Size the component small, large, or extra large. | string | `'sm'`, `'lg'`, `'xl'` | - |
21-
| **transition** | Remove animation to create modal that simply appear rather than fade in to view. | boolean | - | true |
22-
| **unmount-on-close** | By default the component is unmounted after close animation, if you want to keep the component mounted set this property to false. | boolean | - | true |
23-
| **visible** | Toggle the visibility of alert component. | boolean | - | - |
11+
| Prop name | Description | Type | Values | Default |
12+
| ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -------------------------------------------------- | ------- |
13+
| **alignment** | Align the modal in the center or top of the screen. | string | `'top'`, `'center'` | 'top' |
14+
| **backdrop** | Apply a backdrop on body while offcanvas is open. | boolean\|string | `boolean \| 'static'` | true |
15+
| **container** <br><div class="badge bg-primary">5.3.0+</div> | Appends the vue popover to a specific element. You can pass an HTML element or function that returns a single element. By default `document.body`. | HTMLElement \| (() => HTMLElement) \| string | - | 'body' |
16+
| **content-class-name** | A string of all className you want applied to the modal content component. | string | - | - |
17+
| **focus** <br><div class="badge bg-primary">5.0.0+</div> | Puts the focus on the modal when shown. | boolean | - | true |
18+
| **fullscreen** | Set modal to covers the entire user viewport | boolean\|string | `boolean`, `'sm'`, `'md'`, `'lg'`, `'xl'`, `'xxl'` | - |
19+
| **keyboard** | Closes the modal when escape key is pressed. | boolean | - | true |
20+
| **scrollable** | Create a scrollable modal that allows scrolling the modal body. | boolean | - | - |
21+
| **size** | Size the component small, large, or extra large. | string | `'sm'`, `'lg'`, `'xl'` | - |
22+
| **teleport** <br><div class="badge bg-primary">5.3.0+</div> | Generates modal using Teleport. | boolean | - | false |
23+
| **transition** | Remove animation to create modal that simply appear rather than fade in to view. | boolean | - | true |
24+
| **unmount-on-close** | By default the component is unmounted after close animation, if you want to keep the component mounted set this property to false. | boolean | - | true |
25+
| **visible** | Toggle the visibility of alert component. | boolean | - | - |
2426

2527
#### Events
2628

0 commit comments

Comments
 (0)