diff options
Diffstat (limited to 'components/Panel.vue')
| -rw-r--r-- | components/Panel.vue | 75 |
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 |
