add slider range filter

This commit is contained in:
Maxime Adler
2025-03-12 16:10:29 +01:00
parent 34a2e80ffb
commit a21827d146
8 changed files with 217 additions and 12 deletions

View File

@@ -1,5 +1,7 @@
@using GameIdeas.BlazorApp.Shared.Components.Search @using GameIdeas.BlazorApp.Shared.Components.Search
@using GameIdeas.BlazorApp.Shared.Components.Select @using GameIdeas.BlazorApp.Shared.Components.Select
@using GameIdeas.BlazorApp.Shared.Components.Select.Models
@using GameIdeas.BlazorApp.Shared.Components.SliderRange
@using GameIdeas.Shared.Dto @using GameIdeas.Shared.Dto
@using GameIdeas.BlazorApp.Pages.Games.Models @using GameIdeas.BlazorApp.Pages.Games.Models
@@ -33,20 +35,29 @@
</svg> </svg>
</div> </div>
<div class="search-container">
<SearchInput @bind-Text=GameFilterParams.SearchName /> <SearchInput @bind-Text=GameFilterParams.SearchName />
</div>
<div class="select-container">
<MultipleSelectList TItem="string" <MultipleSelectList TItem="string"
Items="Plateforms" Items="Plateforms"
@bind-Values=GameFilterParams.Plateforms @bind-Values=GameFilterParams.Plateforms
Theme="SelectListTheme.Filter"/> Theme="SelectListTheme.Filter" />
</div>
<div class="select-container">
<MultipleSelectList TItem="string" <MultipleSelectList TItem="string"
Items="Genres" Items="Genres"
@bind-Values=GameFilterParams.Genres @bind-Values=GameFilterParams.Genres
Theme="SelectListTheme.Filter" /> Theme="SelectListTheme.Filter" />
</div>
<div class="slider-container">
<SliderRange Params="SliderRangeParams"
@bind-Max=GameFilterParams.MaxRating
@bind-Min=GameFilterParams.MinRating />
</div>
</div> </div>
</EditForm> </EditForm>

View File

@@ -1,5 +1,6 @@
using GameIdeas.BlazorApp.Pages.Games.Models; using GameIdeas.BlazorApp.Pages.Games.Models;
using GameIdeas.BlazorApp.Shared.Components.Select.Models; using GameIdeas.BlazorApp.Shared.Components.Select.Models;
using GameIdeas.BlazorApp.Shared.Components.SliderRange;
using GameIdeas.Shared.Dto; using GameIdeas.Shared.Dto;
using GameIdeas.Shared.Enum; using GameIdeas.Shared.Enum;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@@ -39,6 +40,8 @@ public partial class GameFilter
]; ];
private EditContext? EditContext; private EditContext? EditContext;
private SliderRangeParams SliderRangeParams =
new() { Min = 1, ValueMin = 1, ValueMax = 5, Max = 5 };
protected override void OnInitialized() protected override void OnInitialized()
{ {

View File

@@ -2,11 +2,29 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
gap: 8px; gap: 8px;
align-items: center;
}
.search-container {
width: 150px;
min-width: 150px;
}
.slider-container {
width: 150px;
min-width: 150px;
}
.select-container {
width: 150px;
min-width: 150px;
} }
.square-button { .square-button {
height: 28px; height: 28px;
min-height: 28px;
width: 28px; width: 28px;
min-width: 28px;
border-radius: var(--small-radius); border-radius: var(--small-radius);
background: var(--black); background: var(--black);
overflow: hidden; overflow: hidden;
@@ -43,3 +61,9 @@
padding-top: 1px; padding-top: 1px;
padding-right: 1px; padding-right: 1px;
} }
@media screen and (max-width: 1000px) {
.select-container {
display: none;
}
}

View File

@@ -10,5 +10,6 @@ public class GameFilterParams
public string? SearchName { get; set; } public string? SearchName { get; set; }
public IEnumerable<string>? Plateforms { get; set; } public IEnumerable<string>? Plateforms { get; set; }
public IEnumerable<string>? Genres { get; set; } public IEnumerable<string>? Genres { get; set; }
public int MaxRating { get; set; }
public int MinRating { get; set; }
} }

View File

@@ -0,0 +1,13 @@
<div class="container">
<div class="slider-track" style="@FillColor()"></div>
<input type="range" id="min-range" style="@StatusColor(Params.ValueMin)" min="@Params.Min" max="@Params.Max"
@bind="@Params.ValueMin" @bind:event="oninput" @bind:after=HandleSlideOnInput />
<input type="range" id="max-range" style="@StatusColor(Params.ValueMax)" min="@Params.Min" max="@Params.Max"
@bind="@Params.ValueMax" @bind:event="oninput" @bind:after=HandleSlideTwoInput />
<div class="values">
<span class="value">@Params.ValueMin</span>
<span class="value">@Params.ValueMax</span>
</div>
</div>

View File

@@ -0,0 +1,57 @@
using Microsoft.AspNetCore.Components;
using System.Threading.Tasks;
namespace GameIdeas.BlazorApp.Shared.Components.SliderRange;
public partial class SliderRange
{
[Parameter] public SliderRangeParams Params { get; set; } = new();
[Parameter] public int Max { get; set; }
[Parameter] public EventCallback<int> MaxChanged { get; set; }
[Parameter] public int Min { get; set; }
[Parameter] public EventCallback<int> MinChanged { get; set; }
private async Task HandleSlideTwoInput()
{
if (Params.ValueMax - Params.ValueMin <= Params.Gap)
{
Params.ValueMin = Params.ValueMax - Params.Gap;
}
Max = Params.Max;
await MaxChanged.InvokeAsync(Params.Max);
}
private async Task HandleSlideOnInput()
{
if (Params.ValueMax - Params.ValueMin <= Params.Gap)
{
Params.ValueMax = Params.ValueMin + Params.Gap;
}
Min = Params.Min;
await MinChanged.InvokeAsync(Params.Min);
}
private string FillColor()
{
var percent1 = (double)(Params.ValueMin - Params.Min) / (Params.Max - Params.Min) * 100;
var percent2 = (double)(Params.ValueMax - Params.Min) / (Params.Max - Params.Min) * 100;
return $"background: linear-gradient(to right, var(--light-grey) {percent1}% , var(--violet) {percent1}% , var(--violet) {percent2}%, var(--light-grey) {percent2}%)";
}
private string StatusColor(int value)
{
string str = "--thumb-color: var({0});";
int firstTier = (int)Math.Floor(0.33 * Params.Max);
int secondTier = (int)Math.Ceiling(0.66 * Params.Max);
return value switch
{
int x when x <= firstTier => string.Format(str, "--red"),
int x when x >= secondTier => string.Format(str, "--green"),
_ => string.Format(str, "--yellow"),
};
}
}

View File

@@ -0,0 +1,86 @@
.container {
position: relative;
width: 100%;
}
input[type="range"] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: 100%;
outline: none;
margin: auto;
position: absolute;
top: 0;
bottom: 0;
background-color: transparent;
pointer-events: none;
}
.slider-track {
width: 100%;
height: 2px;
margin: auto;
border-radius: 2px;
}
input[type="range"]::-webkit-slider-runnable-track {
-webkit-appearance: none;
height: 2px;
}
input[type="range"]::-moz-range-track {
-moz-appearance: none;
height: 2px;
}
input[type="range"]::-ms-track {
appearance: none;
height: 2px;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
height: 1em;
width: 1em;
background-color: var(--thumb-color);
cursor: pointer;
margin-top: -6px;
pointer-events: auto;
border-radius: 50%;
}
input[type="range"]::-moz-range-thumb {
-webkit-appearance: none;
height: 1em;
width: 1em;
cursor: pointer;
border-radius: 50%;
background-color: var(--thumb-color);
pointer-events: auto;
border: none;
}
input[type="range"]::-ms-thumb {
appearance: none;
height: 1em;
width: 1em;
cursor: pointer;
border-radius: 50%;
background-color: var(--thumb-color);
pointer-events: auto;
}
.values {
display: flex;
position: absolute;
margin-top: 10px;
width: 100%;
font-weight: bold;
justify-content: space-between;
}
.value {
width: 1em;
text-align:center;
}

View File

@@ -0,0 +1,10 @@
namespace GameIdeas.BlazorApp.Shared.Components.SliderRange;
public class SliderRangeParams
{
public int Min{ get; set; }
public int Max { get; set; }
public int ValueMin { get; set; }
public int ValueMax { get; set; }
public int Gap { get; set; } = 0;
}