NumberInputBox.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <template>
  2. <Touchable
  3. :innerStyle="{
  4. ...themeStyles.box.value,
  5. marginHorizontal: themeContext.resolveSize(gutter),
  6. flex: autoSize ? '1 1 100%' : undefined,
  7. ...finalBoxStyle,
  8. ...boxStyle,
  9. }"
  10. :setCursor="false"
  11. :pressedColor="themeContext.resolveThemeColor('pressed.white')"
  12. :touchable="!disableKeyPad"
  13. direction="column"
  14. @click="emit('click')"
  15. >
  16. <text
  17. :style="{
  18. ...themeStyles.text.value,
  19. ...textStyle,
  20. }"
  21. >
  22. {{ value ? (isPassword ? '●' : value) : '&nbsp;'}}
  23. </text>
  24. <view
  25. v-if="!value && active && showCursur" class="number-input-cursor"
  26. :style="themeStyles.inputCursor.value"
  27. />
  28. </Touchable>
  29. </template>
  30. <script setup lang="ts">
  31. import { computed } from 'vue';
  32. import { useTheme, type TextStyle, type ViewStyle } from '../theme/ThemeDefine';
  33. import { DynamicColor, DynamicSize, selectStyleType } from '../theme/ThemeTools';
  34. import FlexCol from '../layout/FlexCol.vue';
  35. import type { NumberInputBorderType } from './NumberInput.vue';
  36. import Touchable from '../feedback/Touchable.vue';
  37. export interface NumberInputBoxProps {
  38. value?: string,
  39. index: number,
  40. active: boolean,
  41. autoSize: boolean,
  42. isPassword: boolean,
  43. disableKeyPad: boolean,
  44. showCursur: boolean,
  45. gutter: number,
  46. boxStyle?: ViewStyle,
  47. textStyle?: TextStyle,
  48. borderWidth: number,
  49. borderType: NumberInputBorderType,
  50. borderColor: string,
  51. activeBorderColor: string,
  52. }
  53. const emit = defineEmits([ 'click' ]);
  54. const props = withDefaults(defineProps<NumberInputBoxProps>(), {
  55. value: '',
  56. });
  57. const themeContext = useTheme();
  58. const themeStyles = themeContext.useThemeStyles({
  59. box: {
  60. display: 'flex',
  61. position: 'relative',
  62. paddingVertical: DynamicSize('NumberInputBoxPaddingVertical', 24),
  63. paddingHorizontal: DynamicSize('NumberInputBoxPaddingHorizontal', 16),
  64. borderRadius: DynamicSize('NumberInputBoxBorderRadius', 20),
  65. flexDirection: 'row',
  66. flexShrink: 1,
  67. alignItems: 'center',
  68. justifyContent: 'center',
  69. },
  70. text: {
  71. fontSize: DynamicSize('NumberInputTextFontSize', 36),
  72. width: DynamicSize('NumberInputTextWidth', 40),
  73. textAlign: 'center',
  74. color: DynamicColor('NumberInputTextColor', 'text.content'),
  75. },
  76. inputCursor: {
  77. position: 'absolute',
  78. top: DynamicSize('NumberInputCursorLeft', '50%'),
  79. left: DynamicSize('NumberInputCursorLeft', '50%'),
  80. marginTop: DynamicSize('NumberInputCursorMarginTop', -18),
  81. width: DynamicSize('NumberInputCursorWidth', 3),
  82. marginLeft: DynamicSize('NumberInputCursorMarginLeft', -1.5),
  83. height: DynamicSize('NumberInputCursorHeight', 36),
  84. backgroundColor: DynamicColor('NumberInputCursorBackgroundColor', 'text.content'),
  85. },
  86. });
  87. const finalBoxStyle = computed(() => selectStyleType<ViewStyle, NumberInputBorderType>(props.borderType, 'box', {
  88. box: {
  89. borderStyle: 'solid',
  90. borderWidth: themeContext.resolveSize(props.borderWidth),
  91. borderColor: themeContext.resolveThemeColor(props.active ? props.activeBorderColor : props.borderColor),
  92. },
  93. underline: {
  94. borderWidth: themeContext.resolveSize(props.borderWidth),
  95. borderColor: 'transparent',
  96. borderBottomWidth: themeContext.resolveSize(props.borderWidth),
  97. borderBottomStyle: 'solid',
  98. borderBottomColor: themeContext.resolveThemeColor(props.active ? props.activeBorderColor : props.borderColor),
  99. borderRadius: 0,
  100. },
  101. }) as ViewStyle);
  102. </script>
  103. <style lang="scss">
  104. .number-input-cursor {
  105. animation: cursorBlink 1s infinite;
  106. }
  107. @keyframes cursorBlink {
  108. 0% {
  109. opacity: 0;
  110. }
  111. 50% {
  112. opacity: 1;
  113. }
  114. 100% {
  115. opacity: 0;
  116. }
  117. }
  118. </style>