Tinyrack

Theme

Apply the Tinyrack Material 3 light and dark themes.

Apply both themes at the application boundary:

MaterialApp(
  theme: TinyrackTheme.light(),
  darkTheme: TinyrackTheme.dark(),
  themeMode: ThemeMode.system,
  home: const App(),
);

Both themes use Material 3 and install TinyrackThemeData as a ThemeExtension. They map the semantic surface color to Material's canvas and scaffold background, so routed pages use the same light or dark page surface by default. Read semantic colors from context.tinyrackTheme when a custom widget needs the same intent colors as Tinyrack components. Flutter focus, keyboard, gesture, semantics, and text scaling behavior remains native.

The package bundles 11 IBM Plex Sans, Mono, Korean, and Japanese font files. They total about 16.4 MB before platform packaging and are included in the application’s Flutter asset bundle. No runtime font download is required.

UI density

Use TRUiDensityScope when a product needs a more readable interface on a narrow or touch-first surface. The product owns the responsive condition. The scope maps standard to the existing defaults and comfortable to 48-pixel TRUiSize.xl controls, one-step-larger typography, roomier default cards, and larger status indicators.

LayoutBuilder(
  builder: (context, constraints) => TRUiDensityScope(
    density: constraints.maxWidth < TRBreakpoints.small
        ? TRUiDensity.comfortable
        : TRUiDensity.standard,
    child: const AppContent(),
  ),
);

Set uiSize or card padding directly when a component must stay fixed. Explicit sm, md, lg, and xl values override the scope. System text scaling continues to apply on top of the density-selected typography.

Flutter-rendered popup rows resolve separately from their anchor control. Standard density uses TRUiSize.sm row metrics (28-pixel height and 12-pixel labels), while comfortable density uses TRUiSize.lg row metrics (40-pixel height and 14-pixel labels). Menus, submenus, menubars, Flutter context menus, selects, autocompletes, comboboxes, and inline suggestions retain the anchor's density even in a root overlay. A menu's explicit uiSize still changes only its trigger; nest a standard scope around the anchor to keep that popup compact.

Page transitions

Both themes install TRPageTransitionsBuilder for every TargetPlatform. Android uses Flutter's predictive Back transition, while iOS, macOS, Linux, and Windows use Material forward-fade motion. The builder returns the page without motion when the platform reports disableAnimations.

Install a different builder only when a routed region needs another motion contract. Use TRPageTransitionsBuilder.none() when Pages must retain their route lifecycle and identity while a fixed region stays visually still:

ThemeData theme = TinyrackTheme.light().copyWith(
  pageTransitionsTheme: const PageTransitionsTheme(
    builders: <TargetPlatform, PageTransitionsBuilder>{
      TargetPlatform.windows: TRPageTransitionsBuilder.none(),
    },
  ),
);

Cross-platform component contract

React and Flutter share semantic tokens and component purposes where both platforms provide the same concept. They do not promise identical public APIs, anatomy, interaction details, or rendered pixels.

BeforeNow
Alert and Badge intentvariant: TRStatusVariant.*
IconButton without visual or loading optionsappearance, loading, and loadingLabel
Free-form Card paddingTRCardPadding, TRCardVariant, and the Card anatomy widgets
Spinner inherited color onlyvariant: TRSpinnerVariant.*
Text role, TRTextStyle, and arbitrary colorsTRTextVariant plus typed color, align, weight, and truncate

Flutter Form lifecycle properties on TRTextField remain available. Repository checks classify every public component as a shared purpose, an explicit adaptation, or a platform-only capability. React browser tests and Flutter widget and golden tests enforce behavior and appearance within their own rendering engines.