Skip to content

Commit 12b0421

Browse files
committed
chore: update
1 parent 98051af commit 12b0421

File tree

3 files changed

+77
-87
lines changed

3 files changed

+77
-87
lines changed

packages/core/src/components/Input.ts

Lines changed: 46 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { defineComponent, h, ref, computed, PropType } from '@vue/runtime-core'
1+
import { defineComponent, h, ref, computed, watch } from '@vue/runtime-core'
22
import chalk from 'chalk'
33
import { TuiText } from './Text'
44
import { onInputData } from '../composables/input'
55
import type { KeyDataEvent } from '../input/types'
6+
import { useFocus } from '../focus/Focusable'
67

78
const SKIP_EVENT_KEY = ['ArrowUp', 'ArrowDown', 'Ctrl', 'Tab', 'Shift']
8-
const PWD_FIGURE = '*'
99

1010
export const TuiInput = defineComponent({
1111
props: {
@@ -14,131 +14,104 @@ export const TuiInput = defineComponent({
1414
required: false,
1515
default: '',
1616
},
17-
cursor: {
18-
type: Boolean,
19-
required: false,
20-
default: true,
21-
},
2217
modelValue: {
2318
type: String,
2419
required: true,
2520
},
26-
type: {
27-
type: String as PropType<'text' | 'password'>,
28-
required: false,
29-
default: 'text',
21+
focus: {
22+
type: Boolean,
23+
required: true,
3024
},
3125
},
32-
emits: ['update:modelValue', 'change', 'submit'],
26+
emits: ['update:modelValue'],
3327
setup(props, { emit }) {
28+
const { active, isFocus } = useFocus({
29+
active: props.focus,
30+
})
3431
const cursorOffset = ref(props.modelValue.length)
35-
const exited = ref(false)
3632
const content = computed(() => {
37-
if (props.cursor && !exited.value) {
33+
if (active.value) {
3834
if (props.modelValue) {
3935
if (
4036
props.modelValue &&
4137
props.modelValue.length <= cursorOffset.value
4238
) {
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(' ')
4940
}
5041

5142
const l = props.modelValue.slice(0, cursorOffset.value)
5243
const m = chalk.inverse(props.modelValue[cursorOffset.value])
5344
const r = props.modelValue.slice(cursorOffset.value + 1)
5445

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
6047
} else {
6148
return props.placeholder ? '' : chalk.inverse(' ')
6249
}
6350
} else {
64-
const value = props.modelValue
65-
return props.type === 'text' ? value : PWD_FIGURE.repeat(value.length)
51+
return props.modelValue
6652
}
6753
})
6854

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+
)
7865
}
7966

8067
function updateValue(value: string) {
81-
emit('change', value)
8268
emit('update:modelValue', value)
8369
}
8470

85-
const stop = onInputData(({ data, event }) => {
71+
onInputData(({ data, event }) => {
72+
if (!active.value) return
8673
const eventKey = (<KeyDataEvent>event!).key
8774
if (SKIP_EVENT_KEY.includes(eventKey) || !eventKey) return
8875

89-
// Submit
90-
if (eventKey === 'Enter') {
91-
stop()
92-
exited.value = true
93-
emit('submit', props.modelValue)
94-
return
95-
}
96-
9776
// 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)
10281
}
10382
// Delete Content
10483
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) {
10885
updateValue(
10986
props.modelValue.slice(0, cursorOffset.value - 1) +
11087
props.modelValue.slice(cursorOffset.value)
11188
)
112-
updateCursorOffset('-')
89+
updateCursorOffset(-1)
11390
}
11491
}
11592
// Typing Content
11693
else {
11794
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)
12398
)
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)
127102
}
128103
}
129104
})
130105

131106
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)
143116
},
144117
})

packages/core/src/focus/Focusable.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {
22
computed,
3-
customRef,
43
onUnmounted,
54
ref,
65
watch,
@@ -9,6 +8,7 @@ import {
98
unref,
109
onMounted,
1110
} from '@vue/runtime-core'
11+
import type { WritableComputedRef } from '@vue/runtime-core'
1212
import { checkCurrentInstance, MaybeRef } from '../utils'
1313
import { Focusable, FocusId } from './types'
1414
import { useFocusManager } from './FocusManager'
@@ -35,7 +35,9 @@ export function useFocus({
3535
active: startsActive,
3636
disabled: startsDisabled,
3737
id: idSource,
38-
}: FocusableOptions = {}): Focusable {
38+
}: FocusableOptions = {}): Focusable & {
39+
isFocus: WritableComputedRef<boolean>
40+
} {
3941
if (!checkCurrentInstance('useFocus')) {
4042
throw new Error('Cannot create a focusable without an instance')
4143
}
@@ -85,5 +87,19 @@ export function useFocus({
8587
focusable._i = null
8688
})
8789

88-
return focusable
90+
return {
91+
...focusable,
92+
isFocus: computed<boolean>({
93+
get() {
94+
return active.value
95+
},
96+
set(value) {
97+
if (value) {
98+
focus(unref(id))
99+
} else {
100+
focus(null)
101+
}
102+
},
103+
}),
104+
}
89105
}

packages/playground/src/InputDemo.vue

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
<script setup lang="ts">
22
const value = ref('')
3-
const visible = ref(false)
4-
function submit() {
5-
visible.value = true
6-
}
3+
const isFocus = ref(true)
4+
const value1 = ref('')
5+
const isFocus1 = ref(false)
6+
7+
watch(value, (v: string) => {
8+
if (v === 'hello') {
9+
isFocus.value = false
10+
isFocus1.value = true
11+
}
12+
})
713
</script>
814

915
<template borderStyle="round">
10-
<Input
11-
v-model="value"
12-
placeholder="Hello World"
13-
@submit="submit"
14-
type="password"
15-
/>
16-
<Text v-if="visible">Value:{{ value }}</Text>
16+
<Input v-model="value" :focus="isFocus" />
17+
<Input v-model="value1" :focus="isFocus1" />
1718
</template>

0 commit comments

Comments
 (0)