Mobile Input
Working on the MVP for a mobile-first web application, I had to review the interaction mode with forms. On the desktop you usually just hop from one field to the other, but on mobile I've found that many applications use to open a dedicated overlay each time a field is activated for editing. In particular, examining the "Profile" panel of the Instagram app, it seems that this happens when triggering the "focus" event of each attribute.
So I've put together an essential Svelte component displaying a normal input text element and, on focus, a full-screen panel sporting the proper input field (or a textarea, when required) and, optionally, an inline help text.
<script>
let { label, id, value, type = 'text', help = '' } = $props();
let opened = $state(false);
let modalValue = $state('');
function openLargeInput()
{
opened = true;
modalValue = value;
}
function saveLargeInput()
{
opened = false;
value = modalValue;
}
function init(el)
{
/*
To focus the actual field when the overlay panel is opened
*/
el.focus();
}
</script>
<div class="form-floating mb-3">
<input type="text" class="form-control" id={id} placeholder={label} bind:value={value} onfocus={() => openLargeInput()}>
<label for={id} class="form-label">{label}</label>
</div>
{#if opened}
<div class="large-input-overlay">
<div class="d-flex justify-content-between mb-2">
<!-- Button to cancel or confirm the changes -->
<button title="Cancel" class="btn btn-light" onclick={() => opened = false}><i class="bi bi-x-circle-fill text-danger"></i></button>
<button title="Save" class="btn btn-light" onclick={() => saveLargeInput()}><i class="bi bi-x-circle-fill text-success"></i></button>
</div>
<div class="mb-3">
<label for={'actual-' + id} class="form-label">{label}</label>
{#if type == 'textarea'}
<textarea class="form-control" id={'actual-' + id} rows="5" bind:value={modalValue} use:init>{modalValue}</textarea>
{:else}
<input type={type} class="form-control" id={'actual-' + id} bind:value={modalValue} use:init />
{/if}
</div>
<!-- Optionally, it is possible to display some instruction about the field in the overlay -->
{#if help != ''}
<div class="alert alert-dark">
{help}
</div>
{/if}
</div>
{/if}And in global CSS - extending, as usual, Bootstrap - I've defined the style for the full-screen panel.
.large-input-overlay {
background-color: #FFF;
position: absolute;
top: 0;
left: 0;
right: 0;
height: 100dvh;
z-index: 100;
padding: 20px;
}Then, usage is something like:
<LargeInput label="Name" id="name" value={user.name} help="Write here your name. It is your public name." />
<LargeInput label="Phone" id="phone" value={user.phone} help="Your phone number will not be displayed in public." type="tel" />Using this approach, the whole panel appears to be less crowded (as help texts are displayed only when actually required) and more compact (as textareas, or other large widgets, are used only when editing), and interaction on small screen is more predictable (as the active input field always appears on top of the smarphone screen).
In this MVP I've still to deal with actul saving of informations, and sooner or later I expect to implement something more in the saveLargeInput() function. But this is a different story...
Good artists copy; great artists steal.