diff --git a/src/components/DatePicker.spec.ts b/src/components/DatePicker.spec.ts index 0f52bff..cee6677 100644 --- a/src/components/DatePicker.spec.ts +++ b/src/components/DatePicker.spec.ts @@ -58,3 +58,30 @@ describe('DatePicker', () => { expect(mountPicker(null, '开始日期').find('input').attributes('aria-label')).toBe('开始日期') }) }) + +describe('DatePicker 空值占位', () => { + it('空值时显示自定义占位文案', () => { + expect(mountPicker(null).text()).toContain('选择日期') + }) + + it('有值时不再显示占位文案', () => { + expect(mountPicker('2026-10-20').text()).not.toContain('选择日期') + }) + + it('空值时遮住浏览器自带的格式提示(yyyy/mm/日)', () => { + const classes = mountPicker(null).find('input').classes().join(' ') + expect(classes).toContain('::-webkit-datetime-edit') + // 只在未聚焦时透明,否则聚焦后看不见正在编辑的数字 + expect(classes).toContain(':not(:focus)') + }) + + it('有值时不做任何遮挡', () => { + const classes = mountPicker('2026-10-20').find('input').classes().join(' ') + expect(classes).not.toContain('::-webkit-datetime-edit') + }) + + it('占位层不拦截鼠标事件(点击仍能唤起原生选择器)', () => { + const placeholder = mountPicker(null).find('span') + expect(placeholder.classes()).toContain('pointer-events-none') + }) +}) diff --git a/src/components/DatePicker.vue b/src/components/DatePicker.vue index eef8134..fbff563 100644 --- a/src/components/DatePicker.vue +++ b/src/components/DatePicker.vue @@ -6,9 +6,13 @@ * - 其 value 规范就是 YYYY-MM-DD,与 ADR-003 的存储约定天然一致 * - 自带可访问性、键盘操作与本地化日历,无需自己实现 * - 深色模式下日历弹层跟随 html 的 color-scheme + * + * 空值时刻意遮住原生占位文字:Chrome 会按页面 lang 拼出「yyyy/mm/日」 + * 这种半英半中的提示,既别扭又容易被误读成已有内容。改为显示自己的 + * 「选择日期」,聚焦时再让位给原生分段输入(否则编辑时看不见数字)。 */ -defineProps<{ modelValue: string | null; label?: string }>() +const props = defineProps<{ modelValue: string | null; label?: string }>() const emit = defineEmits<{ 'update:modelValue': [value: string | null] }>() @@ -16,17 +20,37 @@ function onChange(event: Event): void { const value = (event.target as HTMLInputElement).value emit('update:modelValue', value === '' ? null : value) } + +/** 空值且未聚焦时才遮住原生占位文字 */ +function hideNativePlaceholder(): boolean { + return props.modelValue === null +}