Skip to content

feat: release 0.1.7 with the locale catalogs every component draws its words from - #115

Merged
rubentalstra merged 4 commits into
mainfrom
feat/release-0-1-7
Oct 19, 2026
Merged

rubentalstra merged 4 commits into
mainfrom
feat/release-0-1-7

Conversation

@rubentalstra

Copy link
Copy Markdown
Contributor

What changed and why

FerroUI 0.1.7 makes the family ready for more languages, with English the one that ships (owner ruling on #112, 2026-10-19). No Dutch or German catalog is added.

  • i18n: every string a component draws itself is a message of crates/ferrohealth-ui/locales/en/ferrohealth-ui.ftl (Project Fluent syntax), embedded at build time by fluent-templates 0.15.1 (static_loader! over locales/, verified on crates.io today; builds and lints on native ssr and on wasm32 hydrate and csr; no JavaScript). en is the reference: complete, the fallback of every lookup, and held complete by i18n::tests, which also checks any other catalog directory against the full message set, so a new language is a catalog file with no code change.
  • The locale is chosen once per render: Locale (from a BCP 47 tag; negotiate over Accept-Language; negotiate_with over a console's catalog with its configured locale as the fallback), provide_locale at the root on both halves, locale() to read it, Locale::tag for <html lang>, Locale::lookup for a console's own catalog, Locale::with_catalog for a catalog the library does not ship. A page that provides none draws English.
  • Proof: tests/it/locale.rs renders the pager and the confirmation dialog with a throwaway qaa catalog under tests/it/locales/ and sees the words change with no code change, while a message the catalog lacks falls back to English.
  • scripts/checks/stray-literals.sh, a new CI job (stray-literals, in conclusion): fails on a string a reader sees in a component outside the catalog; scripts/checks/stray-literals.allow lists the literals that are no reader's text (key names, product names, SVG markup), each with its reason. A console runs the same script with a baseline that only shrinks.
  • view::theme_switch::locale_switch: the language switch, each choice named in its own language and marked with lang (WCAG 2.2 SC 3.1.2).
  • view::layout::keyed_field_row: a field row with an id (FerroFED's list rows hand-write the classes today).
  • Rule and memory: .claude/rules/leptos-ui.md §0 and §13 and .claude/memory/ferroui.md: no user-visible component string outside the catalogs.
  • Gallery: the overview's settings gain the language switch; the gallery's own pseudo-locale qps draws every library string accented and two fifths longer; <html lang> follows the cookie.

What a console must change: Theme::label, Density::label, Step::label, Severity::word and Variant::name return String instead of &'static str; button::label and copy_button accept a String as well. The English words and their markup are unchanged.

The bundle grows to 673607 bytes brotli (+53325 over 0.1.6): the Fluent parser, the CLDR plural rules and the catalog. The budget raise is its own pull request, #113, which merges first.

Left for the next release: the labels a console passes to components are still &'static str in most places, so a console cannot move its own strings until #114 lands.

Screens checked

  • English: all 280 refreshed images diffed against main: every change is the version (Library v0.1.7 pill at row 10 of the wide shots, v0.1.7 in every footer) except the overview (the Language field, 1440 and 390, light and dark, in all four brands) and the skeleton shimmer's frame in tables-narrow. No other pixel moved.
  • Pseudo-locale (FERROUI_PSEUDO=1, FerroBRIDGE brand, every page and sign-in card, 1440 and 390, light and dark, read): two defects found and fixed in this PR. The search box's Find button wrapped its word inside the button (it now keeps one line and the input gives way), and the pager's size choices broke with 100 alone on a new row (the choices now wrap as one group). What remains is graceful wrapping: the document pane's view choice and the theme switch wrap a segment to a second row at 390 px, and the pager's range sentence wraps over several lines, with no overflow and no sideways scroll.

Closes #112

Licensing of contributions

  • I accept the terms in CONTRIBUTING.md § Licensing of contributions: I have the right to submit this work, I license it under the project licence of the version it lands in, and I grant the Licensor the relicensing right stated there.

Checklist

  • Accessibility decisions cite WCAG 2.2, WAI-ARIA 1.2 or the Authoring Practices, not memory and not another library.
  • Rust gates pass: cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings, the wasm32 clippy runs, cargo nextest run --workspace --locked, cargo doc with RUSTDOCFLAGS=-D warnings, and cargo deny check.
  • A visible change refreshed the gallery screenshots, and I looked at every image it changed.
  • A new or changed component was compared with the four consoles' versions (docs/qa/), and the best one on its merits was restyled to the library's tokens; the winner and the reason are stated below.
  • Its interactive states (pointer, focus, open, each tone) are captured by tests/it/states.rs in every brand, light and dark.
  • A release pull request says, per screen and per state, what was checked and what was fixed.
  • Shell and workflow files are clean: shellcheck --severity=style, actionlint, zizmor --min-severity=low .github/.
  • CHANGELOG.md has an [Unreleased] entry, if a console sees the change.
  • No patient data in a fixture, test, gallery row or example.
  • Every commit is signed.
  • No AI or assistant attribution anywhere in the commits or this PR.

…s words from

Every string a component draws itself is a message of a Fluent catalog
under locales/, embedded at build time by fluent-templates 0.15.1 on both
halves with no script. English is the one catalog that ships and the one
every lookup falls back to; a language joins as a catalog file with no code
change, which a throwaway test catalog proves. The locale is chosen once per
render through i18n::provide_locale, a console reads it for <html lang>, and
looks its own strings up with Locale::lookup. A stray-literal check in CI
fails on a component string outside the catalog, and the gallery gains a
language switch and a pseudo-locale that lengthens every library string.
Also adds view::layout::keyed_field_row.
@rubentalstra rubentalstra added this to the v0.1.7 milestone Oct 19, 2026
@sonarqubecloud

Copy link
Copy Markdown

@rubentalstra
rubentalstra added this pull request to the merge queue Oct 19, 2026
Merged via the queue into main with commit cdb5934 Oct 19, 2026
26 checks passed
@rubentalstra
rubentalstra deleted the feat/release-0-1-7 branch October 19, 2026 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A locale mechanism and catalogs for the strings components draw themselves

1 participant