FodLoadingCircular
Documentație pentru componenta FodLoadingCircular
1. Descriere Generală
FodLoadingCircular
este o componentă de încărcare circulară care afișează progresul sau o animație de așteptare. Suportă atât modul determinate (cu valoare specifică) cât și indeterminate (animație continuă).
Caracteristici principale: - Indicator circular SVG - Mod determinate cu procent - Mod indeterminate cu animație - Dimensiuni multiple (Small, Medium, Large) - Culori din tema aplicației - Grosime ajustabilă - Performanță optimizată - Accesibilitate cu ARIA
2. Utilizare de Bază
Loading indeterminate
<FodLoadingCircular Indeterminate="true" />
Loading cu progres
<FodLoadingCircular Value="@progress"
Min="0"
Max="100" />
@code {
private double progress = 45;
}
Loading colorat și dimensionat
<FodLoadingCircular Indeterminate="true"
FodColor="FodColor.Primary"
FodSize="FodSize.Large" />
3. Parametri
Proprietate | Tip | Descriere | Valoare Implicită |
---|---|---|---|
FodColor |
FodColor |
Culoarea componentei | FodColor.Default |
FodSize |
FodSize |
Dimensiunea (Small, Medium, Large) | FodSize.Medium |
Indeterminate |
bool |
Animație continuă fără valoare | false |
Value |
double |
Valoarea curentă a progresului | 0 |
Min |
double |
Valoarea minimă | 0 |
Max |
double |
Valoarea maximă | 100 |
StrokeWidth |
int |
Grosimea liniei cercului | 3 |
4. Exemple Avansate
Loading cu progres și text
<div class="text-center">
<FodLoadingCircular Value="@uploadProgress"
FodColor="FodColor.Primary"
FodSize="FodSize.Large" />
<FodText Typo="Typo.caption" Class="mt-2">
@($"{uploadProgress:F0}% încărcat")
</FodText>
</div>
@code {
private double uploadProgress = 0;
protected override async Task OnInitializedAsync()
{
// Simulare încărcare
while (uploadProgress < 100)
{
await Task.Delay(100);
uploadProgress += Random.Shared.Next(1, 10);
StateHasChanged();
}
}
}
Loading în buton
<FodButton Disabled="@isLoading"
Color="FodColor.Primary">
@if (isLoading)
{
<FodLoadingCircular Indeterminate="true"
FodSize="FodSize.Small"
FodColor="FodColor.Inherit"
Class="me-2" />
}
@buttonText
</FodButton>
@code {
private bool isLoading = false;
private string buttonText = "Salvează";
private async Task Save()
{
isLoading = true;
buttonText = "Se salvează...";
await SaveDataAsync();
isLoading = false;
buttonText = "Salvează";
}
}
Loading overlay
<div class="position-relative">
<FodCard>
<FodCardContent>
<!-- Conținut card -->
</FodCardContent>
</FodCard>
@if (isLoadingData)
{
<div class="loading-overlay">
<FodLoadingCircular Indeterminate="true"
FodColor="FodColor.Primary"
FodSize="FodSize.Large" />
</div>
}
</div>
<style>
.loading-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.8);
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
}
</style>
Loading cu etape multiple
<div class="d-flex flex-column align-items-center">
@foreach (var step in loadingSteps)
{
<div class="d-flex align-items-center mb-2">
@if (step.IsCompleted)
{
<FodIcon Icon="@FodIcons.Material.Filled.CheckCircle"
Color="FodColor.Success" />
}
else if (step.IsActive)
{
<FodLoadingCircular Indeterminate="true"
FodSize="FodSize.Small"
FodColor="FodColor.Primary" />
}
else
{
<FodIcon Icon="@FodIcons.Material.Outlined.Circle"
Color="FodColor.Disabled" />
}
<FodText Class="ms-2">@step.Name</FodText>
</div>
}
</div>
@code {
private List<LoadingStep> loadingSteps = new()
{
new() { Name = "Validare date", IsActive = true },
new() { Name = "Procesare cerere" },
new() { Name = "Generare documente" },
new() { Name = "Finalizare" }
};
public class LoadingStep
{
public string Name { get; set; }
public bool IsActive { get; set; }
public bool IsCompleted { get; set; }
}
}
Progress circular pentru statistici
<div class="d-flex justify-content-around">
@foreach (var stat in statistics)
{
<div class="text-center">
<div class="position-relative d-inline-block">
<FodLoadingCircular Value="@stat.Value"
Max="@stat.Max"
FodColor="@stat.Color"
StrokeWidth="5" />
<div class="position-absolute top-50 start-50 translate-middle">
<FodText Typo="Typo.h6">@stat.Value</FodText>
</div>
</div>
<FodText Typo="Typo.caption" Class="mt-2">
@stat.Label
</FodText>
</div>
}
</div>
@code {
private List<Statistic> statistics = new()
{
new() { Label = "Completate", Value = 75, Max = 100, Color = FodColor.Success },
new() { Label = "În lucru", Value = 15, Max = 100, Color = FodColor.Warning },
new() { Label = "Respinse", Value = 10, Max = 100, Color = FodColor.Error }
};
public class Statistic
{
public string Label { get; set; }
public double Value { get; set; }
public double Max { get; set; }
public FodColor Color { get; set; }
}
}
5. Stilizare și Dimensiuni
Dimensiuni predefinite
<div class="d-flex gap-3 align-items-center">
<div>
<FodLoadingCircular Indeterminate="true" FodSize="FodSize.Small" />
<FodText Typo="Typo.caption">Small</FodText>
</div>
<div>
<FodLoadingCircular Indeterminate="true" FodSize="FodSize.Medium" />
<FodText Typo="Typo.caption">Medium</FodText>
</div>
<div>
<FodLoadingCircular Indeterminate="true" FodSize="FodSize.Large" />
<FodText Typo="Typo.caption">Large</FodText>
</div>
</div>
Culori disponibile
<div class="d-flex flex-wrap gap-3">
@foreach (FodColor color in Enum.GetValues<FodColor>())
{
<div class="text-center">
<FodLoadingCircular Indeterminate="true"
FodColor="@color" />
<FodText Typo="Typo.caption">@color</FodText>
</div>
}
</div>
6. Stilizare CSS Personalizată
/* Loading cu dimensiune custom */
.custom-loading .fod-progress-circular {
width: 100px !important;
height: 100px !important;
}
/* Animație personalizată */
.smooth-loading .fod-progress-circular-circle {
transition: stroke-dashoffset 0.5s ease-in-out;
}
/* Loading cu fundal */
.loading-with-bg {
background: rgba(0, 0, 0, 0.05);
border-radius: 50%;
padding: 10px;
}
/* Pulsație pentru indeterminate */
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.pulsing-loader .fod-progress-circular {
animation: pulse 2s ease-in-out infinite;
}
7. Integrare cu componente
În DataTable
<FodDataTable Items="@items" T="Item">
@if (isLoadingData)
{
<LoadingContent>
<div class="text-center p-4">
<FodLoadingCircular Indeterminate="true"
FodColor="FodColor.Primary" />
<FodText Class="mt-2">Se încarcă datele...</FodText>
</div>
</LoadingContent>
}
<!-- Coloane -->
</FodDataTable>
În Card
<FodCard>
<FodCardContent>
@if (isProcessing)
{
<div class="d-flex align-items-center">
<FodLoadingCircular Indeterminate="true"
FodSize="FodSize.Small"
Class="me-3" />
<div>
<FodText>Procesare în curs...</FodText>
<FodText Typo="Typo.caption" Color="FodColor.Secondary">
Acest proces poate dura câteva minute
</FodText>
</div>
</div>
}
</FodCardContent>
</FodCard>
8. Best Practices
- Feedback clar - Folosiți text descriptiv împreună cu loader
- Dimensiune adecvată - Adaptați dimensiunea la context
- Culori consistente - Folosiți culori din tema aplicației
- Indeterminate vs Determinate - Folosiți determinate când știți progresul
- Poziționare - Centrați în containerul părinte
- Overlay - Pentru încărcare full-screen folosiți overlay
9. Performanță
- SVG este optimizat pentru performanță
- Animația CSS nu blochează thread-ul principal
- Re-render doar la schimbarea valorii
- Folosiți
Indeterminate
pentru animație continuă
10. Accesibilitate
- Atribut
role="progressbar"
inclus aria-valuenow
actualizat automat- Compatibil cu screen readers
- Contrast adecvat pentru culori
11. Troubleshooting
Animația nu funcționează
- Verificați că
Indeterminate="true"
- Verificați că CSS-ul este încărcat
- Verificați consolă pentru erori JS
Valoarea nu se actualizează
- Verificați că Value este între Min și Max
- Verificați că StateHasChanged este apelat
- Folosiți @bind-Value pentru two-way binding
Dimensiunea nu se schimbă
- Verificați că FodSize este setat corect
- Verificați că nu există CSS care suprascrie
- Folosiți Class pentru dimensiuni custom
12. Concluzie
FodLoadingCircular
oferă o soluție elegantă și flexibilă pentru indicarea stării de încărcare în aplicațiile FOD. Cu suport pentru progres determinat și animație continuă, componenta se integrează perfect în orice context de UI.