Skip to content

Platform And Extensions

Kenny Mochizuki Escalona edited this page Aug 21, 2026 · 4 revisions

Platform and Extensions

Utilities for runtime platform detection and convenience extensions on Color and BuildContext.


LayrzPlatform: Runtime Platform Detection

LayrzPlatform is an enum identifying the current runtime platform. It is a Material-free equivalent of ThemedPlatform from layrz_theme.

Enum Values

Value Platform
web Web compiled with CanvasKit
webWasm Web compiled with WebAssembly (WASM)
android Google Android
iOS Apple iOS
macOS Apple macOS
windows Microsoft Windows
linux GNU/Linux
fuchsia Google Fuchsia
unknown Unrecognized platform

Static Predicates

Check the current platform:

// The current platform
LayrzPlatform.current

// Check specific platforms
LayrzPlatform.isWeb       // true on web (CanvasKit or WASM)
LayrzPlatform.isWebWasm   // true on WASM specifically
LayrzPlatform.isAndroid   // true on Android
LayrzPlatform.isIOS       // true on iOS
LayrzPlatform.isMacOS     // true on macOS
LayrzPlatform.isWindows   // true on Windows
LayrzPlatform.isLinux     // true on Linux
LayrzPlatform.isFuchsia   // true on Fuchsia

// Grouped checks
LayrzPlatform.isMobile    // true on Android or iOS
LayrzPlatform.isDesktop   // true on macOS, Windows, or Linux

Example: Platform-Specific Layout

Widget build(BuildContext context) {
  if (LayrzPlatform.isMobile) {
    return MobileLayout();
  }
  if (LayrzPlatform.isDesktop) {
    return DesktopLayout();
  }
  if (LayrzPlatform.isWeb) {
    return WebLayout();
  }
  return FallbackLayout();
}

Enum String Representation

// Friendly string representation
print(LayrzPlatform.web.toString());      // 'Web (CanvasKit)'
print(LayrzPlatform.webWasm.toString());  // 'Web (WASM)'
print(LayrzPlatform.iOS.toString());      // 'Apple iOS'

LayrzColorExtensions: Color Utilities

Extensions on Color for hex serialization, integer conversion, and contrast utilities.

Hex Serialization

Convert a color to a hex string:

final color = Color(0xFF001E60);

// 6-digit hex without alpha
color.toHex()          // '#001E60'
color.hex              // '#001E60' (alias)

// 8-digit hex with alpha
color.toHexWithAlpha() // '#FF001E60'
color.hexWithAlpha     // '#FF001E60' (alias)

Integer Encoding

Encode a color as a 32-bit ARGB integer:

final color = Color(0xFF001E60);
final argb = color.toInt(); // 0xFF001E60

Hex Deserialization

Parse a hex string into a color:

// Static methods on the extension
final color1 = LayrzColorExtensions.fromHex('#001E60');
final color2 = LayrzColorExtensions.fromHex('001E60'); // # is optional

// With alpha
final color3 = LayrzColorExtensions.fromHexWithAlpha('#FF001E60');

// JSON shorthand
final color4 = LayrzColorExtensions.fromJson('#001E60');

Note: These are static methods on the extension, not instance methods. Call them as:

// Correct
LayrzColorExtensions.fromHex('#001E60')

// Incorrect — this would not compile
Color color = Color.fromHex('#001E60') // Error: no such method

Contrast Color

Get black or white, whichever has better contrast against a given color:

final backgroundColor = Color(0xFFFFFFFF); // White
final textColor = backgroundColor.contrastColor; // Returns black

final darkBackground = Color(0xFF001E60); // Dark navy
final textColor = darkBackground.contrastColor; // Returns white

Uses the WCAG relative luminance formula with a 0.179 threshold.

Opacity Control

Create a copy of a color with a different opacity:

final color = Color(0xFF001E60);
final semi = color.withOpacityValue(0.5);  // 50% opacity
final invisible = color.withOpacityValue(0.0); // Fully transparent

Flattening Translucent Colors

Composite a translucent color onto a background and return an opaque result that is pixel-identical when painted over that background:

final accent = Color(0xFFFF8200);
final tonal = accent.withOpacityValue(0.2); // 20% opacity

// Flatten onto the surface token (sf1 — canvas background) to create an opaque equivalent
final opaque = tonal.flattenOn(tokens.colors.sf1);

// opaque is now fully opaque and renders identically to tonal when painted on surface

Why this exists: A translucent fill lets anything painted behind it show through, including a BoxDecoration's shadow. Shadows render as a smudge inside the box rather than a shadow beneath it when the fill is translucent. Flattening the colour onto the surface it will actually be painted over yields the identical pixel colour while being fully opaque — so shadows render correctly.

Important caveat: The result is visually identical only when painted directly over [background]. If this colour will be painted over a different surface, the flattened result will be incorrect.

Opacity Checking

Check whether a color is fully opaque:

final color = Color(0xFF001E60); // Fully opaque
color.isOpaque; // true

final transparent = Color(0x80001E60); // 50% opacity
transparent.isOpaque; // false

Example: Serialization Round-trip

// Save
final color = Color(0xFF001E60);
final hex = color.toHex(); // '#001E60'
storage.writeString('brand_color', hex);

// Load
final hex = storage.readString('brand_color');
final color = LayrzColorExtensions.fromHex(hex);

LayrzContextExtensions: Quick Access

Extensions on BuildContext for quick access to theme values.

Convenience Properties

Extension Returns Equivalent
theme LayrzThemeData LayrzTheme.of(context)
tokens LayrzTokens LayrzTheme.of(context).tokens
tokenizer LayrzTokenizer LayrzTokenizer(context.tokens)
primaryColor Color LayrzTheme.of(context).primaryColor
titleStyle TextStyle Bold title style (18pt, fontWeight: bold)
subtitleStyle TextStyle Bold subtitle style (16pt, fontWeight: bold)
bodyStyle TextStyle Base body text style

Example: Quick Access

Widget build(BuildContext context) {
  return Column(
    children: [
      Text(
        'Title',
        style: context.titleStyle, // Bold 18pt
      ),
      Text(
        'Subtitle',
        style: context.subtitleStyle, // Bold 16pt
      ),
      Text(
        'Body text',
        style: context.bodyStyle, // Base text style
      ),
    ],
  );
}

Example: Theme-Aware Colors

Widget build(BuildContext context) {
  return Container(
    color: context.primaryColor,
    child: Text(
      'Primary colored background',
      style: context.theme.textStyle,
    ),
  );
}

Complete Example

class MyCard extends StatelessWidget {
  const MyCard({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: context.theme.surfaceColor,
        borderRadius: BorderRadius.circular(context.tokenizer.radius),
        boxShadow: context.tokens.shadow.elevation1,
      ),
      padding: context.tokenizer.padding,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            'Card Title',
            style: context.titleStyle,
          ),
          const SizedBox(height: 12),
          Text(
            'Card body text',
            style: context.bodyStyle,
          ),
        ],
      ),
    );
  }
}

Import

Import both utilities via the root barrel:

import 'package:layrz_ui/layrz_ui.dart';

// Available as:
LayrzPlatform.current
context.theme
color.toHex()

Related Decisions


Last updated: 2026-08-13
Related pages: Theming, Design-Tokens, Getting-Started

Clone this wiki locally