Rask
Rask
v0.23.1-alpha.0.440

Components

Flag

A country's flag from its two-letter Unicode region code, 3:2 or cropped to a circle, in five widths. Each is one small file the page fetches when it shows it.

Drawn and behaving as Flux UI's flag does, measured against its live docs.

Flag

24px wide when it says nothing else.

FlagExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class FlagExample : Component
{
    private static readonly string[] Countries = ["US", "EU", "IN", "BR", "DE", "GB", "PH"];

    protected override Component? Render() =>
        Div.Class("flex flex-wrap items-center gap-5")[
            Countries.Select(code => Ui.Flag.Key(code).Country(code))
        ];
}
Live result

Sizes

Xl 48px, Lg 40px, Md 32px, Sm 24px and Xs 20px wide.

FlagSizesExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class FlagSizesExample : Component
{
    protected override Component? Render() =>
        Div.Class("flex flex-wrap items-center gap-5")[
            Ui.Flag.Key("xl").Country("US").Xl,
            Ui.Flag.Key("lg").Country("US").Lg,
            Ui.Flag.Key("md").Country("US").Md,
            Ui.Flag.Key("sm").Country("US"),
            Ui.Flag.Key("xs").Country("US").Xs
        ];
}
Live result

Circle

FlagCircleExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class FlagCircleExample : Component
{
    private static readonly string[] Countries = ["US", "FR", "JP", "BR", "NG"];

    protected override Component? Render() =>
        Div.Class("flex flex-wrap items-center gap-5")[
            Countries.Select(code => Ui.Flag.Key(code).Circle().Country(code))
        ];
}
Live result

Country select

A flag in each option, and in the button once one is picked.

FlagCountrySelectExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class FlagCountrySelectExample : Component
{
    private static readonly (string Code, string Name)[] Places =
    [
        ("US", "United States"), ("CA", "Canada"), ("MX", "Mexico"), ("BR", "Brazil"), ("GB", "United Kingdom"), ("FR", "France"),
        ("DE", "Germany"), ("NG", "Nigeria"), ("ZA", "South Africa"), ("IN", "India"), ("JP", "Japan"), ("AU", "Australia"),
    ];

    private string _country = "US";

    protected override Component? Render() =>
        Div.Class("flex flex-wrap items-center gap-5")[
            Div.Class("w-72")[
                Ui.Select.Value(_country).Listbox.Searchable().OnChange(code => { _country = code ?? "US"; })[
                    Places.Select(place => Ui.SelectOption.Key(place.Code).Value(place.Code)[
                        Div.Class("flex items-center gap-2")[Ui.Flag.Country(place.Code).Xs, Span[place.Name]]
                    ])
                ]
            ],
            Ui.Text.Data("testid", "ui-flag-country-says")[$"Ships to {_country}."]
        ];
}
Live result
No results found
United States
Canada
Mexico
Brazil
United Kingdom
France
Germany
Nigeria
South Africa
India
Japan
Australia

Ships to US.

Currency select

FlagCurrencySelectExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class FlagCurrencySelectExample : Component
{
    private static readonly (string Code, string Country, string Name)[] Currencies =
    [
        ("USD", "US", "US dollar"), ("EUR", "EU", "Euro"), ("CAD", "CA", "Canadian dollar"), ("GBP", "GB", "Pound sterling"),
        ("AUD", "AU", "Australian dollar"), ("JPY", "JP", "Japanese yen"), ("CNY", "CN", "Chinese yuan"), ("CHF", "CH", "Swiss franc"),
    ];

    private string _currency = "USD";

    protected override Component? Render() =>
        Div.Class("flex flex-wrap items-center gap-5")[
            Div.Class("w-72")[
                Ui.Select.Value(_currency).Listbox.OnChange(code => { _currency = code ?? "USD"; })[
                    Currencies.Select(currency => Ui.SelectOption.Key(currency.Code).Value(currency.Code)[
                        Div.Class("flex items-center gap-2")[
                            Ui.Flag.Country(currency.Country).Xs,
                            Span.Class("font-medium")[currency.Code],
                            Span.Class("text-zinc-500 dark:text-zinc-400")[currency.Name]
                        ]
                    ])
                ]
            ],
            Ui.Text.Data("testid", "ui-flag-currency-says")[$"Billed in {_currency}."]
        ];
}
Live result
USDUS dollar
EUREuro
CADCanadian dollar
GBPPound sterling
AUDAustralian dollar
JPYJapanese yen
CNYChinese yuan
CHFSwiss franc

Billed in USD.

Analytics card

FlagAnalyticsExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class FlagAnalyticsExample : Component
{
    private static readonly (string Code, string Name, string Visitors)[] Countries =
    [
        ("ID", "Indonesia", "3.6K"), ("US", "United States", "2.6K"), ("IN", "India", "2.4K"), ("BR", "Brazil", "2.0K"),
        ("DE", "Germany", "1.9K"), ("GB", "United Kingdom", "1.4K"), ("PH", "Philippines", "1.0K"),
    ];

    protected override Component? Render() =>
        Ui.Card.Soft.Class("w-full max-w-sm")[
            Div.Class("flex items-baseline justify-between gap-4")[
                Ui.Heading["Countries"],
                Ui.Text.Class("font-medium")["Visitors"]
            ],
            Div.Class("mt-6 space-y-5")[
                Countries.Select(country => Div.Key(country.Code).Class("flex items-center gap-3")[
                    Ui.Flag.Country(country.Code).Md.Class("w-7"),
                    Ui.Text.Variant(Ui.TextVariant.Strong).Class("min-w-0 flex-1 truncate")[country.Name],
                    Ui.Text.Variant(Ui.TextVariant.Strong).Class("font-medium")[country.Visitors]
                ])
            ]
        ];
}
Live result
Countries

Visitors

Indonesia

3.6K

United States

2.6K

India

2.4K

Brazil

2.0K

Germany

1.9K

United Kingdom

1.4K

Philippines

1.0K

Custom flags

Src takes any image: a subdivision, an organization, a historical flag.

FlagCustomExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class FlagCustomExample : Component
{
    // A flag of the page's own: Src takes any image.
    private const string Pennant =
        "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 3 2'%3E%3Cpath fill='%23fff' d='M0 0h3v2H0z'/%3E"
        + "%3Cpath fill='%23be123c' d='M0 1.6h3V2H0z'/%3E%3Ccircle cx='.6' cy='.6' r='.3' fill='%23be123c'/%3E%3C/svg%3E";

    protected override Component? Render() => Ui.Flag.Src(Pennant).Alt("Pennant").Xl;
}
Live result
Pennant

Accessibility

Beside the country's name a flag is decoration; on its own, Alt says which country it is.

FlagAccessibilityExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class FlagAccessibilityExample : Component
{
    // Beside the country's name a flag is decoration; on its own it says which country it is.
    protected override Component? Render() =>
        Div.Class("flex flex-wrap items-center gap-5")[
            Div.Key("decorative").Class("flex items-center gap-2")[Ui.Flag.Country("CA"), Ui.Text["Canada"]],
            Ui.Flag.Key("informative").Country("CA").Alt("Canada")
        ];
}
Live result

Canada

Canada

Behaviour

The codes and the drawings

The registry is Unicode's two-letter flag sequences, as Flux's is, and saying a code is in it takes no position on any country, territory or border. The drawings are country-flag-icons 1.6.20 (MIT), the set Flux serves; UN and CQ are not in that set and draw the empty frame, as does any code with no drawing.

The drawings are files

The 254 drawings are not part of the assembly: 172 KB an app that shows three flags should not download. An app's build copies them into wwwroot/flags with their notice (wwwroot/flags/LICENSE.txt), together with the phone field's engine, whose list draws a flag a country. An app that turned that engine off, or a host that is not a Web SDK project, says it wants them with <RaskUiWriteFlags>true</RaskUiWriteFlags> in a <PropertyGroup> of its project file; false writes none, phone engine or not.

Each Ui.Flag is then one <img loading="lazy"> of /flags/<CC>.svg: a page fetches the flags it shows. In a one-project WebAssembly app the browser half writes them, as it does the editor's engine. Without them every flag is a broken image.

Reference

Ui.Flag

flux:flag

A country's flag: one <img loading="lazy"> of /flags/<CC>.svg, 3:2.

Step
Takes
What it does
.Country(…)stringThe Unicode region code, in either case: "US", "de". A code with no drawing shows the empty frame.
.Src(…)stringAn image of your own (a subdivision, an organization), which wins over Country.
.Alt(…)stringWhat the flag says, for a reader who cannot see it. Empty when unset: decoration.
.Size(…)
Ui.FlagSize
Sm
Xs
Md
Lg
Xl

Each is a step of its own too, unless an HTML tag has its name.

How wide it is. Sm, 24px, when unset; a w-* in Class wins over it.
.Circle()boolCrops it to a circle.