Skip to content

Commit

Permalink
feat: add positioning options to FwbModal (#293)
Browse files Browse the repository at this point in the history
* fix: correct close button alignment in rtl mode

* feat: add positioning options to FwbModal

* docs: add position example for FwbModal

* fix: change position types to logical ones

* fix: annotate objects
  • Loading branch information
woodrunsdeep authored Aug 6, 2024
1 parent 0cc202f commit bce8477
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 8 deletions.
28 changes: 28 additions & 0 deletions docs/components/modal.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import FwbModalExample from './modal/examples/FwbModalExample.vue'
import FwbModalExampleSize from './modal/examples/FwbModalExampleSize.vue'
import FwbModalExampleEscapable from './modal/examples/FwbModalExampleEscapable.vue'
import FwbModalExamplePersistent from './modal/examples/FwbModalExamplePersistent.vue'
import FwbModalExamplePosition from './modal/examples/FwbModalExamplePosition.vue'
</script>
# Vue Modal - Flowbite

Expand Down Expand Up @@ -91,6 +92,33 @@ import { FwbModal } from 'flowbite-vue'
</script>
```

## Position

The `position` prop allows you to control the placement of the modal on the screen, taking into account RTL (Right-to-Left) mode. You can choose from the following options:

`top-start`, `top-center`, `top-end`, `center-start`, `center`, `center-end`, `bottom-start`, `bottom-center`, `bottom-end`

The default value is: `center`

<fwb-modal-example-position />
```vue
<template>
<fwb-modal position="top-start" />
<fwb-modal position="top-center" />
<fwb-modal position="top-end" />
<fwb-modal position="center-start" />
<fwb-modal position="center" />
<fwb-modal position="center-end" />
<fwb-modal position="bottom-start" />
<fwb-modal position="bottom-center" />
<fwb-modal position="bottom-end" />
</template>
<script setup>
import { FwbModal } from 'flowbite-vue'
</script>
```

## Escapable

The escapable property is true by default to improve user experience and accessibility.
Expand Down
5 changes: 4 additions & 1 deletion docs/components/modal/examples/FwbModalExample.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
:not-escapable="notEscapable"
:persistent="persistent"
:size="size"
:position="position"
@close="closeModal"
>
<template #header>
Expand Down Expand Up @@ -45,20 +46,22 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { FwbButton, FwbModal } from '../../../../src/index'
import { type ModalSize } from '../../../../src/components/FwbModal/types'
import { type ModalPosition, type ModalSize } from '../../../../src/components/FwbModal/types'
interface ModalProps {
size?: ModalSize,
notEscapable?: boolean,
persistent?: boolean,
triggerText?: string
position?: ModalPosition
}
withDefaults(defineProps<ModalProps>(), {
size: '2xl',
notEscapable: false,
persistent: false,
triggerText: 'Open Modal',
position: 'center',
})
const isShowModal = ref(false)
Expand Down
62 changes: 62 additions & 0 deletions docs/components/modal/examples/FwbModalExamplePosition.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<div class="flex flex-wrap justify-start gap-2 vp-raw">
<span>
<fwb-modal-example
position="top-start"
trigger-text="Top Start"
/>
</span>
<span>
<fwb-modal-example
position="top-center"
trigger-text="Top Center"
/>
</span>
<span>
<fwb-modal-example
position="top-end"
trigger-text="Top End"
/>
</span>
<span>
<fwb-modal-example
position="center-start"
trigger-text="Center Start"
/>
</span>
<span>
<fwb-modal-example
position="center"
trigger-text="Center"
/>
</span>
<span>
<fwb-modal-example
position="center-end"
trigger-text="Center End"
/>
</span>
<span>
<fwb-modal-example
position="bottom-start"
trigger-text="Bottom Start"
/>
</span>
<span>
<fwb-modal-example
position="bottom-center"
trigger-text="Bottom Center"
/>
</span>
<span>
<fwb-modal-example
position="bottom-end"
trigger-text="Bottom End"
/>
</span>
</div>
</template>

<script setup>
import FwbModalExample from './FwbModalExample.vue'
</script>
26 changes: 20 additions & 6 deletions src/components/FwbModal/FwbModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
<div class="bg-gray-900 bg-opacity-50 dark:bg-opacity-80 fixed inset-0 z-40" />
<div
ref="modalRef"
class="overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 w-full md:inset-0 h-modal md:h-full justify-center items-center flex"
class="overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 w-full md:inset-0 h-modal md:h-full grid"
tabindex="0"
@click.self="clickOutside"
@keyup.esc="closeWithEsc"
>
<div
:class="`${modalSizeClasses[size]}`"
class="relative p-4 w-full h-full"
:class="`${modalSizeClasses[size]} ${modalPositionClasses[position]}`"
class="relative p-4 w-full"
>
<!-- Modal content -->
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
Expand All @@ -23,7 +23,7 @@
<button
v-if="!persistent"
aria-label="close"
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white"
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ms-auto inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white"
type="button"
@click="closeModal"
>
Expand Down Expand Up @@ -63,22 +63,24 @@

<script lang="ts" setup>
import { onMounted, ref, type Ref } from 'vue'
import type { ModalSize } from './types'
import type { ModalPosition, ModalSize } from './types'
interface ModalProps {
notEscapable?: boolean,
persistent?: boolean
size?: ModalSize,
position?: ModalPosition
}
const props = withDefaults(defineProps<ModalProps>(), {
notEscapable: false,
persistent: false,
size: '2xl',
position: 'center',
})
const emit = defineEmits(['close', 'click:outside'])
const modalSizeClasses = {
const modalSizeClasses: Record<ModalSize, string> = {
xs: 'max-w-xs',
sm: 'max-w-sm',
md: 'max-w-md',
Expand All @@ -92,6 +94,18 @@ const modalSizeClasses = {
'7xl': 'max-w-7xl',
}
const modalPositionClasses: Record<ModalPosition, string> = {
'top-start': 'self-start justify-self-start',
'top-center': 'self-start justify-self-center',
'top-end': 'self-start justify-self-end',
'center-start': 'self-center justify-self-start',
center: 'self-center justify-self-center',
'center-end': 'self-center justify-self-end',
'bottom-start': 'self-end justify-self-start',
'bottom-center': 'self-end justify-self-center',
'bottom-end': 'self-end justify-self-end',
}
function closeModal () {
emit('close')
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/FwbModal/types.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export type ModalPosition = 'bottom-left' | 'bottom-right' | 'bottom-center' | 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right';
export type ModalPosition = 'bottom-start' | 'bottom-end' | 'bottom-center' | 'top-start' | 'top-center' | 'top-end' | 'center-start' | 'center' | 'center-end';
export type ModalSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl';

0 comments on commit bce8477

Please sign in to comment.