Step.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <template>
  2. <scroll-view
  3. v-if="direction === 'horizontal'"
  4. :scroll-x="true"
  5. :show-scrollbar="false"
  6. :scroll-with-animation="true"
  7. :scroll-left="scrollLeft"
  8. :style="themeStyles.scrollHorizontal.value"
  9. >
  10. <view :style="themeStyles.stepHorizontal.value">
  11. <slot />
  12. </view>
  13. </scroll-view>
  14. <view v-else :style="themeStyles.stepVertical.value">
  15. <slot />
  16. </view>
  17. </template>
  18. <script setup lang="ts">
  19. //TODO
  20. import { computed, provide, toRef, type Ref } from 'vue';
  21. import type { IconProps } from '../basic/Icon.vue';
  22. import { propGetThemeVar, useTheme, type TextStyle } from '../theme/ThemeDefine';
  23. import { useChildLinkParent } from '../composeabe/ChildItem';
  24. const themeContext = useTheme();
  25. export interface StepProps {
  26. /**
  27. * 步骤条的方向
  28. * @default 'horizontal'
  29. */
  30. direction?: 'vertical'|'horizontal',
  31. /**
  32. * 激活时的颜色
  33. * @default primary
  34. */
  35. activeColor?: string,
  36. /**
  37. * 未激活时的颜色
  38. * @default Color.grey
  39. */
  40. inactiveColor?: string,
  41. /**
  42. * 文字颜色
  43. * @default text.content
  44. */
  45. textColor?: string,
  46. /**
  47. * 当为水平模式时,条目的宽度
  48. * @default 150rpx
  49. */
  50. lineItemWidth?: number,
  51. /**
  52. * 当为水平模式时,分隔线的边距偏移
  53. * @default 10
  54. */
  55. lineOffset?: number,
  56. /**
  57. * 线段粗细
  58. * @default 1
  59. */
  60. lineWidth?: number;
  61. /**
  62. * 当前激活的步骤
  63. */
  64. activeIndex: number,
  65. /**
  66. * 同 StepItemProps.activeIcon 此项用于所有子条目的设置
  67. */
  68. activeIcon?: string,
  69. /**
  70. * 同 StepItemProps.inactiveIcon 此项用于所有子条目的设置
  71. */
  72. inactiveIcon?: string,
  73. /**
  74. * 同 StepItemProps.finishIcon 此项用于所有子条目的设置
  75. */
  76. finishIcon?: string,
  77. /**
  78. * 同 StepItemProps.iconProps 此项用于所有子条目的设置
  79. */
  80. iconProps?: IconProps;
  81. /**
  82. * 同 StepItemProps.textStyle 此项用于所有子条目的设置
  83. */
  84. textStyle?: TextStyle,
  85. }
  86. const emit = defineEmits([ 'click' ]);
  87. const props = withDefaults(defineProps<StepProps>(), {
  88. direction: 'horizontal',
  89. lineItemWidth: () => propGetThemeVar('StepLineItemWidth', 150),
  90. lineOffset: () => propGetThemeVar('StepLineOffset', 25),
  91. lineWidth: () => propGetThemeVar('StepLineWidth', 2),
  92. activeColor: () => propGetThemeVar('StepActiveColor', 'primary'),
  93. inactiveColor: () => propGetThemeVar('StepInactiveColor', 'lightGrey'),
  94. textColor: () => propGetThemeVar('StepTextColor', 'text.content'),
  95. });
  96. const scrollLeft = computed(() => {
  97. if (props.direction === 'vertical')
  98. return 0;
  99. return uni.upx2px((props.activeIndex - 1) * props.lineItemWidth - props.lineItemWidth / 2);
  100. })
  101. const themeStyles = themeContext.useThemeStyles({
  102. stepVertical: {
  103. position: 'relative',
  104. display: 'flex',
  105. flexDirection: 'column',
  106. },
  107. stepHorizontal: {
  108. display: 'flex',
  109. position: 'relative',
  110. flexDirection: 'row',
  111. justifyContent: 'flex-start',
  112. width: 'auto',
  113. },
  114. scrollHorizontal: {
  115. position: 'relative',
  116. flex: 0,
  117. width: '100%',
  118. },
  119. });
  120. const {
  121. getPosition,
  122. resetCounter,
  123. getLength,
  124. } = useChildLinkParent({
  125. getPositionExtra(index) {
  126. return {}
  127. },
  128. });
  129. export interface StepContext {
  130. direction: Ref<StepProps['direction']>,
  131. activeColor: Ref<StepProps['activeColor']>,
  132. inactiveColor: Ref<StepProps['inactiveColor']>,
  133. textColor: Ref<StepProps['textColor']>,
  134. lineItemWidth: Ref<StepProps['lineItemWidth']>,
  135. lineOffset: Ref<StepProps['lineOffset']>,
  136. lineWidth: Ref<StepProps['lineWidth']>,
  137. activeIndex: Ref<StepProps['activeIndex']>,
  138. getLength: () => number,
  139. getPosition: () => number,
  140. resetCounter: () => void,
  141. }
  142. provide<StepContext>('StepContext', {
  143. direction: toRef(props, 'direction'),
  144. activeColor: toRef(props, 'activeColor'),
  145. inactiveColor: toRef(props, 'inactiveColor'),
  146. textColor: toRef(props, 'textColor'),
  147. lineItemWidth: toRef(props, 'lineItemWidth'),
  148. lineOffset: toRef(props, 'lineOffset'),
  149. lineWidth: toRef(props, 'lineWidth'),
  150. activeIndex: toRef(props, 'activeIndex'),
  151. getLength,
  152. getPosition: () => getPosition().index,
  153. resetCounter,
  154. });
  155. </script>