Refactor receiver list UI and improve accessibility

Reorganized the receiver list in `CreateEnvelopeWizardPopup.razor`:
- Separated "existing receivers" and "new receiver" input rows.
- Added editable fields for `FullName` and `EmailAddress` with real-time updates.
- Introduced "Remove" and "Add Receiver" buttons with updated icons and accessibility attributes.

Updated `sender-page.css`:
- Styled `.sender-create-wizard__receiver-existing-list` for better usability and responsiveness.
- Improved button designs with hover effects and consistent sizing.
- Simplified layout and removed redundant styles.

Enhanced responsiveness and accessibility:
- Made receiver list scrollable and visually distinct.
- Improved localization support with updated titles and `aria-labels`.

Removed redundant code to streamline implementation.
This commit is contained in:
2026-11-10 09:41:38 +01:00
parent 25c03b350b
commit 858b748e65
2 changed files with 81 additions and 81 deletions

View File

@@ -282,73 +282,74 @@
<div class="sender-create-wizard__receiver-tagbox-wrap">
<div class="sender-create-wizard__receiver-list" role="table" aria-label="Added receivers">
@for (var i = 0; i < _receivers.Count; i++)
{
var rowIndex = i;
var receiver = _receivers[rowIndex];
<div class="sender-create-wizard__receiver-existing-list">
@for (var i = 0; i < _receivers.Count; i++)
{
var rowIndex = i;
var receiver = _receivers[rowIndex];
<div class="sender-create-wizard__receiver-row" role="row">
<div class="sender-create-wizard__receiver-row" role="row">
<div class="sender-create-wizard__receiver-fields-stack sender-create-wizard__field--full">
<div class="sender-create-wizard__field">
<DxTextBox Text="@receiver.FullName"
TextChanged="@(value => OnReceiverListNameChanged(rowIndex, value))"
BindValueMode="BindValueMode.OnInput"
NullText='@L("FullName", "Vor- und Nachname")'
CssClass="w-100"
Enabled="@(!IsActionLocked)" />
</div>
<div class="sender-create-wizard__field">
<DxTextBox Text="@receiver.EmailAddress"
TextChanged="@(value => OnReceiverListEmailChanged(rowIndex, value))"
BindValueMode="BindValueMode.OnInput"
NullText='@L("EmailAddress", "E-Mail-Adresse")'
CssClass="w-100"
Enabled="@(!IsActionLocked)" />
</div>
</div>
<button type="button"
class="sender-create-wizard__receiver-remove-btn"
@onclick="() => RemoveReceiver(receiver)"
disabled="@IsActionLocked"
title='@L("Remove", "Entfernen")'
aria-label='@L("Remove", "Entfernen")'>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
<path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
</svg>
</button>
</div>
}
<div class="sender-create-wizard__receiver-row sender-create-wizard__receiver-row--new" role="row">
<div class="sender-create-wizard__receiver-fields-stack sender-create-wizard__field--full">
<div class="sender-create-wizard__field">
<DxTextBox Text="@receiver.FullName"
TextChanged="@(value => OnReceiverListNameChanged(rowIndex, value))"
<DxTextBox Text="@_receiverName"
TextChanged="OnReceiverNameChanged"
BindValueMode="BindValueMode.OnInput"
NullText='@L("FullName", "Vor- und Nachname")'
NullText="Max Mustermann"
CssClass="w-100"
Enabled="@(!IsActionLocked)" />
</div>
<div class="sender-create-wizard__field">
<DxTextBox Text="@receiver.EmailAddress"
TextChanged="@(value => OnReceiverListEmailChanged(rowIndex, value))"
<DxTextBox Text="@_receiverEmail"
TextChanged="OnReceiverEmailChanged"
BindValueMode="BindValueMode.OnInput"
NullText='@L("EmailAddress", "E-Mail-Adresse")'
NullText="name@beispiel.de"
CssClass="w-100"
Enabled="@(!IsActionLocked)" />
</div>
</div>
<button type="button"
class="sender-create-wizard__receiver-remove-btn"
@onclick="() => RemoveReceiver(receiver)"
class="sender-create-wizard__receiver-add-inline-btn"
@onclick="AddReceiver"
disabled="@IsActionLocked"
title='@L("Remove", "Entfernen")'
aria-label='@L("Remove", "Entfernen")'>
title='@L("AddReceiver", "Empfänger hinzufügen")'
aria-label='@L("AddReceiver", "Empfänger hinzufügen")'>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
<path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
<path d="M8 1a.5.5 0 0 1 .5.5V7.5h6a.5.5 0 0 1 0 1h-6v6a.5.5 0 0 1-1 0v-6h-6a.5.5 0 0 1 0-1h6v-6A.5.5 0 0 1 8 1z" />
</svg>
</button>
</div>
}
<div class="sender-create-wizard__receiver-row" role="row">
<div class="sender-create-wizard__receiver-fields-stack sender-create-wizard__field--full">
<div class="sender-create-wizard__field">
<DxTextBox Text="@_receiverName"
TextChanged="OnReceiverNameChanged"
BindValueMode="BindValueMode.OnInput"
NullText="Max Mustermann"
CssClass="w-100"
Enabled="@(!IsActionLocked)" />
</div>
<div class="sender-create-wizard__field">
<DxTextBox Text="@_receiverEmail"
TextChanged="OnReceiverEmailChanged"
BindValueMode="BindValueMode.OnInput"
NullText="name@beispiel.de"
CssClass="w-100"
Enabled="@(!IsActionLocked)" />
</div>
</div>
<button type="button"
class="sender-create-wizard__receiver-add-inline-btn"
@onclick="AddReceiver"
disabled="@IsActionLocked"
title='@L("AddReceiver", "Empfänger hinzufügen")'
aria-label='@L("AddReceiver", "Empfänger hinzufügen")'>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
<path d="M8 1a.5.5 0 0 1 .5.5V7.5h6a.5.5 0 0 1 0 1h-6v6a.5.5 0 0 1-1 0v-6h-6a.5.5 0 0 1 0-1h6v-6A.5.5 0 0 1 8 1z" />
</svg>
</button>
</div>
</div>
</div>

View File

@@ -1502,6 +1502,21 @@
gap: 0.5rem;
}
.sender-create-wizard__receiver-existing-list {
display: flex;
flex-direction: column;
gap: 0.5rem;
max-height: min(24vh, 220px);
overflow-y: auto;
overflow-x: hidden;
scrollbar-gutter: stable;
padding-right: 0.2rem;
}
.sender-create-wizard__receiver-existing-list > .sender-create-wizard__receiver-row--new {
flex: 0 0 auto;
}
.sender-create-wizard__receiver-row {
display: flex;
align-items: flex-start;
@@ -1555,54 +1570,37 @@
.sender-create-wizard__receiver-remove-btn {
flex: 0 0 auto;
width: 2rem;
height: 2rem;
width: auto;
height: auto;
align-self: stretch;
aspect-ratio: 1 / 1;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid rgba(220, 38, 38, 0.2);
border-radius: 6px;
background: transparent;
color: #b91c1c;
padding: 0;
line-height: 1;
}
.sender-create-wizard__receiver-remove-btn:hover:not(:disabled) {
background: rgba(220, 38, 38, 0.08);
}
.sender-create-wizard__receiver-remove-btn:disabled {
opacity: 0.55;
cursor: not-allowed;
}
.sender-create-wizard__receiver-item--new {
border-style: dashed;
}
.sender-create-wizard__receiver-remove-btn:hover {
transform: scale(1.05);
}
.sender-create-wizard__receiver-add-inline-btn {
flex: 0 0 auto;
width: 2rem;
height: 2rem;
width: auto;
height: auto;
align-self: stretch;
aspect-ratio: 1 / 1;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid rgba(14, 116, 144, 0.25);
border-radius: 6px;
background: rgba(236, 254, 255, 0.95);
background: transparent;
color: #0f766e;
padding: 0;
line-height: 1;
}
.sender-create-wizard__receiver-add-inline-btn:hover:not(:disabled) {
background: rgba(207, 250, 254, 1);
}
.sender-create-wizard__receiver-add-inline-btn:disabled {
opacity: 0.55;
cursor: not-allowed;
transition: transform 0.2s ease;
}
.sender-create-wizard__upload-stage {
@@ -1776,6 +1774,10 @@
align-items: stretch;
}
.sender-create-wizard__receiver-existing-list {
max-height: min(20vh, 180px);
}
.sender-create-wizard__receiver-fields-stack {
grid-template-columns: 1fr;
}
@@ -1785,13 +1787,10 @@
}
.sender-create-wizard__receiver-remove-btn {
width: auto;
align-self: flex-end;
}
.sender-create-wizard__receiver-add-inline-btn {
width: auto;
min-width: 2rem;
align-self: flex-end;
}