All files / src/components/Skeleton/variants Article.vue

100% Statements 33/33
100% Branches 24/24
100% Functions 11/11
100% Lines 28/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97                          25x   25x   25x 25x 25x     25x   25x 25x 25x     25x 25x 25x     25x 25x     25x 25x 25x       179x 133x 87x         24x               25x           44x 45x     46x   172x 173x 179x                                              
<script setup lang="ts">
import { computed } from "vue";
import Skeleton from "../Skeleton.vue";
import type { SkeletonBaseProps } from "../types";
 
type ArticleOptions = {
  paragraphs?: number;
  linesPerParagraph?: number;
  titleWidth?: number | string;
  paragraphGap?: number | string;
  lineGap?: number | string;
};
 
const props = defineProps<SkeletonBaseProps>();
 
const options = computed(() => (props.options ?? {}) as ArticleOptions);
 
const paragraphs = computed(() => Math.max(1, options.value.paragraphs ?? 2));
const linesPerParagraph = computed(() =>
  Math.max(2, options.value.linesPerParagraph ?? 4)
);
 
const titleWidth = computed(() => options.value.titleWidth ?? "70%");
 
const paragraphGap = computed(() => {
  const v = options.value.paragraphGap ?? "20px";
  return typeof v === "number" ? `${v}px` : v;
});
 
const lineGap = computed(() => {
  const v = options.value.lineGap ?? "8px";
  return typeof v === "number" ? `${v}px` : v;
});
 
const containerWidth = computed(() =>
  typeof props.width === "number" ? `${props.width}px` : props.width ?? "100%"
);
 
const forwardedProps = computed(() => {
  const { width, options, lines, size, ...rest } = props;
  return rest;
});
 
function getLineWidth(index: number, total: number) {
  if (index === total - 1) return "60%";
  if (index === total - 2) return "85%";
  return "100%";
}
</script>
 
<template>
  <div
    class="vslk-article"
    :style="{
      width: containerWidth,
      gap: paragraphGap,
    }"
  >
    <Skeleton
      v-bind="forwardedProps"
      variant="text"
      :width="titleWidth"
      height="20px"
    />
 
    <div
      v-for="paragraph in paragraphs"
      :key="paragraph"
      class="vslk-article__paragraph"
      :style="{ gap: lineGap }"
    >
      <Skeleton
        v-for="line in linesPerParagraph"
        :key="line"
        v-bind="forwardedProps"
        variant="text"
        :width="getLineWidth(line - 1, linesPerParagraph)"
        height="10px"
      />
    </div>
  </div>
</template>
 
<style scoped>
.vslk-article {
  display: flex;
  flex-direction: column;
  min-width: 0;
  box-sizing: border-box;
}
 
.vslk-article__paragraph {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
</style>