feat: Implement mobile navbar

This commit is contained in:
Jesse Wierzbinski 2024-12-09 16:52:04 +01:00
parent 4ba3ed3d37
commit 0987df7783
No known key found for this signature in database
17 changed files with 310 additions and 25 deletions

View file

@ -0,0 +1,19 @@
<script lang="ts" setup>
import { useForwardPropsEmits } from "radix-vue";
import type { DrawerRootEmits, DrawerRootProps } from "vaul-vue";
import { DrawerRoot } from "vaul-vue";
const props = withDefaults(defineProps<DrawerRootProps>(), {
shouldScaleBackground: true,
});
const emits = defineEmits<DrawerRootEmits>();
const forwarded = useForwardPropsEmits(props, emits);
</script>
<template>
<DrawerRoot v-bind="forwarded">
<slot />
</DrawerRoot>
</template>

View file

@ -0,0 +1,30 @@
<script lang="ts" setup>
import { cn } from "@/lib/utils";
import type { DialogContentEmits, DialogContentProps } from "radix-vue";
import { useForwardPropsEmits } from "radix-vue";
import { DrawerContent, DrawerPortal } from "vaul-vue";
import type { HtmlHTMLAttributes } from "vue";
import DrawerOverlay from "./DrawerOverlay.vue";
const props = defineProps<
DialogContentProps & { class?: HtmlHTMLAttributes["class"] }
>();
const emits = defineEmits<DialogContentEmits>();
const forwarded = useForwardPropsEmits(props, emits);
</script>
<template>
<DrawerPortal>
<DrawerOverlay />
<DrawerContent
v-bind="forwarded" :class="cn(
'fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background',
props.class,
)"
>
<div class="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
<slot />
</DrawerContent>
</DrawerPortal>
</template>

View file

@ -0,0 +1,22 @@
<script lang="ts" setup>
import { cn } from "@/lib/utils";
import type { DrawerDescriptionProps } from "vaul-vue";
import { DrawerDescription } from "vaul-vue";
import { type HtmlHTMLAttributes, computed } from "vue";
const props = defineProps<
DrawerDescriptionProps & { class?: HtmlHTMLAttributes["class"] }
>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;
return delegated;
});
</script>
<template>
<DrawerDescription v-bind="delegatedProps" :class="cn('text-sm text-muted-foreground', props.class)">
<slot />
</DrawerDescription>
</template>

View file

@ -0,0 +1,14 @@
<script lang="ts" setup>
import { cn } from "@/lib/utils";
import type { HtmlHTMLAttributes } from "vue";
const props = defineProps<{
class?: HtmlHTMLAttributes["class"];
}>();
</script>
<template>
<div :class="cn('mt-auto flex flex-col gap-2 p-4', props.class)">
<slot />
</div>
</template>

View file

@ -0,0 +1,14 @@
<script lang="ts" setup>
import { cn } from "@/lib/utils";
import type { HtmlHTMLAttributes } from "vue";
const props = defineProps<{
class?: HtmlHTMLAttributes["class"];
}>();
</script>
<template>
<div :class="cn('grid gap-1.5 p-4 text-center sm:text-left', props.class)">
<slot />
</div>
</template>

View file

@ -0,0 +1,20 @@
<script lang="ts" setup>
import { cn } from "@/lib/utils";
import type { DialogOverlayProps } from "radix-vue";
import { DrawerOverlay } from "vaul-vue";
import { type HtmlHTMLAttributes, computed } from "vue";
const props = defineProps<
DialogOverlayProps & { class?: HtmlHTMLAttributes["class"] }
>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;
return delegated;
});
</script>
<template>
<DrawerOverlay v-bind="delegatedProps" :class="cn('fixed inset-0 z-50 bg-black/80', props.class)" />
</template>

View file

@ -0,0 +1,22 @@
<script lang="ts" setup>
import { cn } from "@/lib/utils";
import type { DrawerTitleProps } from "vaul-vue";
import { DrawerTitle } from "vaul-vue";
import { type HtmlHTMLAttributes, computed } from "vue";
const props = defineProps<
DrawerTitleProps & { class?: HtmlHTMLAttributes["class"] }
>();
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;
return delegated;
});
</script>
<template>
<DrawerTitle v-bind="delegatedProps" :class="cn('text-lg font-semibold leading-none tracking-tight', props.class)">
<slot />
</DrawerTitle>
</template>

View file

@ -0,0 +1,8 @@
export { default as Drawer } from "./Drawer.vue";
export { default as DrawerContent } from "./DrawerContent.vue";
export { default as DrawerDescription } from "./DrawerDescription.vue";
export { default as DrawerFooter } from "./DrawerFooter.vue";
export { default as DrawerHeader } from "./DrawerHeader.vue";
export { default as DrawerOverlay } from "./DrawerOverlay.vue";
export { default as DrawerTitle } from "./DrawerTitle.vue";
export { DrawerClose, DrawerPortal, DrawerTrigger } from "vaul-vue";