Set value to a number, a bigint or text, or leave it unset and write the input as the element’s content, so server-rendered text upgrades in place. preset names the transform; the default, text, presents the input unchanged. The element paints no surface and inherits font and color, so it fits in table cells, list rows and labels. It paints no surface, inherits font and color from its context, and is isolated for bidirectional text like <bdi>, so a right-to-left value never reorders with the text around it.
Case and identifiers
Case presets change how words are capitalized and follow the locale of the closest lang. Identifier presets split names at spaces, -, _, ., case changes and acronyms, so a property key such as billingEmail can become the label “Billing email”. Case changes follow the locale: uppercase maps istanbul to İSTANBUL under lang="tr". capitalize and sentence change only the first character of a word and leave the rest as written.
Case and identifiers
Default density
Compact density
Restart from the initial state
Show the copyable source
capitalize
quarterly planning review
sentence
invoices are sent on the first of the month
uppercase
eu-west-1
humanize
billingEmail
kebab
Billing Email
constant
billingEmail
capitalize
quarterly planning review
sentence
invoices are sent on the first of the month
uppercase
eu-west-1
humanize
billingEmail
kebab
Billing Email
constant
billingEmail
<dl style="display:grid;grid-template-columns:auto auto;gap:var(--tp-space-2) var(--tp-space-6);margin:0;font-size:var(--tp-text-sm)">
<dt style="color:var(--tp-muted-foreground)">capitalize</dt><dd style="margin:0"><tp-text-transform preset="capitalize">quarterly planning review</tp-text-transform></dd>
<dt style="color:var(--tp-muted-foreground)">sentence</dt><dd style="margin:0"><tp-text-transform preset="sentence">invoices are sent on the first of the month</tp-text-transform></dd>
<dt style="color:var(--tp-muted-foreground)">uppercase</dt><dd style="margin:0"><tp-text-transform preset="uppercase">eu-west-1</tp-text-transform></dd>
<dt style="color:var(--tp-muted-foreground)">humanize</dt><dd style="margin:0"><tp-text-transform preset="humanize">billingEmail</tp-text-transform></dd>
<dt style="color:var(--tp-muted-foreground)">kebab</dt><dd style="margin:0"><tp-text-transform preset="kebab">Billing Email</tp-text-transform></dd>
<dt style="color:var(--tp-muted-foreground)">constant</dt><dd style="margin:0"><tp-text-transform preset="constant">billingEmail</tp-text-transform></dd>
</dl>
capitalize and sentence change only the first letter of a word and leave the rest as written, so acronyms survive. camel, pascal and snake complete the identifier presets.
Numbers, currency and units
Numeric presets format through Intl.NumberFormat with tabular figures. currency takes an ISO 4217 code for the currency preset, unit a unit identifier such as kilometer or megabyte-per-second, and decimals fixes the fraction digits. percent reads a ratio, so 0.82 is 82%. Dates and times belong to Time.
Plans
Default density
Compact density
Restart from the initial state
Show the copyable source
Abbreviated forms are spelled out for assistive technology: “1.2M” is read as “1.2 million” and “50 MB/s” as “50 megabytes per second”. Each numeric value renders as a data element carrying the raw number. Grouped text such as 1,234 is not read as a number; it stays as written and the element sets invalid. Decimal text is formatted exactly, so 12345678901234567890.25 keeps every digit. bytes and duration also reject negative values.
Bytes and durations
bytes formats a byte count with binary units (1 KB = 1024 B). duration reads seconds and shows them as a clock, read aloud as “1 hour, 2 minutes, 5 seconds”. Both reject negative values.
Uploads
Default density
Compact density
Restart from the initial state
Show the copyable source
Without locale, the closest lang decides separators, digits and currency placement, and a change to lang updates the text in place. Set locale to fix one value to a language regardless of the page. A locale that is not a valid language tag emits a tp-diagnostic and the browser’s default locale applies.
Locales
Default density
Compact density
Restart from the initial state
Show the copyable source
truncate keeps the text on one line that fits the element’s width, placing the omission (…) at the end, the middle or the start. Use middle for file names whose extension matters and start for paths whose last segment matters. truncate-by="words" removes whole words instead of characters. Drag the handle to see each value refit. Start and end are logical: in right-to-left text the start is on the right. The text refits when the container resizes, fonts load, or the text, locale or truncation settings change.
Truncation
Default density
Compact density
Restart from the initial state
Show the copyable source
Migrate billing to usage-based pricing before the October releaseMigrate billing to usage-based pricing before the October releasedesign-review-2026-10-14-final-screenshots.zip/workspace/marketing/campaigns/autumn-launch/brief.pdf
Migrate billing to usage-based pricing before the October releaseMigrate billing to usage-based pricing before the October releasedesign-review-2026-10-14-final-screenshots.zip/workspace/marketing/campaigns/autumn-launch/brief.pdf
<tp-resizable-panel-group style="block-size:11rem;border:var(--tp-border-width) solid var(--tp-border);border-radius:var(--tp-radius-lg)">
<tp-resizable-panel default-size="40%" min-size="15%">
<div style="display:grid;gap:var(--tp-space-3);padding:var(--tp-space-4);font-size:var(--tp-text-sm)">
<tp-text-transform truncate="end">Migrate billing to usage-based pricing before the October release</tp-text-transform>
<tp-text-transform truncate="end" truncate-by="words">Migrate billing to usage-based pricing before the October release</tp-text-transform>
<tp-text-transform truncate="middle">design-review-2026-10-14-final-screenshots.zip</tp-text-transform>
<tp-text-transform truncate="start">/workspace/marketing/campaigns/autumn-launch/brief.pdf</tp-text-transform>
</div>
</tp-resizable-panel>
<tp-resizable-handle label="Resize the list" with-handle></tp-resizable-handle>
<tp-resizable-panel min-size="20%"></tp-resizable-panel>
</tp-resizable-panel-group>
While shortened, the value can be focused and shows the full text in a tooltip; tooltip="false" removes the tooltip and the tab stop. Assistive technology always hears the complete text once. Inside a flex or grid track the element can shrink below its full text without changing height. The tooltip repeats the full text visually only, so it is not announced twice. Updates are never announced through a live region.
Length limits
max-length caps the characters or words kept. On its own it cuts at the end and the text still wraps; with truncate, the cap applies on top of the width and the omission goes where truncate places it.
Length limits
Default density
Compact density
Restart from the initial state
Show the copyable source
Thanks for the quick turnaround on the pricing page copy, it reads much better now.Thanks for the quick turnaround on the pricing page copy, it reads much better now.design-review-2026-10-14-final-screenshots.zip
Thanks for the quick turnaround on the pricing page copy, it reads much better now.Thanks for the quick turnaround on the pricing page copy, it reads much better now.design-review-2026-10-14-final-screenshots.zip
<div style="display:grid;gap:var(--tp-space-2);font-size:var(--tp-text-sm)">
<tp-text-transform max-length="32">Thanks for the quick turnaround on the pricing page copy, it reads much better now.</tp-text-transform>
<tp-text-transform max-length="6" truncate-by="words">Thanks for the quick turnaround on the pricing page copy, it reads much better now.</tp-text-transform>
<tp-text-transform max-length="24" truncate="middle">design-review-2026-10-14-final-screenshots.zip</tp-text-transform>
</div>
Formatters
The formatter property replaces the preset for one element. It receives a context with the input, the locale and apply(), which runs any preset, and returns text, or { text, accessibleText } when assistive technology should hear something else. Its output is always text, never markup. A formatter that throws or returns something else emits one tp-diagnostic and the preset presents instead.
Formatter
Default density
Compact density
Restart from the initial state
Show the copyable source
For options beyond the attributes, assign Intl.NumberFormatOptions to the format property, or { style, guide } for duration. Options resolve in this order, each overriding the previous: the preset’s defaults, then currency, unit and decimals, then format. A currency preset without a currency, or a unit preset without a unit, formats a plain number. Options that Intl rejects fall back to the preset’s defaults.
Named presets
defineTextPreset(name, definition) from @tweakpad/ui names a format once for the whole page, either a built-in preset with options or a formatter. Elements then use it like any preset, and every element with that name updates when it is defined or replaced. Built-in names are reserved.
Named presets
Default density
Compact density
Restart from the initial state
Show the copyable source
Team plan per yearBusiness plan per yearAssigned to
Team plan per yearBusiness plan per yearAssigned to
<div style="display:grid;gap:var(--tp-space-2);font-size:var(--tp-text-sm)">
<span>Team plan <tp-text-transform preset="plan-price" value="480"></tp-text-transform> per year</span>
<span>Business plan <tp-text-transform preset="plan-price" value="1200"></tp-text-transform> per year</span>
<span>Assigned to <tp-text-transform preset="desk" value="14"></tp-text-transform></span>
</div>
<script type="module">
import { defineTextPreset } from '@tweakpad/ui';
defineTextPreset('plan-price', { preset: 'currency', format: { currency: 'EUR', maximumFractionDigits: 0 } });
defineTextPreset('desk', ({ value }) => ({
text: `D-${String(value).padStart(3, '0')}`,
accessibleText: `Desk ${value}`,
}));
</script>
An element that names a preset before it exists shows its input as text until the definition arrives. The same goes for input a numeric preset cannot read: it stays as written, and the element exposes data-invalid for styling.
Unreadable input
Default density
Compact density
Restart from the initial state
Show the copyable source
Launch price to be announced
Launch price to be announced
<p style="margin:0;font-size:var(--tp-text-sm)">Launch price <tp-text-transform preset="currency" currency="USD">to be announced</tp-text-transform></p>
Functions
ExportBehaviordefineTextPreset(name, definition)Defines a page-wide preset (a formatter or { preset, format }); returns a remove function.transformText(input, options)The same transform outside the DOM; returns { text, accessibleText, machineValue, invalid, diagnostics }.TEXT_PRESETS, isBuiltInTextPreset(name)The built-in preset names.
API Reference
Every element also accepts motion-policy.
Attributes
AttributePropertyTypeDefaultDescriptionvaluevalueunknownundefinedNumber, bigint or text; the trimmed light-DOM text is read when unset.presetpresetstring'text'A built-in or Consumer preset name.currencycurrencystring''Currency code of the currency preset.unitunitstring''Unit identifier of the unit preset.decimalsdecimalsnumber | nullnullExact number of fraction digits, from 0 to 20.localelocalestring''Formatting and case-mapping locale; the owner locale when empty.truncatetruncateTruncatePosition'none'Where the omission goes: none, start, middle or end.truncate-bytruncateByTruncateUnit'chars'The unit truncation removes: chars (grapheme clusters) or words.max-lengthmaxLengthnumber | nullnullThe most units kept; truncates at the end when truncate is none.tooltiptooltipbooleantrueShows the complete text in a Tooltip while the text is truncated.
Properties
PropertyTypeDefaultDescriptionformatTextFormatOptions | undefined—Preset options: number format options, or { style, guide } for durations.formatterTextFormatter | undefined—Replaces the preset; returns text or { text, accessibleText }.textread-onlystring—The complete presented text, before truncation.accessibleTextread-onlystring—The complete text for assistive technology: the long form of abbreviated text.truncatedread-onlyboolean—Whether the presented text is shortened.
Slots
SlotDescriptiondefaultFallback content: the input when value is unset, and the presentation when a numeric preset cannot read the input.
CSS parts
PartDescription::part(text-transform-description)The Tooltip showing the complete text while the text is shortened.::part(text-transform-value)The presented text: a data element carrying the raw number for numeric input.