From ed3faf85e6a6e8083128ec68894533738c762b04 Mon Sep 17 00:00:00 2001
From: Leonardo Bishop <me@leonardobishop.com>
Date: Fri, 24 Jan 2025 01:53:42 +0000
Subject: Add /live

---
 components/Panel.vue | 75 +++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 53 insertions(+), 22 deletions(-)

(limited to 'components/Panel.vue')

diff --git a/components/Panel.vue b/components/Panel.vue
index 285db57..1f2d22e 100644
--- a/components/Panel.vue
+++ b/components/Panel.vue
@@ -1,10 +1,10 @@
 <script setup lang="ts">
 import { ArrowRight } from 'lucide-vue-next';
-import { defineProps, type PropType } from 'vue';
+import { defineProps, type FunctionalComponent, type PropType } from 'vue';
 
 defineProps({
   kind: {
-    type: String as PropType<"normal" | "error" | "success">,
+    type: String as PropType<"normal" | "error" | "success" | "emphasis">,
     required: false,
     default: 'normal',
   },
@@ -18,46 +18,66 @@ defineProps({
     required: false,
     default: () => [],
   },
+  icon: {
+    type: Object as PropType<FunctionalComponent>,
+    default: null
+  }
 });
 </script>
 <template>
   <div class="card" :class="kind">
-    <div v-if="title" class="card-title-container">
-      <span v-for="(breadcrumb, index) in breadcrumbs" class="breadcrumb" :key="index">
-        <NuxtLink :to="breadcrumb.to">{{ breadcrumb.text }}</NuxtLink>
-        <ArrowRight />
-      </span>
-      <span class="card-title"> {{ title }} </span>
+    <div v-if="title" class="card-header">
+      <div class="header-left">
+        <component :is="icon" v-if="icon" />
+        <div class="card-title-container">
+          <span v-for="(breadcrumb, index) in breadcrumbs" class="breadcrumb" :key="index">
+            <NuxtLink :to="breadcrumb.to">{{ breadcrumb.text }}</NuxtLink>
+            <ArrowRight v-if="index != breadcrumbs.length - 1" />
+          </span>
+          <span class="card-title"> {{ title }} </span>
+        </div>
+      </div>
+      
+      <slot name="actions" />
     </div>
     <slot />
   </div>
 </template>
 
 <style>
-.card {
+div.card {
   padding: 1rem; 
   border-radius: 0.5rem; 
 }
 
-.card-title-container {
-  line-height: 1;
-  background-color: var(--color-background-muted);
+div.card-header {
   padding: 1rem 1rem;
-  margin: -1rem -1rem 1rem -1rem;
+  margin: -1rem -1rem 0 -1rem;
   border-top-left-radius: 0.5rem;
   border-top-right-radius: 0.5rem;;
-  border-bottom: 1px solid var(--color-border);
   display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+div.header-left {
+  display: flex;
+  line-height: 1;
   align-items: center;
   gap: 0.5rem;
 }
 
-.card-title {
+div.header-left > svg {
+  width: 1.3rem;
+  height: 1.3rem;
+}
+
+span.card-title {
   font-size: 1.5rem;
   font-weight: 700;
 }
 
-.breadcrumb {
+span.breadcrumb {
   font-size: 1.2rem;
   font-weight: 600;
   display: flex;
@@ -65,32 +85,43 @@ defineProps({
   gap: 0.5rem;
 }
 
-.breadcrumb > svg {
+span.breadcrumb > svg {
   width: 1.2rem;
   height: 1.2rem;
   color: var(--color-text-muted);
 }
 
-.breadcrumb > a {
+span.breadcrumb > a {
   color: var(--color-text-muted);
 }
 
-.breadcrumb > a:hover {
+span.breadcrumb > a:hover {
   color: var(--color-primary);
 }
 
-.normal {
+div.normal {
   background-color: white;
   border: 0.1rem solid var(--color-border);
 }
 
-.error {
+div.normal .card-header {
+  background-color: var(--color-background-muted);
+  border-bottom: 1px solid var(--color-border);
+  margin: -1rem -1rem 1rem -1rem;
+}
+
+div.error {
   background-color: var(--color-error-light);
   border: 0.1rem solid var(--color-border-error-light);
 }
 
-.success {
+div.success {
   background-color: var(--color-success-light);
   border: 0.1rem solid var(--color-border-success-light);
 }
+
+div.emphasis {
+  background-color: var(--color-background-primary);
+  border: 0.1rem solid var(--color-border-primary-light);
+}
 </style>
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2

