layrz_ui_extensions 0.0.4
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
LayrzUiL10nlookups through thelayrz_i18ntranslation engine.layrz_uideclares the contract with 133 English strings but has no i18n dependency; this adapter enables translation. Once registered, everylayrz_uicomponent automatically picks up your translations. - SDK model conversions (coming soon) — Adapters converting
layrz_sdktypes intolayrz_uiview types, solayrz_uiitself needs no dependency onlayrz_sdk. - go_router transition bridge —
LayrzTransitionPage, aCustomTransitionPagepre-wired with alayrz_uipage transition and the design system's transition duration, so a go_router app no longer repeats the sametransitionsBuilder/transitionDurationboilerplate 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 #
- Initialize the
layrz_i18nengine 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));
}
- Register
LayrzUiI18nDelegatein 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(),
);
}
}
- That's it. Every
layrz_uicomponent readingcontext.l10nnow 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_uiis purely a design system — no translation engine, no SDK, no heavy dependencieslayrz_ui_extensionscontains adapters that route lookups and conversions through dependent packages- Each adapter is optional; apps choose which ones they need
This means:
- Apps using
layrz_uiwithout i18n or SDK conversions have zero overhead - Apps using different translation engines or model types can build their own adapters
- Both
layrz_uiand its dependencies can evolve and release independently
Documentation #
For complete guides on layrz_ui, see the GitHub Wiki:
- Getting Started — Set up
LayrzAppand preload fonts - Theming — Access design tokens in your widgets
- Design Tokens — Complete reference of colors, typography, spacing, and more
- Component Catalog — Browse all available components
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.