NumberInputBox.vue 3.6 KB

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