Section.vue 1.78 KB
<script setup>
/** 页面区块。页面 = PageHeader + N 个 Section,Section 不嵌套。 */

defineProps({
  /** 区块标题。不给就不渲染标题栏。 */
  title: { type: String, default: '' },
  /** 表格类内容自己带边框和内边距,这里就不要再加一层。 */
  padded: { type: Boolean, default: true },
})
</script>

<template>
  <section class="drama-section">
    <header
      v-if="title || $slots.actions"
      class="drama-section__header"
    >
      <h2 v-if="title">{{ title }}</h2>
      <div
        v-if="$slots.actions"
        class="drama-section__actions"
      >
        <slot name="actions" />
      </div>
    </header>
    <div :class="['drama-section__body', { 'is-padded': padded }]">
      <slot />
    </div>
  </section>
</template>

<style scoped>
.drama-section {
  background-color: var(--drama-color-surface);
  border: 1px solid var(--drama-color-border);
  border-radius: var(--drama-radius-lg);
  overflow: hidden;
}

/* 不带外边距:块与块之间的距离归页面容器(见 admin 的 `.vga-page`)。组件自己伸手管周围的间距,
   页面再叠一层 gap,两者就会互相加码。 */

.drama-section__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--drama-space-lg);
  padding: var(--drama-space-lg) var(--drama-space-xl);
  border-bottom: 1px solid var(--drama-color-border);
}

h2 {
  margin: 0;
  color: var(--drama-color-text);
  font-family: var(--drama-font-family-heading);
  font-size: var(--drama-font-size-lg);
  font-weight: var(--drama-font-weight-medium);
  line-height: var(--drama-line-height-tight);
}

.drama-section__actions {
  display: flex;
  align-items: center;
  gap: var(--drama-space-sm);
}

.drama-section__body.is-padded {
  padding: var(--drama-space-xl);
}
</style>