aboutsummaryrefslogtreecommitdiffstats
path: root/components/Panel.vue
diff options
context:
space:
mode:
authorLeonardo Bishop <me@leonardobishop.com>2025-01-24 01:53:42 +0000
committerLeonardo Bishop <me@leonardobishop.com>2025-01-24 01:53:42 +0000
commited3faf85e6a6e8083128ec68894533738c762b04 (patch)
treee8bb6ddc4b0d470c024667ab3ccacd3e2f85cf50 /components/Panel.vue
parent0248517c6845a6c755d40c89d3d769ce7d60bd03 (diff)
Add /live
Diffstat (limited to 'components/Panel.vue')
-rw-r--r--components/Panel.vue75
1 files changed, 53 insertions, 22 deletions
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