1
- import { defineComponent , h , ref , computed , PropType } from '@vue/runtime-core'
1
+ import { defineComponent , h , ref , computed , watch } from '@vue/runtime-core'
2
2
import chalk from 'chalk'
3
3
import { TuiText } from './Text'
4
4
import { onInputData } from '../composables/input'
5
5
import type { KeyDataEvent } from '../input/types'
6
+ import { useFocus } from '../focus/Focusable'
6
7
7
8
const SKIP_EVENT_KEY = [ 'ArrowUp' , 'ArrowDown' , 'Ctrl' , 'Tab' , 'Shift' ]
8
- const PWD_FIGURE = '*'
9
9
10
10
export const TuiInput = defineComponent ( {
11
11
props : {
@@ -14,131 +14,104 @@ export const TuiInput = defineComponent({
14
14
required : false ,
15
15
default : '' ,
16
16
} ,
17
- cursor : {
18
- type : Boolean ,
19
- required : false ,
20
- default : true ,
21
- } ,
22
17
modelValue : {
23
18
type : String ,
24
19
required : true ,
25
20
} ,
26
- type : {
27
- type : String as PropType < 'text' | 'password' > ,
28
- required : false ,
29
- default : 'text' ,
21
+ focus : {
22
+ type : Boolean ,
23
+ required : true ,
30
24
} ,
31
25
} ,
32
- emits : [ 'update:modelValue' , 'change' , 'submit' ] ,
26
+ emits : [ 'update:modelValue' ] ,
33
27
setup ( props , { emit } ) {
28
+ const { active, isFocus } = useFocus ( {
29
+ active : props . focus ,
30
+ } )
34
31
const cursorOffset = ref ( props . modelValue . length )
35
- const exited = ref ( false )
36
32
const content = computed ( ( ) => {
37
- if ( props . cursor && ! exited . value ) {
33
+ if ( active . value ) {
38
34
if ( props . modelValue ) {
39
35
if (
40
36
props . modelValue &&
41
37
props . modelValue . length <= cursorOffset . value
42
38
) {
43
- return (
44
- ( props . type === 'text'
45
- ? props . modelValue
46
- : PWD_FIGURE . repeat ( props . modelValue . length ) ) +
47
- chalk . inverse ( ' ' )
48
- )
39
+ return props . modelValue + chalk . inverse ( ' ' )
49
40
}
50
41
51
42
const l = props . modelValue . slice ( 0 , cursorOffset . value )
52
43
const m = chalk . inverse ( props . modelValue [ cursorOffset . value ] )
53
44
const r = props . modelValue . slice ( cursorOffset . value + 1 )
54
45
55
- return props . type === 'text'
56
- ? l + m + r
57
- : PWD_FIGURE . repeat ( l . length ) +
58
- chalk . inverse ( PWD_FIGURE ) +
59
- PWD_FIGURE . repeat ( r . length )
46
+ return l + m + r
60
47
} else {
61
48
return props . placeholder ? '' : chalk . inverse ( ' ' )
62
49
}
63
50
} else {
64
- const value = props . modelValue
65
- return props . type === 'text' ? value : PWD_FIGURE . repeat ( value . length )
51
+ return props . modelValue
66
52
}
67
53
} )
68
54
69
- function updateCursorOffset ( type : '-' | '+' ) {
70
- if ( type === '-' ) {
71
- cursorOffset . value = Math . max ( 0 , cursorOffset . value - 1 )
72
- } else {
73
- cursorOffset . value = Math . min (
74
- cursorOffset . value + 1 ,
75
- + props . modelValue . length + 1
76
- )
77
- }
55
+ watch (
56
+ ( ) => props . focus ,
57
+ ( value ) => ( isFocus . value = value )
58
+ )
59
+
60
+ function updateCursorOffset ( offset : number ) {
61
+ cursorOffset . value = Math . max (
62
+ 0 ,
63
+ Math . min ( cursorOffset . value + offset , props . modelValue . length + 1 )
64
+ )
78
65
}
79
66
80
67
function updateValue ( value : string ) {
81
- emit ( 'change' , value )
82
68
emit ( 'update:modelValue' , value )
83
69
}
84
70
85
- const stop = onInputData ( ( { data, event } ) => {
71
+ onInputData ( ( { data, event } ) => {
72
+ if ( ! active . value ) return
86
73
const eventKey = ( < KeyDataEvent > event ! ) . key
87
74
if ( SKIP_EVENT_KEY . includes ( eventKey ) || ! eventKey ) return
88
75
89
- // Submit
90
- if ( eventKey === 'Enter' ) {
91
- stop ( )
92
- exited . value = true
93
- emit ( 'submit' , props . modelValue )
94
- return
95
- }
96
-
97
76
// Move cursor
98
- if ( props . cursor && eventKey === 'ArrowLeft' ) {
99
- updateCursorOffset ( '-' )
100
- } else if ( props . cursor && eventKey === 'ArrowRight' ) {
101
- updateCursorOffset ( '+' )
77
+ if ( eventKey === 'ArrowLeft' ) {
78
+ updateCursorOffset ( - 1 )
79
+ } else if ( eventKey === 'ArrowRight' ) {
80
+ updateCursorOffset ( 1 )
102
81
}
103
82
// Delete Content
104
83
else if ( eventKey === 'Backspace' || eventKey === 'Delete' ) {
105
- if ( ! props . cursor ) {
106
- updateValue ( props . modelValue . slice ( 0 , - 1 ) )
107
- } else if ( props . cursor && cursorOffset . value > 0 ) {
84
+ if ( cursorOffset . value > 0 ) {
108
85
updateValue (
109
86
props . modelValue . slice ( 0 , cursorOffset . value - 1 ) +
110
87
props . modelValue . slice ( cursorOffset . value )
111
88
)
112
- updateCursorOffset ( '-' )
89
+ updateCursorOffset ( - 1 )
113
90
}
114
91
}
115
92
// Typing Content
116
93
else {
117
94
updateValue (
118
- props . cursor
119
- ? props . modelValue . slice ( 0 , cursorOffset . value ) +
120
- data +
121
- props . modelValue . slice ( cursorOffset . value )
122
- : props . modelValue + data
95
+ props . modelValue . slice ( 0 , cursorOffset . value ) +
96
+ data +
97
+ props . modelValue . slice ( cursorOffset . value )
123
98
)
124
- updateCursorOffset ( '+' )
125
- if ( props . cursor && cursorOffset . value === props . modelValue . length ) {
126
- updateCursorOffset ( '+' )
99
+ updateCursorOffset ( 1 )
100
+ if ( cursorOffset . value === props . modelValue . length ) {
101
+ updateCursorOffset ( 1 )
127
102
}
128
103
}
129
104
} )
130
105
131
106
return ( ) =>
132
- h ( TuiText , ( ) =>
133
- props . placeholder && ! props . modelValue
134
- ? h (
135
- TuiText ,
136
- {
137
- dimmed : true ,
138
- } ,
139
- ( ) => props . placeholder
140
- )
141
- : h ( TuiText , ( ) => content . value )
142
- )
107
+ props . placeholder && ! props . modelValue
108
+ ? h (
109
+ TuiText ,
110
+ {
111
+ dimmed : true ,
112
+ } ,
113
+ ( ) => props . placeholder
114
+ )
115
+ : h ( TuiText , ( ) => content . value )
143
116
} ,
144
117
} )
0 commit comments