Skip to content

Commit

Permalink
fix(PinInput): placeholder not showing after reseting the value progr…
Browse files Browse the repository at this point in the history
…amatically (#1530)

* fix(PinInput): placeholder not showing after reseting the value programatically

* test: include test

Co-authored-by: antfu <[email protected]>
  • Loading branch information
zernonia and antfu authored Dec 30, 2024
1 parent ad43ecf commit 2ff8ffe
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 7 deletions.
24 changes: 24 additions & 0 deletions packages/radix-vue/src/PinInput/PinInput.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ describe('given default PinInput', () => {
expect(await axe(wrapper.element)).toHaveNoViolations()
})

it('should display input placeholders', () => {
expect(inputs[0].element.placeholder).toBe('') // first input was focused thus not showing placeholder
expect(inputs[1].element.placeholder).toBe('*')
expect(inputs[2].element.placeholder).toBe('*')
expect(inputs[3].element.placeholder).toBe('*')
expect(inputs[4].element.placeholder).toBe('*')
})

describe('after user input', () => {
beforeEach(async () => {
await userEvent.keyboard('test')
Expand Down Expand Up @@ -143,6 +151,22 @@ describe('given default PinInput', () => {
it('should emit \'complete\' with the result', () => {
expect(wrapper.emitted('complete')?.[0]?.[0]).toStrictEqual(['a', 'p', 'p', 'l', 'e'])
})

describe('after resetting value', async () => {
beforeEach(async () => {
await userEvent.keyboard('apple')
const button = wrapper.find('button')
await button.trigger('click')
})

it('should display input placeholders', () => {
expect(inputs[0].element.placeholder).toBe('*')
expect(inputs[1].element.placeholder).toBe('*')
expect(inputs[2].element.placeholder).toBe('*')
expect(inputs[3].element.placeholder).toBe('*')
expect(inputs[4].element.placeholder).toBe('*')
})
})
})
})

Expand Down
25 changes: 18 additions & 7 deletions packages/radix-vue/src/PinInput/PinInputInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ export interface PinInputInputProps extends PrimitiveProps {
</script>

<script setup lang="ts">
import { computed, nextTick, onMounted, onUnmounted } from 'vue'
import { computed, nextTick, onMounted, onUnmounted, watch } from 'vue'
const props = withDefaults(defineProps<PinInputInputProps>(), {
as: 'input',
})
const context = injectPinInputRootContext()
const inputElements = computed(() => Array.from(context.inputElements!.value))
const currentValue = computed(() => context.modelValue.value[props.index])
const disabled = computed(() => props.disabled || context.disabled.value)
const isOtpMode = computed(() => context.otp.value)
Expand Down Expand Up @@ -48,6 +49,14 @@ function handleInput(event: InputEvent) {
nextEl.focus()
}
function resetPlaceholder() {
const target = currentElement.value as HTMLInputElement
nextTick(() => {
if (!target.value)
target.placeholder = context.placeholder.value
})
}
function handleKeydown(event: KeyboardEvent) {
useArrowNavigation(event, document.activeElement as HTMLElement, undefined, {
itemsArray: inputElements.value,
Expand Down Expand Up @@ -91,11 +100,7 @@ function handleFocus(event: FocusEvent) {
}
function handleBlur(event: FocusEvent) {
const target = event.target as HTMLInputElement
nextTick(() => {
if (!target.value)
target.placeholder = context.placeholder.value
})
resetPlaceholder()
}
function handlePaste(event: ClipboardEvent) {
Expand Down Expand Up @@ -142,6 +147,12 @@ function updateModelValueAt(index: number, value: string) {
context.modelValue.value = removeTrailingEmptyStrings(tempModelValue)
}
watch(currentValue, () => {
if (!currentValue.value) {
resetPlaceholder()
}
})
onMounted(() => {
context.onInputElementChange(currentElement.value as HTMLInputElement)
})
Expand All @@ -161,7 +172,7 @@ onUnmounted(() => {
:inputmode="isNumericMode ? 'numeric' : 'text'"
:pattern="isNumericMode ? '[0-9]*' : undefined"
:placeholder="context.placeholder.value"
:value="context.modelValue.value[index]"
:value="currentValue"
:disabled="disabled"
:data-disabled="disabled ? '' : undefined"
:data-complete="context.isCompleted.value ? '' : undefined"
Expand Down
5 changes: 5 additions & 0 deletions packages/radix-vue/src/PinInput/story/_PinInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const value = ref<string[]>([])
<PinInputRoot
v-bind="{ ...props, ...useEmitAsProps(emits) }"
v-model="value"
placeholder="*"
class="flex gap-2 items-center"
>
<PinInputInput
Expand All @@ -24,4 +25,8 @@ const value = ref<string[]>([])
:index="index"
/>
</PinInputRoot>

<button @click="value = []">
Reset value
</button>
</template>

0 comments on commit 2ff8ffe

Please sign in to comment.