FodLoadingLinear
Documentație pentru componenta FodLoadingLinear
1. Descriere Generală
FodLoadingLinear
este o componentă de încărcare liniară (progress bar) care afișează progresul într-o bară orizontală sau verticală. Suportă moduri determinate, indeterminate și buffer, cu opțiuni pentru stilizare avansată.
Caracteristici principale: - Bară de progres orizontală/verticală - Mod determinate cu procent - Mod indeterminate cu animație - Mod buffer pentru încărcare în două etape - Striații opționale - Colțuri rotunjite opționale - Dimensiuni multiple - Conținut personalizat - Suport RTL
2. Utilizare de Bază
Progress simplu
<FodLoadingLinear Value="@progress" />
@code {
private double progress = 35;
}
Loading indeterminate
<FodLoadingLinear Indeterminate="true"
FodColor="FodColor.Primary" />
Progress cu buffer
<FodLoadingLinear Value="@downloadProgress"
BufferValue="@bufferProgress"
Buffer="true" />
@code {
private double downloadProgress = 30;
private double bufferProgress = 50;
}
3. Parametri
Proprietate | Tip | Descriere | Valoare Implicită |
---|---|---|---|
FodColor |
FodColor |
Culoarea componentei | FodColor.Default |
FodSize |
FodSize |
Dimensiunea barei | FodSize.Small |
Indeterminate |
bool |
Animație continuă | false |
Buffer |
bool |
Activează modul buffer | false |
Rounded |
bool |
Colțuri rotunjite | false |
Striped |
bool |
Adaugă striații | false |
Vertical |
bool |
Orientare verticală | false |
Value |
double |
Valoarea progresului | 0 |
BufferValue |
double |
Valoarea buffer | 0 |
Min |
double |
Valoare minimă | 0 |
Max |
double |
Valoare maximă | 100 |
ChildContent |
RenderFragment |
Conținut personalizat | - |
4. Exemple Avansate
Progress cu text și procent
<div class="position-relative">
<FodLoadingLinear Value="@uploadProgress"
FodColor="FodColor.Success"
FodSize="FodSize.Medium"
Rounded="true">
<div class="position-absolute w-100 text-center">
<FodText Typo="Typo.caption" Color="FodColor.Inherit">
@($"{uploadProgress:F0}%")
</FodText>
</div>
</FodLoadingLinear>
</div>
@code {
private double uploadProgress = 67;
}
Multi-step progress
<div class="mb-4">
<div class="d-flex justify-content-between mb-2">
<FodText Typo="Typo.subtitle2">@currentStep.Name</FodText>
<FodText Typo="Typo.caption">
Pasul @currentStepIndex din @totalSteps
</FodText>
</div>
<FodLoadingLinear Value="@overallProgress"
FodColor="FodColor.Primary"
Rounded="true"
Striped="true" />
<div class="mt-2">
<FodLoadingLinear Value="@currentStep.Progress"
FodColor="FodColor.Secondary"
FodSize="FodSize.Small" />
</div>
</div>
@code {
private int currentStepIndex = 2;
private int totalSteps = 5;
private double overallProgress => (currentStepIndex - 1) * 100.0 / totalSteps +
(currentStep.Progress / totalSteps);
private StepInfo currentStep = new()
{
Name = "Procesare date",
Progress = 45
};
public class StepInfo
{
public string Name { get; set; }
public double Progress { get; set; }
}
}
Download cu buffer
<FodCard>
<FodCardContent>
<div class="d-flex align-items-center mb-3">
<FodIcon Icon="@FodIcons.Material.Filled.Download"
Class="me-2" />
<div class="flex-grow-1">
<FodText>document.pdf</FodText>
<FodText Typo="Typo.caption" Color="FodColor.Secondary">
@FormatBytes(downloadedBytes) / @FormatBytes(totalBytes)
</FodText>
</div>
<FodText>@downloadSpeed MB/s</FodText>
</div>
<FodLoadingLinear Value="@downloadPercent"
BufferValue="@bufferPercent"
Buffer="true"
FodColor="FodColor.Info"
Rounded="true" />
</FodCardContent>
</FodCard>
@code {
private long downloadedBytes = 45_000_000;
private long bufferedBytes = 67_000_000;
private long totalBytes = 150_000_000;
private double downloadSpeed = 2.5;
private double downloadPercent => (double)downloadedBytes / totalBytes * 100;
private double bufferPercent => (double)bufferedBytes / totalBytes * 100;
private string FormatBytes(long bytes)
{
return $"{bytes / 1_000_000.0:F1} MB";
}
}
Progress vertical pentru skills
<div class="d-flex gap-4">
@foreach (var skill in skills)
{
<div class="text-center">
<FodText Typo="Typo.caption" Class="mb-2">
@skill.Name
</FodText>
<div style="height: 200px; position: relative;">
<FodLoadingLinear Value="@skill.Level"
FodColor="@skill.Color"
Vertical="true"
Rounded="true"
Class="h-100" />
<div class="position-absolute bottom-0 w-100 text-center pb-2">
<FodText Typo="Typo.caption" Color="FodColor.OnPrimary">
@skill.Level%
</FodText>
</div>
</div>
</div>
}
</div>
@code {
private List<Skill> skills = new()
{
new() { Name = "C#", Level = 90, Color = FodColor.Primary },
new() { Name = "Blazor", Level = 85, Color = FodColor.Secondary },
new() { Name = "SQL", Level = 75, Color = FodColor.Info },
new() { Name = "JavaScript", Level = 70, Color = FodColor.Warning }
};
public class Skill
{
public string Name { get; set; }
public double Level { get; set; }
public FodColor Color { get; set; }
}
}
Loading cu animație customizată
<div class="loading-container">
@if (!isComplete)
{
<FodLoadingLinear @ref="progressBar"
Value="@progress"
FodColor="FodColor.Primary"
FodSize="FodSize.Medium"
Rounded="true"
Striped="@(progress > 50)" />
<div class="d-flex justify-content-between mt-2">
<FodText Typo="Typo.caption">@statusMessage</FodText>
<FodText Typo="Typo.caption">@timeRemaining</FodText>
</div>
}
else
{
<FodAlert Severity="FodSeverity.Success">
Proces finalizat cu succes!
</FodAlert>
}
</div>
@code {
private FodLoadingLinear progressBar;
private double progress = 0;
private bool isComplete = false;
private string statusMessage = "Inițializare...";
private string timeRemaining = "Calculez...";
protected override async Task OnInitializedAsync()
{
await SimulateProgress();
}
private async Task SimulateProgress()
{
var stages = new[]
{
("Conectare la server...", 20),
("Descărcare date...", 40),
("Procesare...", 30),
("Finalizare...", 10)
};
foreach (var (message, duration) in stages)
{
statusMessage = message;
var stageProgress = progress;
var targetProgress = Math.Min(progress + duration, 100);
while (progress < targetProgress)
{
await Task.Delay(100);
progress += 1;
var remaining = (100 - progress) * 0.1;
timeRemaining = $"{remaining:F1} secunde rămase";
StateHasChanged();
}
}
isComplete = true;
StateHasChanged();
}
}
5. Stilizare și Variante
Toate dimensiunile
<div class="space-y-4">
<div>
<FodText Typo="Typo.caption">Small</FodText>
<FodLoadingLinear Value="70" FodSize="FodSize.Small" />
</div>
<div>
<FodText Typo="Typo.caption">Medium</FodText>
<FodLoadingLinear Value="70" FodSize="FodSize.Medium" />
</div>
<div>
<FodText Typo="Typo.caption">Large</FodText>
<FodLoadingLinear Value="70" FodSize="FodSize.Large" />
</div>
</div>
Variante stilizate
<div class="space-y-4">
<FodLoadingLinear Value="60"
FodColor="FodColor.Primary" />
<FodLoadingLinear Value="60"
FodColor="FodColor.Secondary"
Rounded="true" />
<FodLoadingLinear Value="60"
FodColor="FodColor.Success"
Striped="true" />
<FodLoadingLinear Value="60"
FodColor="FodColor.Warning"
Rounded="true"
Striped="true" />
</div>
6. Stilizare CSS Personalizată
/* Progress cu gradient */
.gradient-progress .fod-progress-linear-bar {
background: linear-gradient(90deg,
var(--fod-palette-primary-light) 0%,
var(--fod-palette-primary-dark) 100%);
}
/* Animație pentru striped */
@keyframes progress-striped {
0% { background-position: 0 0; }
100% { background-position: 40px 0; }
}
.animated-stripes .fod-progress-linear-striped .fod-progress-linear-bar {
animation: progress-striped 1s linear infinite;
}
/* Progress cu glow */
.glow-progress .fod-progress-linear-bar {
box-shadow: 0 0 10px var(--fod-palette-primary-main);
}
/* Dimensiune custom */
.thick-progress {
height: 20px !important;
}
.thick-progress .fod-progress-linear-content {
line-height: 20px;
}
7. Integrare cu Formulare
Upload fișiere
<InputFile OnChange="HandleFileSelected" multiple />
@if (uploadingFiles.Any())
{
<div class="mt-3">
@foreach (var file in uploadingFiles)
{
<div class="mb-3">
<div class="d-flex justify-content-between mb-1">
<FodText Typo="Typo.caption">@file.Name</FodText>
<FodText Typo="Typo.caption">@file.Progress%</FodText>
</div>
<FodLoadingLinear Value="@file.Progress"
FodColor="@(file.HasError ? FodColor.Error : FodColor.Primary)"
FodSize="FodSize.Small" />
@if (file.HasError)
{
<FodText Color="FodColor.Error" Typo="Typo.caption">
@file.ErrorMessage
</FodText>
}
</div>
}
</div>
}
@code {
private List<FileUploadInfo> uploadingFiles = new();
private async Task HandleFileSelected(InputFileChangeEventArgs e)
{
foreach (var file in e.GetMultipleFiles())
{
var fileInfo = new FileUploadInfo { Name = file.Name };
uploadingFiles.Add(fileInfo);
_ = UploadFile(file, fileInfo);
}
}
private async Task UploadFile(IBrowserFile file, FileUploadInfo info)
{
try
{
// Simulare upload
while (info.Progress < 100)
{
await Task.Delay(100);
info.Progress += Random.Shared.Next(5, 15);
StateHasChanged();
}
}
catch (Exception ex)
{
info.HasError = true;
info.ErrorMessage = ex.Message;
}
}
}
8. Best Practices
- Feedback vizual - Folosiți culori consistente pentru stări
- Valori clare - Afișați procente sau text descriptiv
- Animații subtile - Nu distrageți utilizatorul
- Buffer pentru streaming - Folosiți pentru date în flux
- Indeterminate pentru necunoscut - Când nu știți durata
- Accesibilitate - Includeți aria labels
9. Performanță
- Animațiile CSS sunt optimizate
- Re-render doar la schimbarea valorilor
- Folosiți
Buffer
doar când e necesar - Evitați actualizări prea frecvente
10. Accesibilitate
- Atribute ARIA incluse automat
role="progressbar"
setataria-valuenow
,aria-valuemin
,aria-valuemax
- Compatibil cu screen readers
11. Troubleshooting
Progress nu se actualizează
- Verificați că Value este între Min și Max
- Apelați StateHasChanged după actualizare
- Verificați că nu există erori în consolă
Animația indeterminate nu merge
- Verificați că Indeterminate="true"
- Verificați că CSS-ul este încărcat corect
Buffer nu apare
- Setați Buffer="true"
- Asigurați-vă că BufferValue > Value
12. Concluzie
FodLoadingLinear
oferă o soluție versatilă pentru afișarea progresului în aplicațiile FOD. Cu multiple moduri de afișare și opțiuni de stilizare, componenta se adaptează perfect la orice context de încărcare sau procesare.