Skip to content

Commit f73e6bc

Browse files
committed
refactor(NcModal): use Typescript for props and emit definition
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 7bde5a8 commit f73e6bc

1 file changed

Lines changed: 75 additions & 108 deletions

File tree

src/components/NcModal/NcModal.vue

Lines changed: 75 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,6 @@ export default {
227227

228228
<!-- Actions menu -->
229229
<NcActions class="header-actions" :inline="inlineActions">
230-
<!-- @slot Actions to show (one or more NcAction* components) -->
231230
<slot name="actions" />
232231
</NcActions>
233232

@@ -276,7 +275,6 @@ export default {
276275
<!-- Content -->
277276
<div :id="'modal-description-' + modalId" class="modal-container">
278277
<div class="modal-container__content">
279-
<!-- @slot Modal content to render -->
280278
<slot />
281279
</div>
282280
<!-- Close modal -->
@@ -317,8 +315,8 @@ export default {
317315

318316
<script setup lang="ts">
319317
import type { UseSwipeDirection } from '@vueuse/core'
320-
import type { FocusTargetValueOrFalse, FocusTrap } from 'focus-trap'
321-
import type { PropType } from 'vue'
318+
import type { FocusTargetValueOrFalse, FocusTrap, Options as FocusTrapOptions } from 'focus-trap'
319+
import type { Slot } from 'vue'
322320
323321
import { mdiChevronLeft, mdiChevronRight, mdiClose, mdiPause, mdiPlay } from '@mdi/js'
324322
import { useIntervalFn, useSwipe } from '@vueuse/core'
@@ -333,199 +331,171 @@ import { createElementId } from '../../utils/createElementId.ts'
333331
import { getTrapStack } from '../../utils/focusTrap.ts'
334332
import { isRtl } from '../../utils/rtl.ts'
335333
336-
const props = defineProps({
334+
const props = withDefaults(defineProps<{
337335
/**
338336
* Name to be shown with the modal
339337
*/
340-
name: {
341-
type: String,
342-
default: '',
343-
},
338+
name?: string
344339
345340
/**
346341
* Declare if a previous slide is available
347342
*/
348-
hasPrevious: {
349-
type: Boolean,
350-
default: false,
351-
},
343+
hasPrevious?: boolean
352344
353345
/**
354346
* Declare if a next slide is available
355347
*/
356-
hasNext: {
357-
type: Boolean,
358-
default: false,
359-
},
348+
hasNext?: boolean
360349
361350
/**
362351
* Declare if hiding the modal should be animated
363352
*/
364-
outTransition: {
365-
type: Boolean,
366-
default: false,
367-
},
353+
outTransition?: boolean
368354
369355
/**
370356
* Declare if the slideshow functionality should be enabled
371357
*/
372-
enableSlideshow: {
373-
type: Boolean,
374-
default: false,
375-
},
358+
enableSlideshow?: boolean
376359
377360
/**
378361
* Declare the slide interval
379362
*/
380-
slideshowDelay: {
381-
type: Number,
382-
default: 5000,
383-
},
363+
slideshowDelay?: number
384364
385365
/**
386366
* Allow to pause an ongoing slideshow
387367
*/
388-
slideshowPaused: {
389-
type: Boolean,
390-
default: false,
391-
},
368+
slideshowPaused?: boolean
392369
393370
/**
394371
* Disable swipe between slides
395372
*/
396-
disableSwipe: {
397-
type: Boolean,
398-
default: false,
399-
},
373+
disableSwipe?: boolean
400374
401375
/**
402376
* Enable spread navigation
403377
*/
404-
spreadNavigation: {
405-
type: Boolean,
406-
default: false,
407-
},
378+
spreadNavigation?: boolean
408379
409380
/**
410381
* Defines the modal size.
411-
* Default is 'normal'.
412-
* Available are 'small', 'normal', 'large' and 'full'.
413382
* All sizes except 'small' change automatically to full-screen on mobile.
414383
*/
415-
size: {
416-
type: String as PropType<'small' | 'normal' | 'large' | 'full'>,
417-
default: 'normal',
418-
validator: (size: string) => {
419-
return ['small', 'normal', 'large', 'full'].includes(size)
420-
},
421-
},
384+
size?: 'small' | 'normal' | 'large' | 'full'
422385
423386
/**
424387
* Do not show the close button for the dialog.
425-
*
426-
* @default false
427388
*/
428-
noClose: {
429-
type: Boolean,
430-
default: false,
431-
},
389+
noClose?: boolean
432390
433391
/**
434392
* Close the modal if the user clicked outside the modal
435393
* Only relevant if `noClose` is not set.
436394
*/
437-
closeOnClickOutside: {
438-
type: Boolean,
439-
default: false,
440-
},
395+
closeOnClickOutside?: boolean
441396
442397
/**
443398
* Makes the modal backdrop opaque if true
444399
* Will be overwritten if some buttons are shown outside
445400
*/
446-
dark: {
447-
type: Boolean,
448-
default: false,
449-
},
401+
dark?: boolean
450402
451403
/**
452404
* Set light backdrop. Makes the modal header appear light.
453405
*/
454-
lightBackdrop: {
455-
type: Boolean,
456-
default: false,
457-
},
406+
lightBackdrop?: boolean
458407
459408
/**
460409
* Selector for the modal container, pass `null` to prevent automatic container mounting
461410
*/
462-
container: {
463-
type: [String, null],
464-
default: 'body',
465-
},
411+
container?: string | null
466412
467413
/**
468414
* Pass in `true` if you want the modal 'close' button to be displayed
469415
* outside the modal boundaries, in the top right corner of the window.
470416
*
471-
* @default false
472417
* @since 8.25.0
473418
*/
474-
closeButtonOutside: {
475-
type: Boolean,
476-
default: false,
477-
},
419+
closeButtonOutside?: boolean
478420
479421
/**
480422
* Additional elements to add to the focus trap
481423
*/
482-
additionalTrapElements: {
483-
type: Array as PropType<(string | HTMLElement)[]>,
484-
default: () => [],
485-
},
424+
additionalTrapElements?: (string | HTMLElement)[]
486425
487426
/**
488427
* Display x items inline
489428
*
490-
* @see Actions component usage
429+
* @see NcActions component usage
491430
*/
492-
inlineActions: {
493-
type: Number,
494-
default: 0,
495-
},
431+
inlineActions?: number
496432
497433
/**
498434
* The current open property of the modal
499435
*/
500-
show: {
501-
type: Boolean as PropType<boolean | undefined>,
502-
default: undefined,
503-
},
436+
show?: boolean | undefined
504437
505438
/**
506439
* Id of the element that labels the dialog (the name)
507440
* Not needed if the `name` prop is set, but if no name is set you need to provide the ID of an element to label the dialog for accessibility.
508441
*/
509-
labelId: {
510-
type: String,
511-
default: '',
512-
},
442+
labelId?: string
513443
514444
/**
515445
* Set element to return focus to after focus trap deactivation
516446
*/
517-
setReturnFocus: {
518-
default: undefined,
519-
type: [Boolean, HTMLElement, SVGElement, String] as PropType<FocusTargetValueOrFalse>,
520-
},
447+
setReturnFocus?: FocusTargetValueOrFalse
448+
}>(), {
449+
additionalTrapElements: () => [],
450+
container: 'body',
451+
inlineActions: 0,
452+
labelId: '',
453+
slideshowDelay: 5000,
454+
size: 'normal',
455+
name: '',
456+
show: undefined,
457+
setReturnFocus: undefined,
521458
})
522459
523-
const emit = defineEmits([
524-
'previous',
525-
'next',
526-
'close',
527-
'update:show',
528-
])
460+
const emit = defineEmits<{
461+
/**
462+
* Trigger showing the next slide.
463+
*
464+
* @param payload - The event that triggered showing the next slide
465+
*/
466+
next: [payload?: Event]
467+
468+
/**
469+
* Trigger showing the previous slide.
470+
*
471+
* @param payload - The event that triggered showing the previous slide
472+
*/
473+
previous: [payload?: Event]
474+
475+
/**
476+
* Emitted when the closing animation is finished
477+
*
478+
* @param payload - The event that triggered the close
479+
*/
480+
close: [payload?: Event]
481+
482+
/**
483+
* @param payload - The new show-state
484+
*/
485+
'update:show': [payload: boolean]
486+
}>()
487+
488+
defineSlots<{
489+
/**
490+
* Actions to show (one or more NcAction* components)
491+
*/
492+
actions?: Slot
493+
494+
/**
495+
* The modal content to show.
496+
*/
497+
default?: Slot
498+
}>()
529499
530500
const modalId = createElementId()
531501
const maskElement = useTemplateRef<HTMLDivElement>('mask')
@@ -676,9 +646,6 @@ function close(event?: Event) {
676646
677647
// delay closing for animation
678648
setTimeout(() => {
679-
/**
680-
* Emitted when the closing animation is finished
681-
*/
682649
emit('close', event)
683650
}, 300)
684651
}
@@ -708,7 +675,7 @@ async function useFocusTrap() {
708675
// wait until all children are mounted and available in the DOM before focusTrap can be added
709676
await nextTick()
710677
711-
const options = {
678+
const options: FocusTrapOptions = {
712679
allowOutsideClick: true,
713680
fallbackFocus: maskElement.value!,
714681
trapStack: getTrapStack(),

0 commit comments

Comments
 (0)