CellGroup.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. <template>
  2. <FlexCol :style="{ width: '100%' }">
  3. <text v-if="title" :style="(titleSpeicalStyle as any)">
  4. {{ title }}
  5. </text>
  6. <view v-else-if="showTopMargin" :style="{ ...titleStyle, paddingTop: showTopMarginSize }" />
  7. <view :style="{
  8. ...(inset ? insetViewStyle as any : {}),
  9. ...(round ? roundViewStyle as any : {}),
  10. }">
  11. <slot />
  12. </view>
  13. <view v-if="showBottomMargin" :style="(titleSpeicalStyle as any)" />
  14. </FlexCol>
  15. </template>
  16. <script setup lang="ts">
  17. import { computed } from 'vue';
  18. import { propGetThemeVar, useTheme } from '../theme/ThemeDefine';
  19. import FlexCol from '../layout/FlexCol.vue';
  20. export interface CellGroupProp {
  21. /**
  22. * 分组标题
  23. */
  24. title?: string,
  25. /**
  26. * 是否展示为圆角卡片风格
  27. */
  28. round?: boolean,
  29. /**
  30. * 是否增加内边距
  31. */
  32. inset?: boolean,
  33. /**
  34. * 是否显示底部边距。默认否
  35. */
  36. showBottomMargin?: boolean,
  37. /**
  38. * 是否显示没有标题时顶部边距。默认是
  39. */
  40. showTopMargin?: boolean,
  41. /**
  42. * 是否显示没有标题时顶部边距大小。默认是 10rpx
  43. */
  44. showTopMarginSize?: number,
  45. /**
  46. * 标题的样式
  47. */
  48. titleStyle?: object,
  49. /**
  50. * 标题背景是否变暗
  51. */
  52. titleDark?: boolean,
  53. }
  54. const theme = useTheme();
  55. const props = withDefaults(defineProps<CellGroupProp>(), {
  56. titleDark: () => propGetThemeVar('CellGroupTitleDark', false),
  57. inset: () => propGetThemeVar('CellGroupInset', false),
  58. showTopMargin: () => propGetThemeVar('CellGroupShowTopMargin', true),
  59. showBottomMargin: () => propGetThemeVar('CellGroupShowBottomMargin', false),
  60. showTopMarginSize: () => propGetThemeVar('CellGroupTopMarginSize', 10),
  61. });
  62. const CellGroupDarkTitleBackgroundColor = computed(() => theme.resolveThemeColor('CellGroupDarkTitleBackgroundColor', 'border.light'));
  63. const CellGroupInsetPaddingHorizontal = computed(() => theme.resolveThemeSize('CellGroupInsetPaddingHorizontal', 40));
  64. const CellGroupPaddingHorizontal = computed(() => theme.resolveThemeSize('CellGroupPaddingHorizontal', 20));
  65. const titleSpeicalStyle = computed(() => ({
  66. color: theme.resolveThemeColor('CellGroupTitleColor', 'text.second'),
  67. paddingTop: theme.resolveThemeSize('CellGroupTitlePaddingTop', 24),
  68. paddingBottom: theme.resolveThemeSize('CellGroupTitlePaddingBottom', 12),
  69. backgroundColor: props.titleDark ? CellGroupDarkTitleBackgroundColor.value : undefined,
  70. paddingLeft: props.inset ? CellGroupInsetPaddingHorizontal.value : CellGroupPaddingHorizontal.value,
  71. paddingRight: props.inset ? CellGroupInsetPaddingHorizontal.value : CellGroupPaddingHorizontal.value,
  72. }));
  73. const roundViewStyle = computed(() => ({
  74. borderRadius: theme.resolveThemeSize('CellGroupInsetBorderRadius', 20),
  75. backgroundColor: theme.resolveThemeColor('CellGroupInsetBackgroundColor', 'white'),
  76. overflow: 'hidden',
  77. }));
  78. const insetViewStyle = computed(() => ({
  79. position: 'relative',
  80. margin: `${theme.resolveThemeSize('CellGroupInsetMarginVertical', 0)} ${theme.resolveThemeSize('CellGroupInsetMarginHorizontal', 30)}`,
  81. flexDirection: 'column',
  82. }));
  83. </script>