Para resumir o problema das entradas de data:
- Você deve exibi-los (ou seja, evitar display: none), caso contrário, a IU de entrada não será acionada;
- um espaço reservado é contraditório com eles (de acordo com as especificações e porque eles precisam exibir uma IU específica);
- convertê-los para outro tipo de entrada para o tempo desfocado permite espaços reservados, mas o foco então aciona a IU de entrada incorreta (teclado), pelo menos por um curto período, porque os eventos de foco não podem ser cancelados.
- inserir (antes) ou adicionar (depois) conteúdo não impede que o valor de entrada de data seja exibido.
A solução que encontrei para atender a esses requisitos é usar o truque usual para estilizar os elementos nativos do formulário: garantir que o elemento seja exibido, mas não visível, e exibir seu estilo esperado por meio de seu rótulo associado . Normalmente, o rótulo é exibido como entrada (incluindo um espaço reservado), mas sobre ele.
Portanto, um HTML como:
<div class="date-input>
<input id="myInput" type="date">
<label for="myInput">
<span class="place-holder">Enter a date</span>
</label>
</div>
Pode ser denominado como:
.date-input {
display: inline-block;
position: relative;
}
/* Fields overriding */
input[type=date] + label {
position: absolute; /* Same origin as the input, to display over it */
background: white; /* Opaque background to hide the input behind */
left: 0; /* Start at same x coordinate */
}
/* Common input styling */
input[type=date], label {
/* Must share same size to display properly (focus, etc.) */
width: 15em;
height: 1em;
font-size: 1em;
}
Qualquer evento (clique, foco) em um rótulo associado será refletido no próprio campo e, portanto, acionará a IU de entrada de data.
Se você quiser testar essa solução ao vivo, pode executar esta versão Angular em seu tablet ou celular.