SideBar.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <template>
  2. <view :style="{
  3. ...themeStyles.container.value,
  4. ...props.innerStyle
  5. }">
  6. <slot name="background" />
  7. <slot />
  8. </view>
  9. </template>
  10. <script setup lang="ts">
  11. import { computed, provide, toRef, type Ref } from 'vue';
  12. import { useTheme, type TextStyle, type ViewStyle } from '../theme/ThemeDefine';
  13. import { DynamicColor } from '../theme/ThemeTools';
  14. export interface SideBarProps {
  15. /**
  16. * 自定义外层样式
  17. */
  18. innerStyle?: ViewStyle;
  19. /**
  20. * 选中文字颜色
  21. * @default primary
  22. */
  23. activeColor?: string;
  24. /**
  25. * 选中时条目的样式
  26. */
  27. activeStyle?: ViewStyle;
  28. /**
  29. * 选中时条目左侧的标记的样式
  30. */
  31. activeBadgeStyle?: ViewStyle;
  32. /**
  33. * 未选中文字颜色
  34. * @default text.title
  35. */
  36. inactiveColor?: string;
  37. /**
  38. * 禁用文字颜色
  39. * @default text.second
  40. */
  41. disableColor?: string;
  42. /**
  43. * 未选中时条目的样式
  44. */
  45. inactiveStyle?: ViewStyle;
  46. /**
  47. * 标签文字样式
  48. */
  49. textStyle?: TextStyle;
  50. /**
  51. * 选中的条目名称。
  52. * @default ''
  53. */
  54. modelValue?: string|number,
  55. }
  56. const emit = defineEmits([ 'update:modelValue', 'clickItem' ])
  57. const props = withDefaults(defineProps<SideBarProps>(), {
  58. activeColor: 'primary',
  59. inactiveColor: 'text.title',
  60. disableColor: 'text.second',
  61. });
  62. const themeContext = useTheme();
  63. const themeStyles = themeContext.useThemeStyles({
  64. container: {
  65. position: 'relative',
  66. flexDirection: 'column',
  67. alignItems: 'flex-start',
  68. justifyContent: 'flex-start',
  69. },
  70. activeStyle: {
  71. backgroundColor: DynamicColor('SideBarItemActiveBackgroundColor', 'white'),
  72. },
  73. inactiveStyle: {
  74. backgroundColor: DynamicColor('SideBarItemInactiveBackgroundColor', 'light'),
  75. },
  76. });
  77. const activeStyle = computed(() => props.activeStyle || themeStyles.activeStyle.value);
  78. const inactiveStyle = computed(() => props.inactiveStyle || themeStyles.inactiveStyle.value);
  79. export interface SideBarContext {
  80. selectedName: Ref<string|number|undefined>,
  81. activeColor: Ref<string>,
  82. inactiveColor: Ref<string>,
  83. disableColor: Ref<string>,
  84. activeStyle: Ref<ViewStyle>,
  85. inactiveStyle: Ref<ViewStyle>,
  86. textStyle: Ref<TextStyle|undefined>,
  87. activeBadgeStyle: Ref<ViewStyle|undefined>,
  88. onItemClick: (name: string|number) => void,
  89. }
  90. provide<SideBarContext>('SideBarContext', {
  91. selectedName: toRef(props, 'modelValue'),
  92. activeColor: toRef(props, 'activeColor'),
  93. disableColor: toRef(props, 'disableColor'),
  94. inactiveColor: toRef(props, 'inactiveColor'),
  95. activeStyle: activeStyle,
  96. inactiveStyle: inactiveStyle,
  97. textStyle: toRef(props, 'textStyle'),
  98. activeBadgeStyle: toRef(props, 'activeBadgeStyle'),
  99. onItemClick: (name) => {
  100. emit('update:modelValue', name);
  101. emit('clickItem', name);
  102. },
  103. })
  104. </script>