LilyDesignSystem.Blazor.TextSizePicker 0.2.0

dotnet add package LilyDesignSystem.Blazor.TextSizePicker --version 0.2.0
                    
NuGet\Install-Package LilyDesignSystem.Blazor.TextSizePicker -Version 0.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="LilyDesignSystem.Blazor.TextSizePicker" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="LilyDesignSystem.Blazor.TextSizePicker" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="LilyDesignSystem.Blazor.TextSizePicker" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add LilyDesignSystem.Blazor.TextSizePicker --version 0.2.0
                    
#r "nuget: LilyDesignSystem.Blazor.TextSizePicker, 0.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package LilyDesignSystem.Blazor.TextSizePicker@0.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=LilyDesignSystem.Blazor.TextSizePicker&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=LilyDesignSystem.Blazor.TextSizePicker&version=0.2.0
                    
Install as a Cake Tool

TextSizePicker (Blazor helper)

A reusable, headless Blazor text-size picker. Renders an icon button that opens a dropdown listbox of size slugs and applies the chosen slug to the document root via data-text-size, with optional localStorage persistence. Ships no CSS — you style the class hooks and map each [data-text-size="{slug}"] to real typography.

Single source of truth: spec/index.md.

Install

Add a project reference to LilyDesignSystem.Blazor.TextSizePicker.csproj, or the published LilyDesignSystem.Blazor.TextSizePicker NuGet package.

Quick start

@using LilyDesignSystem.Blazor.Helpers

<TextSizePicker Label="Text size"
                Sizes='new[] { "small", "medium", "large", "x-large" }'
                StorageKey="lily-text-size"
                @bind-Value="size" />

<p class="text-size-picker-status" aria-live="polite">
    Text size: @TextSizePicker.SizeName(size)
</p>

@code {
    private string size = "";
}

The closed control shows only a glyph, so nothing on screen says which size is active. The status region above is the recommended companion — see docs/accessibility.md.

Then style the slugs in your own CSS:

:root[data-text-size="small"]   { font-size: 87.5%; }
:root[data-text-size="medium"]  { font-size: 100%; }
:root[data-text-size="large"]   { font-size: 112.5%; }
:root[data-text-size="x-large"] { font-size: 125%; }

Rendered HTML

<div class="text-size-picker">
  <input type="hidden" name="text-size" value="medium" />
  <button type="button" class="text-size-picker-button" aria-label="Text size"
          aria-haspopup="listbox" aria-expanded="false" aria-controls="text-size-picker-1-list">
    <span class="text-size-picker-icon" aria-hidden="true">A</span>
  </button>
  <ul class="text-size-picker-list" id="text-size-picker-1-list" role="listbox"
      aria-label="Text size" tabindex="-1" hidden>
    <li class="text-size-picker-option" role="option" aria-selected="false">Small</li>
    <li class="text-size-picker-option" role="option" aria-selected="true" data-active>Medium</li>
    <li class="text-size-picker-option" role="option" aria-selected="false">Large</li>
    <li class="text-size-picker-option" role="option" aria-selected="false">X Large</li>
  </ul>
</div>

The package ships no CSS, so give the root position: relative and the list position: absolute or an open list will shove the page around. See docs/styling.md.

Parameters

Parameter Type Required Default
Label string yes —
Sizes IReadOnlyList<string> yes —
Value string no ""
ValueChanged EventCallback<string> no —
DefaultValue string? no "medium" if present, else Sizes[0]
StorageKey string? no null
Name string no "text-size"
SizeLabels IReadOnlyDictionary<string,string> no empty
ChildContent RenderFragment<TextSizePickerContext>? no the "A" glyph
OnChange EventCallback<string> no —
CssClass string no ""
AdditionalAttributes Dictionary<string,object>? no —

CssClass and AdditionalAttributes land on the root <div>, not on a form control.

There is deliberately no DetectFromSystem parameter: unlike colour scheme and language, browsers expose no "preferred text size" signal to detect.

Statics

  • No glyph constant — the default icon is a bundled SVG, not a Unicode character (reversed 2026-09-16).
  • TextSizePicker.SizeName(slug) — the shared title-casing rule ("x-large" → "X Large"). Use it when you render your own labels so they match the listbox exactly. Mirrors ThemePicker.ThemeName and Locales.LocaleName.
  • SetSizeAsync(slug) — apply a size imperatively via a @ref.

Custom glyph

ChildContent replaces the glyph inside the button. It does not render options — those are component-owned so the listbox semantics cannot be broken by an override.

<TextSizePicker Label="Text size" Sizes="sizes" @bind-Value="size">
    <ChildContent Context="ctx">
        <svg viewBox="0 0 24 24" width="20" height="20" aria-hidden="true">
            <path d="M4 20 L10 4 L16 20 M6.5 14 H13.5" fill="none"
                  stroke="currentColor" stroke-width="2" />
        </svg>
    </ChildContent>
</TextSizePicker>

The context carries Value, Open, and LabelFor. The accessible name still comes from the button's aria-label, so keep Label set even when supplying your own glyph.

Keyboard

Button: ArrowDown / Enter / Space open on the selected option, ArrowUp opens on the last. Listbox: arrows move and clamp, Home / End jump, PageUp / PageDown move by ten (clamped), Enter / Space select and close, Escape closes without changing the value, Tab closes and moves on (the browser's default Tab proceeds from the picker's position), printable characters run a 500 ms APG typeahead — a repeated character cycles through its matches; differing characters refine from the active option. Full table: docs/accessibility.md.

Accessibility

  • WCAG 2.2 AAA target; directly supports SC 1.4.4 (Resize Text).
  • WAI-ARIA APG listbox pattern with aria-activedescendant.
  • aria-label is the button's entire accessible name — it is icon-only.
  • The tradeoffs of a custom listbox versus a native <select> are stated plainly in docs/accessibility.md.

Examples

See examples/.

License

Dual-licensed under MIT or Apache-2.0 or GPL-2.0 or GPL-3.0 or BSD-3-Clause. Contact joel@joelparkerhenderson.com for other terms.


Lily™ and Lily Design System™ are trademarks.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on LilyDesignSystem.Blazor.TextSizePicker:

Package Downloads
LilyDesignSystem.Blazor.PickerBar

Lily Design System Blazor picker bar: composes theme-picker, locale-picker, text-size-picker, and share-picker into one page-header row. Headless, SSR-safe, no CSS.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.0 98 9/16/2026
0.1.0 110 9/2/2026