cl-timeline-item.uvue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <template>
  2. <view class="cl-timeline-item" :class="[pt.className]">
  3. <view class="cl-timeline-item__left">
  4. <cl-icon
  5. v-if="icon != ''"
  6. :name="icon"
  7. :size="20"
  8. :pt="{
  9. className: `${pt.icon?.className}`
  10. }"
  11. ></cl-icon>
  12. <view v-else class="cl-timeline-item__dot"></view>
  13. <view class="cl-timeline-item__line dark:!bg-surface-600" v-if="!hideLine"></view>
  14. </view>
  15. <view
  16. class="cl-timeline-item__right"
  17. :class="[
  18. {
  19. 'is-icon': icon != '',
  20. 'is-title': title != ''
  21. }
  22. ]"
  23. >
  24. <cl-text
  25. v-if="title != ''"
  26. :size="16"
  27. :pt="{
  28. className: parseClass([
  29. `mb-2 !font-bold ${pt.title?.className}`,
  30. [isDark, 'text-white', 'text-surface-900']
  31. ])
  32. }"
  33. >{{ title }}</cl-text
  34. >
  35. <cl-text
  36. v-if="content != ''"
  37. :pt="{
  38. className: `mb-3 ${pt.content?.className}`
  39. }"
  40. >{{ content }}</cl-text
  41. >
  42. <slot></slot>
  43. <cl-text
  44. v-if="date != ''"
  45. :size="12"
  46. :pt="{
  47. className: `${pt.date?.className}`
  48. }"
  49. color="info"
  50. >{{ date }}</cl-text
  51. >
  52. </view>
  53. </view>
  54. </template>
  55. <script setup lang="ts">
  56. import { computed } from "vue";
  57. import { isDark, parseClass, parsePt } from "@/.cool";
  58. import type { PassThroughProps } from "../../types";
  59. defineOptions({
  60. name: "cl-timeline-item"
  61. });
  62. const props = defineProps({
  63. pt: {
  64. type: Object,
  65. default: () => ({})
  66. },
  67. // 标题
  68. title: {
  69. type: String,
  70. default: ""
  71. },
  72. // 图标
  73. icon: {
  74. type: String,
  75. default: ""
  76. },
  77. // 内容
  78. content: {
  79. type: String,
  80. default: ""
  81. },
  82. // 日期
  83. date: {
  84. type: String,
  85. default: ""
  86. },
  87. // 是否隐藏线
  88. hideLine: {
  89. type: Boolean,
  90. default: false
  91. }
  92. });
  93. type PassThrough = {
  94. className?: string;
  95. icon?: PassThroughProps;
  96. title?: PassThroughProps;
  97. content?: PassThroughProps;
  98. date?: PassThroughProps;
  99. };
  100. const pt = computed(() => parsePt<PassThrough>(props.pt));
  101. </script>
  102. <style lang="scss" scoped>
  103. .cl-timeline-item {
  104. @apply flex flex-row w-full;
  105. overflow: visible;
  106. margin-bottom: 5px;
  107. &__left {
  108. @apply flex flex-col items-center overflow-visible;
  109. width: 25px;
  110. margin-right: 5px;
  111. }
  112. &__dot {
  113. @apply rounded-full bg-surface-300;
  114. height: 8px;
  115. width: 8px;
  116. }
  117. &__line {
  118. @apply bg-surface-300;
  119. width: 1px;
  120. flex: 1;
  121. margin-top: 5px;
  122. }
  123. &__right {
  124. @apply relative;
  125. top: -6px;
  126. flex: 1;
  127. margin-bottom: 20px;
  128. &.is-title {
  129. top: -6px;
  130. }
  131. &.is-icon {
  132. top: -2px;
  133. }
  134. }
  135. }
  136. </style>