layrz_ui_extensions 0.0.4 copy "layrz_ui_extensions: ^0.0.4" to clipboard
layrz_ui_extensions: ^0.0.4 copied to clipboard

Adapters and extensions bridging layrz_sdk and other Layrz packages into layrz_ui, including i18n bindings and model conversions.

layrz_ui_extensions #

Adapters and extensions bridging Layrz packages into layrz_ui — including the layrz_i18n binding and conversions from layrz_sdk models into layrz_ui types.

AI-assisted code notice This package was developed with AI assistance. If you run into any issue or unexpected behavior, feel free to open a Pull Request — contributions are always welcome!


What is layrz_ui_extensions? #

layrz_ui_extensions is a collection of adapters and type converters that bridge Layrz ecosystem packages into layrz_ui, keeping the design system lightweight and decoupled from heavy dependencies.

Included:

  • i18n binding — Routes LayrzUiL10n lookups through the layrz_i18n translation engine. layrz_ui declares the contract with 133 English strings but has no i18n dependency; this adapter enables translation. Once registered, every layrz_ui component automatically picks up your translations.
  • SDK model conversions (coming soon) — Adapters converting layrz_sdk types into layrz_ui view types, so layrz_ui itself needs no dependency on layrz_sdk.
  • go_router transition bridgeLayrzTransitionPage, a CustomTransitionPage pre-wired with a layrz_ui page transition and the design system's transition duration, so a go_router app no longer repeats the same transitionsBuilder / transitionDuration boilerplate on every route.

Page transitions #

layrz_ui ships its page transitions (LayrzPageTransitions) as bare builder functions on purpose — the design system has exactly three dependencies and must not take on go_router as a fourth. That keeps layrz_ui lightweight, but it pushes the wiring onto every route a go_router app declares:

// Before — every route repeats this
GoRoute(
  path: '/detail',
  pageBuilder: (context, state) => CustomTransitionPage(
    key: state.pageKey,
    child: const DetailPage(),
    transitionsBuilder: LayrzPageTransitions.fade,
    transitionDuration: LayrzPageTransitions.durationOf(context),
  ),
);

layrz_ui_extensions is allowed to depend on go_router, so it is the right place for the missing convenience layer. LayrzTransitionPage collapses the snippet above to:

// After
GoRoute(
  path: '/detail',
  pageBuilder: (context, state) => LayrzTransitionPage.fade(
    key: state.pageKey,
    context: context,
    child: const DetailPage(),
  ),
);

A named constructor exists for every LayrzPageTransitions builder — .fade, .slide, .scale, .rotation, .none — plus an unnamed constructor that takes a LayrzTransitionType for callers holding a runtime value (for example, a single app-wide transition setting):

GoRoute(
  path: '/detail',
  pageBuilder: (context, state) => LayrzTransitionPage(
    type: settings.transitionType,
    key: state.pageKey,
    context: context,
    child: const DetailPage(),
  ),
);

LayrzTransitionPage<T> stays generic over the same pop-result type CustomTransitionPage<T> is, and forwards every parameter a real route needs — key, name, arguments, restorationId, maintainState, fullscreenDialog, opaque, barrierDismissible, barrierColor, barrierLabel.

Pass context when you have it. CustomTransitionPage.transitionDuration is a plain field read once, at construction time, by go_router's underlying route — unlike transitionsBuilder, it cannot be resolved lazily from a later, themed BuildContext. go_router's own pageBuilder: (context, state) => ... always hands back a context positioned under LayrzApp's installed theme, so passing it lets LayrzTransitionPage resolve the real LayrzPageTransitions.durationOf(context) token. Omit context (or use it from somewhere with no LayrzTheme ancestor) and it falls back to the raw kPageTransitionDuration constant (250ms) instead of throwing — the same value the token resolves to under a default theme. Pass transitionDuration explicitly to override either path.


Installation #

Add both packages to your pubspec.yaml:

dependencies:
  layrz_ui: ^0.0.9
  layrz_ui_extensions: ^0.0.2

layrz_ui_extensions requires layrz_ui >= 0.0.9 because that is where LayrzUiL10n was introduced. Both packages version independently.


Usage #

  1. Initialize the layrz_i18n engine with your translation data:
import 'package:layrz_i18n/layrz_i18n.dart';
import 'package:layrz_ui_extensions/layrz_ui_extensions.dart';

void main() async {
  final i18n = LayrzI18n(languages: [
    'en', 'es', 'pt',  // or your supported locales
  ]);
  await i18n.load();
  
  runApp(MyApp(i18n: i18n));
}
  1. Register LayrzUiI18nDelegate in your app before the default English fallback:
class MyApp extends StatelessWidget {
  final LayrzI18n i18n;
  const MyApp({required this.i18n});

  @override
  Widget build(BuildContext context) {
    return LayrzApp(
      title: 'My App',
      theme: LayrzThemeData.light(),
      localizationsDelegates: [
        LayrzUiI18nDelegate(i18n),      // Your custom translations
        const LayrzUiL10nDelegate(),    // English fallback
      ],
      supportedLocales: [
        const Locale('en'),
        const Locale('es'),
        const Locale('pt'),
      ],
      home: const HomePage(),
    );
  }
}
  1. That's it. Every layrz_ui component reading context.l10n now automatically uses your translations.

Important: The Delegate Type Requirement #

When implementing a custom localization delegate, you must type it over LayrzUiL10n, not a subclass.

// ✅ CORRECT
class MyDelegate extends LocalizationsDelegate<LayrzUiL10n> { ... }

// ❌ WRONG
class MyDelegate extends LocalizationsDelegate<LayrzUiI18n> { ... }

Why? Flutter's Localizations.of<T>() looks up delegates by their type parameter. If you type a delegate over a subclass, the resolver never finds it — it only looks for LocalizationsDelegate<LayrzUiL10n>. The result is silent fallback to English with no error message.

LayrzUiI18nDelegate follows this rule: it extends LayrzUiL10nDelegate and is typed over the base LayrzUiL10n, not LayrzUiI18n.


Translation Keys #

All 133 keys follow a dotted namespace pattern derived from the contract member names:

  • Actions: 'actions.cancel', 'actions.save', 'actions.reset', 'actions.search', 'actions.lint', 'actions.run'
  • Confirmations: 'confirmations.title', 'confirmations.content', 'confirmations.confirm', 'confirmations.dismiss', 'confirmations.multipleTitle', 'confirmations.multipleContent'
  • About: 'about.search', 'about.poweredBy', 'about.platformOS'
  • Calendar: 'calendar.yearBack', 'calendar.yearNext', 'calendar.monthBack', 'calendar.monthNext', 'calendar.today', 'calendar.monthShort', and eleven month names
  • Date-time pickers: 'dateTimePickers.from', 'dateTimePickers.to', 'dateTimePickers.selectDate', etc.
  • And 13 more namespaces covering dual lists, dynamic avatars, editors, files, helpers, maps, notifications, passwords, required fields, select inputs, tables, taskbars, and weekdays

Important: These keys are derived from member names and have not been verified against live translation data. The implementation is correct; the key names follow a consistent pattern. You must validate that your layrz_i18n engine has entries for all 133 keys before deployment.

Pluralization: Eight duration-related keys use the tc() method for singular/plural selection. The translation engine must provide these in ' | '-separated format:

'helpers.duration.days': '1 day | %count% days'
'helpers.duration.hours': '1 hour | %count% hours'
// ... and six more duration keys

Partial Translation #

You don't need to translate all 133 keys. Any key not present in the translation engine falls back to whatever layrz_i18n's default behavior is (typically the key name or English). Moreover, any key not overridden in LayrzUiI18n inherits its English default from LayrzUiL10n, so new keys added to layrz_ui in future releases will continue to work without requiring your adapter to be updated.


Decoupled Architecture #

This package keeps layrz_ui lightweight by extracting bridging logic into layrz_ui_extensions:

  • layrz_ui is purely a design system — no translation engine, no SDK, no heavy dependencies
  • layrz_ui_extensions contains adapters that route lookups and conversions through dependent packages
  • Each adapter is optional; apps choose which ones they need

This means:

  • Apps using layrz_ui without i18n or SDK conversions have zero overhead
  • Apps using different translation engines or model types can build their own adapters
  • Both layrz_ui and its dependencies can evolve and release independently

Documentation #

For complete guides on layrz_ui, see the GitHub Wiki:


License #

This project is licensed under the MIT License — see the LICENSE file for details.

Who are we? #

Golden M is a software and hardware development company working on innovative and disruptive technologies. For more information, contact us at sales@goldenm.com or via WhatsApp at +(507) 6979-3073.

0
likes
130
points
318
downloads

Documentation

Documentation
API reference

Publisher

verified publisherlayrz.com

Weekly Downloads

Adapters and extensions bridging layrz_sdk and other Layrz packages into layrz_ui, including i18n bindings and model conversions.

Repository (GitHub)
View/report issues

Topics

#i18n #localization #flutter-ui #design-system

License

MIT (license)

Dependencies

flutter, flutter_material_design_icons, flutter_mdi_remap, go_router, http, layrz_i18n, layrz_sdk, layrz_ui

More

Packages that depend on layrz_ui_extensions