code-snippet.vue 2.02 KB
<template>
  <div class="code-snippet">
    <div class="code-snippet--demo">
      <slot name="source"></slot>
    </div>
    <div class="code-snippet--desc">
      <slot name="desc"></slot>
      <span class="code-snippet--icon-code" @click="showCode = !showCode" title="查看代码">
        <img v-if="showCode" src="@/assets/images/icon/code-open.svg" />
        <img v-else src="@/assets/images/icon/code-close.svg" />
      </span>
    </div>
    <code-collapse>
      <div v-show="showCode" class="code-snippet--code">
        <slot name="code"></slot>
      </div>
    </code-collapse>
  </div>
</template>

<script>
import CodeCollapse from './code-collapse';

export default {
  components: { CodeCollapse },
  data() {
    return {
      showCode: false,
    };
  },
};
</script>
<style lang="scss">
.code-snippet {
  position: relative;
  box-sizing: border-box;
  width: 100%;
  margin: 0 0 16px;
  border-radius: 4px;
  transition: all 0.2s;
  border: 1px solid $border;
  background-color: inherit;
  text-align: left;
}
.code-snippet--demo {
  box-sizing: border-box;
  padding: 16px;
  color: inherit;
  border-bottom: 1px solid $border;
}
.code-snippet--desc {
  position: relative;
  box-sizing: border-box;
  width: 100%;
  padding: 0 16px;
  font-size: 14px;
  transition: background-color 0.4s;
  line-height: 1.5;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.code-snippet--icon-code {
  cursor: pointer;
  min-width: 18px;
  width: 18px;
  height: 18px;
  text-align: center;

  > img {
    transition: all 0.4s;
    user-select: none;
    max-width: 100%;
    width: 100%;
    vertical-align: baseline;
    box-shadow: none;
  }
}

.code-snippet--code {
  box-sizing: border-box;
  border-top: 1px solid $border;

  code {
    background-color: $background;
    font-family: Consolas, Menlo, Courier, monospace;
    border: none;
    display: block;
    font-size: 14px;
    padding: 16px;
    line-height: 1.5;
  }

  .hljs {
    padding: 0;
    margin: 0;

    code {
      margin: 0;
    }
  }
}
</style>