AppLeftSidebar.vue 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. <script setup lang="ts">
  2. import { ref } from "vue"
  3. const open = defineModel<boolean>("open", { required: true })
  4. const pages = ref([
  5. { id: "1", label: "Getting Started", icon: "i-lucide-book-open" },
  6. { id: "2", label: "Architecture", icon: "i-lucide-layers" },
  7. { id: "3", label: "API Reference", icon: "i-lucide-code" },
  8. { id: "4", label: "Changelog", icon: "i-lucide-history" },
  9. ])
  10. </script>
  11. <template>
  12. <USidebar
  13. v-model:open="open"
  14. collapsible="icon"
  15. :ui="{ header: 'border-b border-default' }"
  16. >
  17. <template #header="{ state }">
  18. <div class="flex items-center gap-2 px-2 py-1 min-w-0">
  19. <UButton
  20. icon="i-lucide-panels-top-left"
  21. color="neutral"
  22. variant="ghost"
  23. size="sm"
  24. @click="open = !open"
  25. />
  26. <span v-if="state !== 'collapsed'" class="font-semibold text-sm truncate">
  27. My Workspace
  28. </span>
  29. </div>
  30. </template>
  31. <!-- Navigation items -->
  32. <div class="flex flex-col gap-0.5 p-2">
  33. <UButton
  34. v-for="page in pages"
  35. :key="page.id"
  36. :icon="page.icon"
  37. :label="page.label"
  38. color="neutral"
  39. variant="ghost"
  40. size="sm"
  41. class="justify-start w-full"
  42. />
  43. </div>
  44. <template #footer="{ state }">
  45. <div class="p-2 border-t border-default">
  46. <UButton
  47. icon="i-lucide-plus"
  48. :label="state !== 'collapsed' ? 'New Page' : undefined"
  49. color="neutral"
  50. variant="soft"
  51. size="sm"
  52. class="w-full justify-start"
  53. />
  54. </div>
  55. </template>
  56. </USidebar>
  57. </template>