Add D-prefixed Blazor wrappers for every daisyUI 5 component
Components/Daisy/ wraps all 69 components in daisyUI's llms.txt, grouped by daisyUI's categories (Actions, DataDisplay, Navigation, Feedback, DataInput, Layout, Mockup), with part components where daisyUI has repeating parts (DTab, DMenuItem, DTimelineItem, ...). - Each enum maps to whole literal class names in a switch, so Tailwind's scanner generates them. Nothing is concatenated. - Value-holding fields derive from DInputBase<TValue>, Blazor's InputBase, so @bind-Value and EditForm validation work. Invalid fields get the component's *-error class. - Open and active state lives in C# (@bind-IsOpen, @bind-Active) and is rendered with daisyUI's *-open modifiers. DDropdown adds an outside-click layer and Escape. No component uses JS interop. - The one exception is DCalendar, which wraps the Cally web component, vendored as wwwroot/vendor/cally.js (0.9.2, MIT). /styleguide (not linked) renders every component in all its colours, sizes and states, with a theme and hue picker that previews without saving. neo.css follows what the styleguide showed: - select keeps daisyUI's arrow; - skeleton-text isn't sunk; - the phone mockup and dock are raised; - active menu items and OTP digits are inset; - a joined accordion is raised as one block. The primary, secondary and accent colours are deeper, so they still read as text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
8e03d12a3e
commit
90e4b9200c
127 files changed
+6962
-17
No files matched your search
@@ -0,0 +1,380 @@
|
||||
@using System.ComponentModel.DataAnnotations
|
||||
|
||||
@* Styleguide: the Data input components (Input, Select, Textarea, Checkbox, Toggle, Radio, Range, Rating, Filter, OTP,
|
||||
File input, Fieldset, Label, Validator, Calendar). Everything sits in one EditForm with DataAnnotations: submit it
|
||||
empty to see input-error and the validator hints. novalidate leaves the checking to Blazor. *@
|
||||
<EditForm Model="model" OnValidSubmit="() => Submitted(true)" OnInvalidSubmit="() => Submitted(false)" novalidate>
|
||||
<DataAnnotationsValidator />
|
||||
<div class="grid gap-8 lg:grid-cols-2">
|
||||
<section class="flex flex-col gap-3 lg:col-span-2">
|
||||
<h3 class="text-lg font-bold">DInput</h3>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
@foreach (var color in Enum.GetValues<DColor>())
|
||||
{
|
||||
<DInput @bind-Value="text" Color="color" placeholder="@color.ToString()" class="w-36" />
|
||||
}
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<DInput @bind-Value="text" Size="DSize.Xs" placeholder="Xs" class="w-28" />
|
||||
<DInput @bind-Value="text" Size="DSize.Sm" placeholder="Sm" class="w-28" />
|
||||
<DInput @bind-Value="text" placeholder="Md" class="w-28" />
|
||||
<DInput @bind-Value="text" Size="DSize.Lg" placeholder="Lg" class="w-28" />
|
||||
<DInput @bind-Value="text" Size="DSize.Xl" placeholder="Xl" class="w-28" />
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<DInput @bind-Value="text" Ghost="true" placeholder="Ghost" />
|
||||
<DInput @bind-Value="text" disabled placeholder="Disabled" />
|
||||
<DInput @bind-Value="search" Immediate="true" placeholder="Search">
|
||||
<Prefix><i class="ion-md-search opacity-50"></i></Prefix>
|
||||
<Suffix><kbd class="kbd kbd-sm">⌘</kbd><kbd class="kbd kbd-sm">K</kbd></Suffix>
|
||||
</DInput>
|
||||
<DInput @bind-Value="site" Color="DColor.Primary">
|
||||
<Prefix><DLabel>https://</DLabel></Prefix>
|
||||
<Suffix><DLabel>.com</DLabel></Suffix>
|
||||
</DInput>
|
||||
</div>
|
||||
<p class="text-sm opacity-60">Immediate search: "@search", text: "@text"</p>
|
||||
<div class="flex flex-col">
|
||||
<DInput @bind-Value="model.Name" Validator="true" placeholder="Name (required)" class="w-full max-w-xs" />
|
||||
<DValidatorHint>Name is required</DValidatorHint>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="flex flex-col gap-3">
|
||||
<h3 class="text-lg font-bold">DSelect</h3>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
@foreach (var color in Enum.GetValues<DColor>())
|
||||
{
|
||||
<DSelect @bind-Value="language" Color="color" class="w-36">
|
||||
<option value="C#">C# (@color)</option>
|
||||
<option value="F#">F#</option>
|
||||
<option value="TypeScript">TypeScript</option>
|
||||
</DSelect>
|
||||
}
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<DSelect @bind-Value="language" Size="DSize.Xs" class="w-28"><option>C#</option><option>F#</option></DSelect>
|
||||
<DSelect @bind-Value="language" Size="DSize.Sm" class="w-28"><option>C#</option><option>F#</option></DSelect>
|
||||
<DSelect @bind-Value="language" class="w-28"><option>C#</option><option>F#</option></DSelect>
|
||||
<DSelect @bind-Value="language" Size="DSize.Lg" class="w-28"><option>C#</option><option>F#</option></DSelect>
|
||||
<DSelect @bind-Value="language" Size="DSize.Xl" class="w-28"><option>C#</option><option>F#</option></DSelect>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<DSelect @bind-Value="language" Ghost="true" class="w-36"><option>C#</option><option>F#</option></DSelect>
|
||||
<DSelect @bind-Value="language" disabled class="w-36"><option>C#</option><option>F#</option></DSelect>
|
||||
<DSelect @bind-Value="language" class="w-48">
|
||||
<Prefix><DLabel>Type</DLabel></Prefix>
|
||||
<ChildContent><option>C#</option><option>F#</option></ChildContent>
|
||||
</DSelect>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<DSelect @bind-Value="model.Language" Validator="true" class="w-full max-w-xs">
|
||||
<option value="">Pick a language (required)</option>
|
||||
<option>C#</option>
|
||||
<option>F#</option>
|
||||
</DSelect>
|
||||
<DValidatorHint>Pick one</DValidatorHint>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="flex flex-col gap-3">
|
||||
<h3 class="text-lg font-bold">DTextarea</h3>
|
||||
<div class="grid grid-cols-3 gap-2">
|
||||
@foreach (var color in Enum.GetValues<DColor>())
|
||||
{
|
||||
<DTextarea @bind-Value="bio" Color="color" placeholder="@color.ToString()" class="min-h-0 h-12" />
|
||||
}
|
||||
</div>
|
||||
<div class="flex flex-wrap items-start gap-2">
|
||||
<DTextarea @bind-Value="bio" Size="DSize.Xs" placeholder="Xs" class="w-24" />
|
||||
<DTextarea @bind-Value="bio" Size="DSize.Sm" placeholder="Sm" class="w-24" />
|
||||
<DTextarea @bind-Value="bio" placeholder="Md" class="w-24" />
|
||||
<DTextarea @bind-Value="bio" Size="DSize.Lg" placeholder="Lg" class="w-24" />
|
||||
<DTextarea @bind-Value="bio" Size="DSize.Xl" placeholder="Xl" class="w-24" />
|
||||
</div>
|
||||
<div class="flex flex-wrap items-start gap-2">
|
||||
<DTextarea @bind-Value="bio" Ghost="true" placeholder="Ghost" />
|
||||
<DTextarea @bind-Value="bio" disabled placeholder="Disabled" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<DTextarea @bind-Value="model.Bio" Immediate="true" Validator="true" placeholder="Bio, 10 to 140 characters" class="w-full" />
|
||||
<DValidatorHint>Between 10 and 140 characters</DValidatorHint>
|
||||
<span class="text-sm opacity-60">@(model.Bio?.Length ?? 0)/140</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="flex flex-col gap-3">
|
||||
<h3 class="text-lg font-bold">DCheckbox</h3>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
@foreach (var color in Enum.GetValues<DColor>())
|
||||
{
|
||||
<DCheckbox @bind-Value="check" Color="color" title="@color.ToString()" />
|
||||
}
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<DCheckbox @bind-Value="check" Size="DSize.Xs" />
|
||||
<DCheckbox @bind-Value="check" Size="DSize.Sm" />
|
||||
<DCheckbox @bind-Value="check" />
|
||||
<DCheckbox @bind-Value="check" Size="DSize.Lg" />
|
||||
<DCheckbox @bind-Value="check" Size="DSize.Xl" />
|
||||
<DCheckbox @bind-Value="check" disabled />
|
||||
</div>
|
||||
<DCheckbox @bind-Value="check" Color="DColor.Primary" LabelText="@($"Checked: {check}")" />
|
||||
<DCheckbox @bind-Value="model.Terms" LabelText="I accept the terms (must be checked)" />
|
||||
<ValidationMessage For="() => model.Terms" class="text-error text-xs" />
|
||||
</section>
|
||||
|
||||
<section class="flex flex-col gap-3">
|
||||
<h3 class="text-lg font-bold">DToggle</h3>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
@foreach (var color in Enum.GetValues<DColor>())
|
||||
{
|
||||
<DToggle @bind-Value="toggle" Color="color" title="@color.ToString()" />
|
||||
}
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<DToggle @bind-Value="toggle" Size="DSize.Xs" />
|
||||
<DToggle @bind-Value="toggle" Size="DSize.Sm" />
|
||||
<DToggle @bind-Value="toggle" />
|
||||
<DToggle @bind-Value="toggle" Size="DSize.Lg" />
|
||||
<DToggle @bind-Value="toggle" Size="DSize.Xl" />
|
||||
<DToggle @bind-Value="toggle" disabled />
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-4">
|
||||
<DToggle @bind-Value="toggle" Size="DSize.Lg">
|
||||
<CheckedIcon><i class="ion-md-checkmark"></i></CheckedIcon>
|
||||
<UncheckedIcon><i class="ion-md-close"></i></UncheckedIcon>
|
||||
</DToggle>
|
||||
<DToggle @bind-Value="toggle" Color="DColor.Success" Size="DSize.Lg">
|
||||
<CheckedIcon><i class="ion-md-sunny"></i></CheckedIcon>
|
||||
<UncheckedIcon><i class="ion-md-moon"></i></UncheckedIcon>
|
||||
</DToggle>
|
||||
<DToggle @bind-Value="toggle" Color="DColor.Accent" LabelText="With icons and a label">
|
||||
<CheckedIcon><i class="ion-md-volume-high"></i></CheckedIcon>
|
||||
<UncheckedIcon><i class="ion-md-volume-off"></i></UncheckedIcon>
|
||||
</DToggle>
|
||||
</div>
|
||||
<DToggle @bind-Value="model.Notifications" Color="DColor.Primary" LabelText="Notifications" />
|
||||
</section>
|
||||
|
||||
<section class="flex flex-col gap-3">
|
||||
<h3 class="text-lg font-bold">DRadioGroup / DRadio</h3>
|
||||
<DRadioGroup @bind-Value="radioColor" class="flex flex-wrap items-center gap-2" aria-label="Colors">
|
||||
@foreach (var color in Enum.GetValues<DColor>())
|
||||
{
|
||||
<DRadio Value="color" Color="color" title="@color.ToString()" />
|
||||
}
|
||||
</DRadioGroup>
|
||||
<p class="text-sm opacity-60">Picked: @radioColor</p>
|
||||
<DRadioGroup @bind-Value="radioSize" class="flex flex-wrap items-center gap-2" aria-label="Sizes">
|
||||
@foreach (var size in sizes)
|
||||
{
|
||||
<DRadio Value="size" Size="size" Color="DColor.Secondary" />
|
||||
}
|
||||
</DRadioGroup>
|
||||
<DRadioGroup @bind-Value="disabledPick" class="flex flex-wrap items-center gap-2" aria-label="Disabled">
|
||||
<DRadio Value="1" Disabled="true" LabelText="Disabled, checked" />
|
||||
<DRadio Value="2" Disabled="true" LabelText="Disabled" />
|
||||
</DRadioGroup>
|
||||
<DRadioGroup @bind-Value="model.Plan" class="flex flex-col gap-1" aria-label="Plan">
|
||||
@foreach (var plan in plans)
|
||||
{
|
||||
<DRadio Value="plan" LabelText="@plan" Color="DColor.Primary" />
|
||||
}
|
||||
</DRadioGroup>
|
||||
<ValidationMessage For="() => model.Plan" class="text-error text-xs" />
|
||||
</section>
|
||||
|
||||
<section class="flex flex-col gap-3">
|
||||
<h3 class="text-lg font-bold">DRange</h3>
|
||||
@foreach (var color in Enum.GetValues<DColor>())
|
||||
{
|
||||
<DRange @bind-Value="volume" Color="color" Immediate="true" title="@color.ToString()" />
|
||||
}
|
||||
<p class="text-sm opacity-60">Value: @volume</p>
|
||||
<DRange @bind-Value="volume" Size="DSize.Xs" />
|
||||
<DRange @bind-Value="volume" Size="DSize.Sm" />
|
||||
<DRange @bind-Value="volume" Size="DSize.Lg" />
|
||||
<DRange @bind-Value="volume" Size="DSize.Xl" />
|
||||
<div class="w-full max-w-xs">
|
||||
<DRange @bind-Value="steps" Step="25" Color="DColor.Accent" />
|
||||
<div class="mt-2 flex justify-between px-2.5 text-xs"><span>|</span><span>|</span><span>|</span><span>|</span><span>|</span></div>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<DRange @bind-Value="volume" Direction="DDirection.Vertical" Immediate="true" Color="DColor.Primary" />
|
||||
<DRange @bind-Value="volume" disabled />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="flex flex-col gap-3">
|
||||
<h3 class="text-lg font-bold">DRating</h3>
|
||||
<div class="flex flex-wrap items-center gap-4">
|
||||
<DRating @bind-Value="model.Stars" />
|
||||
<span class="text-sm opacity-60">@model.Stars stars (1 to 5)</span>
|
||||
</div>
|
||||
<ValidationMessage For="() => model.Stars" class="text-error text-xs" />
|
||||
<DRating @bind-Value="stars" Mask="DRatingMask.Star2" ItemClass="bg-orange-400" />
|
||||
<DRating @bind-Value="stars" Mask="DRatingMask.Heart" ItemClass="bg-red-400" UnitText="heart" class="gap-1" />
|
||||
<div class="flex flex-wrap items-center gap-4">
|
||||
<DRating @bind-Value="stars" Size="DSize.Xs" />
|
||||
<DRating @bind-Value="stars" Size="DSize.Sm" />
|
||||
<DRating @bind-Value="stars" />
|
||||
<DRating @bind-Value="stars" Size="DSize.Lg" />
|
||||
<DRating @bind-Value="stars" Size="DSize.Xl" />
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-4">
|
||||
<DRating @bind-Value="halfStars" Half="true" Clearable="true" Mask="DRatingMask.Star2" Size="DSize.Lg" ItemClass="bg-green-500" />
|
||||
<span class="text-sm opacity-60">@(halfStars / 2.0) stars (clearable)</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-4">
|
||||
<DRating @bind-Value="stars" Static="true" />
|
||||
<DRating @bind-Value="stars" Disabled="true" Mask="DRatingMask.Diamond" Count="3" />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="flex flex-col gap-3">
|
||||
<h3 class="text-lg font-bold">DFilter</h3>
|
||||
<DFilter @bind-Value="framework" Options="frameworks" />
|
||||
<DFilter @bind-Value="filterColor" Options="@(Enum.GetValues<DColor>().Skip(1).Cast<DColor?>())" TextOf="c => c?.ToString()" Size="DSize.Sm" />
|
||||
<p class="text-sm opacity-60">Picked: @(framework ?? "none"), @(filterColor?.ToString() ?? "none")</p>
|
||||
</section>
|
||||
|
||||
<section class="flex flex-col gap-3">
|
||||
<h3 class="text-lg font-bold">DOtp</h3>
|
||||
<div class="flex flex-col">
|
||||
<DOtp @bind-Value="model.Code" Immediate="true" />
|
||||
<ValidationMessage For="() => model.Code" class="text-error text-xs" />
|
||||
</div>
|
||||
<DOtp @bind-Value="otp" Length="4" Joined="true" Color="DColor.Primary" />
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
@foreach (var color in Enum.GetValues<DColor>().Skip(1))
|
||||
{
|
||||
<DOtp @bind-Value="otp" Length="4" Color="color" Size="DSize.Xs" title="@color.ToString()" />
|
||||
}
|
||||
</div>
|
||||
<div class="flex flex-wrap items-end gap-2">
|
||||
@foreach (var size in sizes)
|
||||
{
|
||||
<DOtp @bind-Value="otp" Length="4" Size="size" />
|
||||
}
|
||||
</div>
|
||||
<DOtp @bind-Value="otp" Length="4" disabled />
|
||||
</section>
|
||||
|
||||
<section class="flex flex-col gap-3">
|
||||
<h3 class="text-lg font-bold">DFileInput</h3>
|
||||
<div class="flex flex-col gap-2">
|
||||
@foreach (var color in Enum.GetValues<DColor>())
|
||||
{
|
||||
<DFileInput Color="color" title="@color.ToString()" />
|
||||
}
|
||||
</div>
|
||||
<DFileInput Size="DSize.Xs" />
|
||||
<DFileInput Size="DSize.Sm" />
|
||||
<DFileInput Size="DSize.Lg" />
|
||||
<DFileInput Size="DSize.Xl" />
|
||||
<DFileInput Ghost="true" />
|
||||
<DFileInput disabled />
|
||||
<DFileInput Multiple="true" Accept="image/*" Color="DColor.Primary" OnChange="OnFiles" />
|
||||
<p class="text-sm opacity-60">Picked: @(files.Count == 0 ? "nothing" : string.Join(", ", files))</p>
|
||||
</section>
|
||||
|
||||
<section class="flex flex-col gap-3">
|
||||
<h3 class="text-lg font-bold">DFieldset / DLabel</h3>
|
||||
<DFieldset class="bg-base-200 border-base-300 rounded-box w-xs border p-4">
|
||||
<Legend>Page details</Legend>
|
||||
<ChildContent>
|
||||
<DLabel>Title</DLabel>
|
||||
<DInput @bind-Value="text" placeholder="My awesome page" />
|
||||
<DLabel>Slug</DLabel>
|
||||
<DInput @bind-Value="site" placeholder="my-awesome-page" />
|
||||
</ChildContent>
|
||||
<Description>You can edit these later</Description>
|
||||
</DFieldset>
|
||||
<DFieldset disabled>
|
||||
<Legend>Disabled fieldset</Legend>
|
||||
<ChildContent><DInput @bind-Value="text" placeholder="Can't type here" /></ChildContent>
|
||||
</DFieldset>
|
||||
<DLabel Floating="true" Text="Your email">
|
||||
<DInput @bind-Value="email" placeholder="mail@site.com" />
|
||||
</DLabel>
|
||||
<DLabel Floating="true" Text="Notes">
|
||||
<DTextarea @bind-Value="bio" placeholder="Notes" />
|
||||
</DLabel>
|
||||
</section>
|
||||
|
||||
<section class="flex flex-col gap-3">
|
||||
<h3 class="text-lg font-bold">DValidator / DValidatorHint</h3>
|
||||
<p class="text-sm opacity-60">Native rules, checked by the browser once you've edited the field.</p>
|
||||
<div class="flex flex-col">
|
||||
<DInput @bind-Value="email" Type="email" Validator="true" required="true" placeholder="mail@site.com" />
|
||||
<DValidatorHint>Enter a valid email address</DValidatorHint>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<DInput @bind-Value="username" Validator="true" required="true" pattern="[A-Za-z][A-Za-z0-9\-]*" minlength="3"
|
||||
maxlength="30" placeholder="Username" title="Only letters, numbers or dash" />
|
||||
<DValidatorHint Compact="true">Must be 3 to 30 letters, numbers or dashes (Compact: no space while valid)</DValidatorHint>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="flex flex-col gap-3">
|
||||
<h3 class="text-lg font-bold">DCalendar</h3>
|
||||
<DCalendar @bind-Value="model.Date" Min="today.AddDays(-30)" Max="today.AddMonths(3)"
|
||||
class="bg-base-100 border-base-300 rounded-box border shadow-lg" />
|
||||
<p class="text-sm opacity-60">Picked: @(model.Date?.ToString("yyyy-MM-dd") ?? "nothing") (from 30 days ago to 3 months ahead)</p>
|
||||
<DButton Size="DSize.Sm" OnClick="() => model.Date = today" class="self-start">Today</DButton>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 flex items-center gap-4">
|
||||
<DButton Type="submit" Color="DColor.Primary">Validate the form</DButton>
|
||||
<span class="text-sm opacity-60">@submitResult</span>
|
||||
</div>
|
||||
</EditForm>
|
||||
|
||||
@code {
|
||||
class DemoModel
|
||||
{
|
||||
[Required] public string Name { get; set; }
|
||||
[Required] public string Language { get; set; }
|
||||
[Required, StringLength(140, MinimumLength = 10)] public string Bio { get; set; }
|
||||
[Range(typeof(bool), "true", "true", ErrorMessage = "Accept the terms")] public bool Terms { get; set; }
|
||||
public bool Notifications { get; set; } = true;
|
||||
[Required] public string Plan { get; set; }
|
||||
[Range(1, 5, ErrorMessage = "Rate from 1 to 5 stars")] public int Stars { get; set; }
|
||||
[Required, RegularExpression("[0-9]{6}", ErrorMessage = "Enter the 6 digits")] public string Code { get; set; }
|
||||
public DateOnly? Date { get; set; }
|
||||
}
|
||||
|
||||
readonly DemoModel model = new();
|
||||
readonly DSize[] sizes = { DSize.Xs, DSize.Sm, DSize.Md, DSize.Lg, DSize.Xl };
|
||||
readonly string[] plans = { "Free", "Pro", "Team" };
|
||||
readonly string[] frameworks = { "Blazor", "Svelte", "Vue", "React" };
|
||||
readonly DateOnly today = DateOnly.FromDateTime(DateTime.Today);
|
||||
|
||||
string submitResult;
|
||||
int disabledPick = 1;
|
||||
string text;
|
||||
string search;
|
||||
string site;
|
||||
string email;
|
||||
string username;
|
||||
string language = "C#";
|
||||
string bio;
|
||||
bool check = true;
|
||||
bool toggle = true;
|
||||
DColor radioColor = DColor.Primary;
|
||||
DSize radioSize = DSize.Md;
|
||||
int volume = 40;
|
||||
int steps = 25;
|
||||
int stars = 3;
|
||||
int halfStars = 7;
|
||||
string framework;
|
||||
DColor? filterColor;
|
||||
string otp;
|
||||
List<string> files = new();
|
||||
|
||||
void Submitted(bool valid) => submitResult = valid ? "Valid" : "Invalid: see the messages above";
|
||||
|
||||
void OnFiles(InputFileChangeEventArgs e) => files = e.GetMultipleFiles(e.FileCount).Select(f => f.Name).ToList();
|
||||
}
|
||||
Reference in new issue
Block a user