Skip to content

Static Functions

Overview

Static functions are available in every EL expression without additional setup. They accept expressions as arguments, so you can compose them — length(replaceAll(user.name, ' ', '')) works the same as any other nested call. See Rules for the full EL evaluation model.

XWidget also registers a small set of application functions during XWidget.initialize(). Those functions are not part of the core xwidget_el package, but they are available in XWidget fragments after initialization. See XWidget-Registered Functions.

Functions

abs

Absolute value.

num abs(dynamic value);
<Text data="${abs(-42)}"/>

ceil

Round up to nearest integer.

int ceil(dynamic value);
<Text data="${ceil(3.2)}"/>

clamp

Clamp a value to a range. Returns lower if value is below the range, upper if above, otherwise returns the value unchanged. All values must be [Comparable].

dynamic clamp(dynamic value, dynamic lower, dynamic upper);
<Container width="${clamp(barWidth, 20, 300)}"/>
<Opacity opacity="${clamp(progress, 0.0, 1.0)}"/>

contains

Check if a value contains a search value.

bool contains(dynamic value, dynamic searchValue);
<if test="${contains('Hello, World!', 'World')}">
    <!-- true condition -->
    <else>
        <!-- optional false condition -->
    </else>
</if>

containsKey

Check if a map contains a key.

bool containsKey(Map? map, dynamic searchKey);
<if test="${containsKey(myMap, 'userId')}">
    <!-- true condition -->
</if>

containsValue

Check if a map contains a value.

bool containsValue(Map? map, dynamic searchValue);
<if test="${containsValue(myMap, 'admin')}">
    <!-- true condition -->
</if>

diffDateTime

Calculate duration between two dates.

Duration diffDateTime(DateTime left, DateTime right);
<Text data="${diffDateTime(now(), startDate)}"/>

endsWith

Check if a string ends with a value.

bool endsWith(String value, String searchValue);
<if test="${endsWith(fileName, '.dart')}">
    <!-- true condition -->
</if>

eval

Evaluate an expression string.

dynamic eval(String? value);
<Text data="${eval('2 + 2')}"/>

first

Get first element of a collection.

dynamic first(dynamic value);
<Text data="${first(myList)}"/>

floor

Round down to nearest integer.

int floor(dynamic value);
<Text data="${floor(3.7)}"/>

formatBytes

Format a byte count into a human-readable string with unit suffix (B, KB, MB, GB, TB).

String formatBytes(dynamic value, [int decimalPlaces = 1]);
<Text data="${formatBytes(bundleSize, 1)}"/>
<!-- 14200 -> "13.9 KB", 1048576 -> "1.0 MB" -->

formatCompact

Format a number with a compact suffix (K, M, B, T). Trailing zeros are removed.

String formatCompact(dynamic value, [int decimalPlaces = 1]);
<Text data="${formatCompact(totalUsers)}"/>
<!-- 1200 -> "1.2K", 3400000 -> "3.4M" -->

formatDateTime

Format a DateTime with a pattern.

String? formatDateTime(String format, dynamic value);
<Text data="${formatDateTime('yyyy-MM-dd', now())}"/>

formatDuration

Format a Duration with specified precision.

String? formatDuration(Duration? value, [String precision = "s", DurationFormat? format = defaultDurationFormat]);
<Text data="${formatDuration(myDuration, 'ms')}"/>

formatElapsed

Format a DateTime as a relative time string (e.g. "5 minutes ago", "in 3 hours"). Returns "just now" for durations under 60 seconds in the past, and "in a moment" for durations under 60 seconds in the future.

String formatElapsed(dynamic value);
<Text data="${formatElapsed(lastSeen)}"/>
<!-- "2 minutes ago", "3 hours ago", "5 days ago" -->

formatNumber

Format a number using an ICU/intl pattern string. Supports grouping separators, decimal places, percentages, and currency symbols.

String formatNumber(dynamic value, String pattern);
<Text data="${formatNumber(totalRenders, '#,##0')}"/>
<!-- 24891 -> "24,891" -->

<Text data="${formatNumber(price, '#,##0.00')}"/>
<!-- 3.14159 -> "3.14" -->

formatOrdinal

Format an integer with an English ordinal suffix (st, nd, rd, th). Correctly handles teen exceptions (11th, 12th, 13th).

String formatOrdinal(dynamic value);
<Text data="${formatOrdinal(rank)}"/>
<!-- 1 -> "1st", 2 -> "2nd", 3 -> "3rd", 11 -> "11th" -->

formatPercent

Format a number as a percentage string. Multiplies the value by 100 and appends '%'.

String formatPercent(dynamic value, [int decimalPlaces = 0]);
<Text data="${formatPercent(changeRate, 1)}"/>
<!-- 0.123 -> "12.3%", 0.5 -> "50%" -->

formatPlural

Format a count with a singular or plural label. Uses the singular form when the absolute value of count is 1.

String formatPlural(dynamic count, String singular, String plural);
<Text data="${formatPlural(errorCount, 'error', 'errors')}"/>
<!-- 0 -> "0 errors", 1 -> "1 error", 5 -> "5 errors" -->

isBlank

Check if a value is blank (null, empty, or whitespace).

bool isBlank(dynamic value);
<if test="${isBlank(userName)}">
    <!-- true condition -->
</if>

isEmpty

Check if a value is empty.

bool isEmpty(dynamic value);
<if test="${isEmpty(myList)}">
    <!-- true condition -->
    <else>
        <!-- optional false condition -->
    </else>
</if>

isFalse

Check if a value evaluates to boolean false. Uses toBool for conversion.

bool isFalse(dynamic value);
<if test="${isFalse(isEnabled)}">
    <!-- true condition -->
</if>

isFalseOrNull

Check if a value is false or null.

bool isFalseOrNull(dynamic value);
<if test="${isFalseOrNull(isEnabled)}">
    <!-- true condition -->
</if>

isNotBlank

Check if a value is not blank.

bool isNotBlank(dynamic value);
<if test="${isNotBlank(userName)}">
    <!-- true condition -->
</if>

isNotEmpty

Check if a value is not empty.

bool isNotEmpty(dynamic value);
<if test="${isNotEmpty(myList)}">
    <!-- true condition -->
</if>

isNotNull

Check if a value is not null.

bool isNotNull(dynamic value);
<if test="${isNotNull(userId)}">
    <!-- true condition -->
</if>

isNull

Check if a value is null.

bool isNull(dynamic value);
<if test="${isNull(userId)}">
    <!-- true condition -->
</if>

isTrue

Check if a value evaluates to boolean true. Uses toBool for conversion.

bool isTrue(dynamic value);
<if test="${isTrue(isEnabled)}">
    <!-- true condition -->
</if>

isTrueOrNull

Check if a value is true or null.

bool isTrueOrNull(dynamic value);
<if test="${isTrueOrNull(isEnabled)}">
    <!-- true condition -->
</if>

last

Get last element of a collection.

dynamic last(dynamic value);
<Text data="${last(myList)}"/>

length

Get length of a collection or string.

int length(dynamic value);
<Text data="${length('Hello')}"/>

logDebug

Log a debug message.

void logDebug(dynamic message);
<!-- expressions evaluate at inflation time; use <callback> to defer to the tap -->
<Button>
    <callback for="onPressed" action="logDebug('Button clicked')"/>
    <Text data="Click me"/>
</Button>

matches

Check if a string matches a regular expression. The entire string must match — a pattern that matches only part of the value returns false, so contains-style partial matching needs explicit wildcards (e.g. '.*ing').

bool matches(String? value, String regExp);
<if test="${matches(email, '^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$')}">
    <!-- true condition -->
</if>

max

Return the larger of two values. Both values must be [Comparable]. If either value is null, the non-null value is returned.

dynamic max(dynamic a, dynamic b);
<Container height="${max(barHeight, 4)}"/>

min

Return the smaller of two values. Both values must be [Comparable]. If either value is null, the non-null value is returned.

dynamic min(dynamic a, dynamic b);
<Container width="${min(contentWidth, 400)}"/>

now

Get current DateTime.

DateTime now();
<Text data="${now()}"/>

nowUtc

Get current DateTime in UTC.

DateTime nowUtc();
<Text data="${nowUtc()}"/>

randomDouble

Generate a random double between 0.0 and 1.0.

double randomDouble();
<Text data="${randomDouble()}"/>

randomInt

Generate a random integer.

int randomInt(int max);
<Text data="${randomInt(100)}"/>

replaceAll

Replace all occurrences in a string.

String? replaceAll(String? value, String regex, String replacement);
<Text data="${replaceAll('I enjoy programming', 'enjoy', 'love')}"/>

replaceFirst

Replace first occurrence in a string.

String? replaceFirst(String? value, String regex, String replacement, [int startIndex = 0]);
<Text data="${replaceFirst('test test', 'test', 'demo')}"/>

round

Round to nearest integer.

int round(dynamic value);
<Text data="${round(3.7)}"/>

startsWith

Check if a string starts with a value.

bool startsWith(String value, String searchValue);
<if test="${startsWith('Dart is fun', 'Dart')}">
    <!-- true condition -->
    <else>
        <!-- optional false condition -->
    </else>
</if>

substring

Extract a substring.

String? substring(String? value, int start, [int end = -1]);
<Text data="${substring('Hello World', 0, 5)}"/>

toBool

Convert to boolean.

bool? toBool(dynamic value);
<Text data="${toBool('true')}"/>

toColor

Convert to Color.

Color? toColor(dynamic value);
<Container color="${toColor('#FF5733')}"/>

toDateTime

Convert to DateTime.

DateTime? toDateTime(dynamic value);
<Text data="${toDateTime('2024-01-01')}"/>

toDays

Convert to days.

int? toDays(dynamic value);
<Text data="${toDays(myDuration)}"/>

toDouble

Convert to double.

double? toDouble(dynamic value);
<Text data="${toDouble('3.14')}"/>

toDuration

Convert to Duration.

Duration? toDuration(dynamic value, [String? intUnit]);
<Text data="${toDuration(3600, 's')}"/>

toHours

Convert to hours.

int? toHours(dynamic value);
<Text data="${toHours(myDuration)}"/>

toInt

Convert to integer.

int? toInt(dynamic value);
<Text data="${toInt('123')}"/>

toMillis

Convert to milliseconds.

int? toMillis(dynamic value);
<Text data="${toMillis(myDuration)}"/>

toMinutes

Convert to minutes.

int? toMinutes(dynamic value);
<Text data="${toMinutes(myDuration)}"/>

toSeconds

Convert to seconds.

int? toSeconds(dynamic value);
<Text data="${toSeconds(myDuration)}"/>

toString

Convert to string.

String? toString(dynamic value);
<Text data="${toString(42)}"/>

tryToBool

Try to convert to boolean, returns null on failure.

bool? tryToBool(dynamic value);
<Text data="${tryToBool(userInput)}"/>

tryToColor

Try to convert to Color, returns null on failure.

Color? tryToColor(dynamic value);
<Container color="${tryToColor(userColor)}"/>

tryToDateTime

Try to convert to DateTime, returns null on failure.

DateTime? tryToDateTime(dynamic value);
<Text data="${tryToDateTime(userInput)}"/>

tryToDays

Try to convert to days, returns null on failure.

int? tryToDays(dynamic value);
<Text data="${tryToDays(userInput)}"/>

tryToDouble

Try to convert to double, returns null on failure.

double? tryToDouble(dynamic value);
<Text data="${tryToDouble(userInput)}"/>

tryToDuration

Try to convert to Duration, returns null on failure.

Duration? tryToDuration(dynamic value, [String? intUnit]);
<Text data="${tryToDuration(userInput, 's')}"/>

tryToHours

Try to convert to hours, returns null on failure.

int? tryToHours(dynamic value);
<Text data="${tryToHours(userInput)}"/>

tryToInt

Try to convert to integer, returns null on failure.

int? tryToInt(dynamic value);
<Text data="${tryToInt(userInput)}"/>

tryToMillis

Try to convert to milliseconds, returns null on failure.

int? tryToMillis(dynamic value);
<Text data="${tryToMillis(userInput)}"/>

tryToMinutes

Try to convert to minutes, returns null on failure.

int? tryToMinutes(dynamic value);
<Text data="${tryToMinutes(userInput)}"/>

tryToSeconds

Try to convert to seconds, returns null on failure.

int? tryToSeconds(dynamic value);
<Text data="${tryToSeconds(userInput)}"/>

XWidget-Registered Functions

The functions in this section are registered by XWidget during XWidget.initialize(). Use them in fragments when you need access to XWidget resources, navigation helpers, or the global navigator key.

resBool

Returns a boolean value resource by name.

bool resBool(String name);
<if test="${resBool('show_advanced_filters')}">
    <!-- advanced filters -->
</if>

resColor

Returns a color value resource by name.

Color resColor(String name);
<Container color="${resColor('accent')}" />

resColorString

Returns a color value resource as a string.

String resColorString(String name);
<Text data="${resColorString('accent')}" />

resDouble

Returns a double value resource by name.

double resDouble(String name);
<SizedBox height="${resDouble('chart_height')}" />

resInt

Returns an integer value resource by name.

int resInt(String name);
<Text data="${resInt('page_size')}" />

resString

Returns a string value resource by name.

String resString(String name);
<Text data="${resString('usage_title')}" />

For static attribute values, prefer resource directives such as @string/usage_title or @color/accent. Use the res* functions when an attribute needs an expression or computed value. See Resources for resource declarations and lookup behavior.

routeTo

Returns a callback that navigates to a route by path or name. Use it in XML attributes such as onPressed or onTap.

VoidCallback routeTo(String target, [String? action]);
<TextButton onPressed="${routeTo('/settings')}">
    <Text data="Settings" />
</TextButton>

<ElevatedButton onPressed="${routeTo('/login', 'pushAndRemoveAll')}">
    <Text data="Log Out" />
</ElevatedButton>

The optional action argument is parsed as a NavigatorAction value. If it is omitted or invalid, XRouter uses NavigatorAction.push.

routePop

Returns a callback that pops the current Navigator route.

VoidCallback routePop();
<TextButton onPressed="${routePop()}">
    <Text data="Go Back" />
</TextButton>

routePopAll

Returns a callback that pops Navigator routes until the root route remains.

VoidCallback routePopAll();
<TextButton onPressed="${routePopAll()}">
    <Text data="Return to Root" />
</TextButton>

routeTo, routePop, and routePopAll operate through XRouter and XWidget.navigatorKey. See Routing for route definitions, callback routes, browser history, and Navigator actions.

Returns XWidget's global navigator key. Use it when assigning navigatorKey on the root app widget.

GlobalKey<NavigatorState> navigatorKey();
<MaterialApp
    xmlns="https://xwidget.dev/fragments"
    navigatorKey="${navigatorKey()}">
    ...
</MaterialApp>

See the Navigator Key section for setup details.