-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
338 additions
and
336 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<template> | ||
<template v-if="isLink"> | ||
<a | ||
v-if="external" | ||
:href="href" | ||
:class="[buttonBase, buttonSize, buttonColor]" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
<Icon v-if="icon" :icon="icon" :class="[iconBase, iconSize, iconColor]" /> | ||
|
||
<slot>{{ label }}</slot> | ||
</a> | ||
|
||
<Link v-else :href="href" :class="[buttonBase, buttonSize, buttonColor]"> | ||
<Icon v-if="icon" :icon="icon" :class="[iconBase, iconSize, iconColor]" /> | ||
|
||
<slot>{{ label }}</slot> | ||
</Link> | ||
</template> | ||
|
||
<button v-else :type="type" :class="[buttonBase, buttonSize, buttonColor]"> | ||
<Icon v-if="icon" :icon="icon" :class="[iconBase, iconSize, iconColor]" /> | ||
|
||
<slot>{{ label }}</slot> | ||
</button> | ||
</template> | ||
|
||
<script setup> | ||
import { computed } from 'vue'; | ||
import { Link } from '@inertiajs/vue3'; | ||
import Icon from '@/Components/Icon.vue'; | ||
const props = defineProps({ | ||
href: { | ||
type: String, | ||
default: null, | ||
}, | ||
type: { | ||
type: String, | ||
default: 'button', | ||
}, | ||
icon: { | ||
type: [String, Function], | ||
default: null, | ||
}, | ||
external: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
size: { | ||
type: String, | ||
default: 'md', | ||
validator: (value) => ['sm', 'md', 'lg'].includes(value), | ||
}, | ||
label: { | ||
type: String, | ||
default: null, | ||
}, | ||
primary: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
}); | ||
const isLink = computed(() => props.href !== null); | ||
const buttonBase = `flex items-center justify-center ring-inset font-medium rounded-full whitespace-nowrap `; | ||
const iconBase = 'shrink-0'; | ||
const buttonSize = computed( | ||
() => | ||
({ | ||
sm: 'gap-2 px-4 py-2 text-sm shadow-sm', | ||
md: 'gap-2 px-4 py-2 text-base shadow', | ||
lg: 'gap-3 px-4 py-2 text-lg shadow-lg', | ||
}[props.size]) | ||
); | ||
const buttonColor = computed(() => | ||
props.primary | ||
? 'bg-primary-800 text-white ring-primary-800 hover:bg-primary-700 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-700 focus:outline-none' | ||
: 'ring-1 bg-white text-gray-700 ring-gray-300 hover:bg-gray-50' | ||
); | ||
const iconSize = computed( | ||
() => | ||
({ | ||
sm: 'h-4 w-4', | ||
md: 'h-5 w-5', | ||
lg: 'h-5 w-5', | ||
}[props.size]) | ||
); | ||
const iconColor = computed( | ||
() => | ||
({ | ||
white: 'text-gray-500', | ||
}[props.color]) | ||
); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<template> | ||
<slot name="trigger" :open="open" :isOpen="isOpen"> | ||
<Button color="white" @click="open"> | ||
<span>Open Modal</span> | ||
</Button> | ||
</slot> | ||
|
||
<TransitionRoot as="template" :show="isOpen"> | ||
<Dialog class="relative z-10" @close="overlayDismissable && close()"> | ||
<TransitionChild | ||
as="template" | ||
enter="ease-out duration-300" | ||
enter-from="opacity-0" | ||
enter-to="opacity-100" | ||
leave="ease-in duration-200" | ||
leave-from="opacity-100" | ||
leave-to="opacity-0" | ||
> | ||
<div class="fixed inset-0 transition-opacity bg-black bg-opacity-25" /> | ||
</TransitionChild> | ||
|
||
<div class="fixed inset-0 z-10"> | ||
<div class="flex items-start justify-center min-h-full p-4 text-center sm:items-center sm:p-0"> | ||
<TransitionChild | ||
as="template" | ||
enter="ease-out duration-300" | ||
enter-from="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" | ||
enter-to="opacity-100 translate-y-0 sm:scale-100" | ||
leave="ease-in duration-200" | ||
leave-from="opacity-100 translate-y-0 sm:scale-100" | ||
leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" | ||
> | ||
<DialogPanel class="w-full h-screen sm:py-8 sm:max-w-lg"> | ||
<div | ||
class="relative flex flex-col w-full max-h-full overflow-hidden text-left transition-all transform bg-white rounded-lg shadow-xl" | ||
> | ||
<div class="sticky top-0 px-4 py-5 sm:px-6"> | ||
<button | ||
v-if="dismissable" | ||
type="button" | ||
class="absolute text-gray-400 rounded-md top-4 right-4 hover:text-gray-500 focus:outline-none focus:text-gray-900" | ||
@click="close" | ||
> | ||
<span class="sr-only">Close</span> | ||
<XMarkIcon class="w-6 h-6" aria-hidden="true" /> | ||
</button> | ||
|
||
<DialogTitle | ||
v-if="$slots.title" | ||
as="h3" | ||
class="text-base font-semibold text-gray-900 sm:text-lg" | ||
> | ||
<slot name="title" /> | ||
</DialogTitle> | ||
</div> | ||
|
||
<div class="flex-1 px-4 py-5 overflow-y-auto sm:px-6"> | ||
<slot /> | ||
</div> | ||
|
||
<div | ||
v-if="$slots.footer" | ||
class="flex flex-col-reverse justify-end gap-4 px-4 py-5 sm:flex-row sm:px-6 shrink-0" | ||
> | ||
<slot name="footer" /> | ||
</div> | ||
</div> | ||
</DialogPanel> | ||
</TransitionChild> | ||
</div> | ||
</div> | ||
</Dialog> | ||
</TransitionRoot> | ||
</template> | ||
|
||
<script setup> | ||
import { ref } from 'vue'; | ||
import { Dialog, DialogPanel, DialogTitle, TransitionChild, TransitionRoot } from '@headlessui/vue'; | ||
import { XMarkIcon } from '@heroicons/vue/24/solid'; | ||
import Button from '@/Components/Button.vue'; | ||
const isOpen = ref(false); | ||
const props = defineProps({ | ||
dismissable: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
overlayDismissable: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
}); | ||
const open = () => { | ||
isOpen.value = true; | ||
}; | ||
const close = () => { | ||
isOpen.value = false; | ||
}; | ||
</script> |
Oops, something went wrong.