howdy/ui/words
Words: everything howdy_ui’s components say, in one language.
let t = i18n.new(locale.to_string(locale.detect(ctx, locales)))
let w = words.translated(t)
pagination.pagination(w, current: 3, total: 12, href: page_href)
toast.region(w, [], toasts)
calendar.new("due", year: 2026, month: 9) |> calendar.locale(w.calendar)
data_table.new(columns, rows) |> data_table.words(w)
Components that are plain functions take the words as their first
argument; those built step by step take them with a words step and
speak English without one. Calendars, uploaders and attachments keep
their own words, which are fields here.
english is what the components have always said. translated gives
the words for a translator’s locale from howdy_ui’s catalogues, with
numbers, dates and the first day of the week from CLDR; locales without
a catalogue fall back to English words with their own number formats.
The catalogues were machine translated and are waiting for review by
native speakers. Change a few words with a record update:
Words(..words.english(), dismiss: "Close").
The catalogues live in ui/locales. After changing them, regenerate
howdy/ui/internal/messages from the i18n directory:
gleam run -m howdy/i18n/cli -- gen --locales=../ui/locales --out=../ui/src/howdy/ui/internal/messages.gleam
Types
What a rich text editor says. heading may contain {level}, and
too_large {limit}.
pub type RichTextWords {
RichTextWords(
toolbar: String,
bold: String,
italic: String,
strike: String,
code: String,
link: String,
heading: String,
quote: String,
bullet_list: String,
numbered_list: String,
code_block: String,
divider: String,
attach: String,
undo: String,
redo: String,
link_address: String,
link_apply: String,
link_remove: String,
bad_link: String,
no_matches: String,
remove: String,
uploading: String,
too_large: String,
wrong_type: String,
failed: String,
wait: String,
missing: String,
unavailable: String,
)
}
Constructors
-
RichTextWords( toolbar: String, bold: String, italic: String, strike: String, code: String, link: String, heading: String, quote: String, bullet_list: String, numbered_list: String, code_block: String, divider: String, attach: String, undo: String, redo: String, link_address: String, link_apply: String, link_remove: String, bad_link: String, no_matches: String, remove: String, uploading: String, too_large: String, wrong_type: String, failed: String, wait: String, missing: String, unavailable: String, )
pub type Words {
Words(
locale: String,
number: fn(Int) -> String,
decimal: fn(Float) -> String,
percent: fn(Float) -> String,
position: fn(Int, Int) -> String,
pagination: String,
previous_page: String,
next_page: String,
breadcrumb: String,
notifications: String,
dismiss: String,
command_menu: String,
clear: String,
remove: fn(String) -> String,
no_results: String,
select_row: String,
select_all_rows: String,
carousel: String,
slide: String,
previous_slide: String,
next_slide: String,
pause_slides: String,
play_slides: String,
resize: String,
jump_to_newest: String,
show_data: String,
total: String,
out_of: fn(String, String) -> String,
minimum: String,
maximum: String,
question_count: fn(Int, Int) -> String,
progress: String,
back: String,
skip: String,
next: String,
finish: String,
answer_required: String,
choose_one: String,
choose_from: String,
choose_on_scale: String,
give_one_answer: String,
loading: String,
unread: String,
mark_all_read: String,
mark_read: String,
mark_unread: String,
caught_up: String,
see_all_notifications: String,
notifications_failed: String,
push_on: String,
push_off: String,
push_blocked: String,
calendar: calendar.Locale,
uploader: uploader.Words,
attachment: attachment.Words,
rich_text: RichTextWords,
)
}
Constructors
-
Words( locale: String, number: fn(Int) -> String, decimal: fn(Float) -> String, percent: fn(Float) -> String, position: fn(Int, Int) -> String, pagination: String, previous_page: String, next_page: String, breadcrumb: String, notifications: String, dismiss: String, command_menu: String, clear: String, remove: fn(String) -> String, no_results: String, select_row: String, select_all_rows: String, carousel: String, slide: String, previous_slide: String, next_slide: String, pause_slides: String, play_slides: String, resize: String, jump_to_newest: String, show_data: String, total: String, out_of: fn(String, String) -> String, minimum: String, maximum: String, question_count: fn(Int, Int) -> String, progress: String, back: String, skip: String, next: String, finish: String, answer_required: String, choose_one: String, choose_from: String, choose_on_scale: String, give_one_answer: String, loading: String, unread: String, mark_all_read: String, mark_read: String, mark_unread: String, caught_up: String, see_all_notifications: String, notifications_failed: String, push_on: String, push_off: String, push_blocked: String, calendar: calendar.Locale, uploader: uploader.Words, attachment: attachment.Words, rich_text: RichTextWords, )Arguments
- locale
-
The BCP 47 tag of the words’ language, such as
de. - number
-
A whole number, such as a page number.
- decimal
-
A value in a chart: thousands separators and at most two decimal places.
- percent
-
A share of a whole, given as a fraction, such as
0.25for 25%. - position
-
A position in a sequence, such as “2 of 5”, given the position and the count.
- pagination
-
Pagination: the navigation’s name and the links on either side.
- notifications
-
Toasts: the region’s name and each toast’s close button.
- command_menu
-
Command menus and comboboxes.
- remove
-
The remove button on a chosen option’s chip, given its label.
- no_results
-
Data tables.
- carousel
-
Carousels: what a screen reader calls a carousel and a slide, and the buttons.
- resize
-
A drawer’s handle.
- jump_to_newest
-
The button that appears in a conversation scrolled back from the newest message.
- show_data
-
Charts: the button that shows the table, the label in a donut’s middle, and a value out of a maximum, given both written out.
- minimum
-
A range slider’s two thumbs.
- question_count
-
Questionnaires: “Question 2 of 5”, given the number and the count, the progress bar, the buttons, and why an answer was not accepted.
- loading
-
A label for a spinner.
- unread
-
Notification bells: the unread count, which may contain
{count}, the buttons, what an empty or failed inbox says, and the browser notification switch. The bell’s name isnotifications.
Values
pub fn english_decimal(value: Float) -> String
Thousands separators and at most two decimal places: 12,500 or 3.25.
pub fn locales() -> List(String)
The locales howdy_ui has catalogues for. Others still get their own
number and date formats from translated, with English words.
pub fn translated(translator t: i18n.Translator) -> Words
The words for a translator’s locale.