omni_pixel 0.3.1 copy "omni_pixel: ^0.3.1" to clipboard
omni_pixel: ^0.3.1 copied to clipboard

Figma-first responsive sizing for Flutter. Register the device frames your designers use, then write 48.opx to get pixel-perfect scaling on any screen.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:omni_pixel/omni_pixel.dart';

void main() => runApp(const OmniPixelExampleApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'omni_pixel example',
      theme: ThemeData(colorSchemeSeed: Colors.indigo, useMaterial3: true),
      // Put OmniBuilder in MaterialApp.builder so every route is covered.
      builder: (context, child) => OmniBuilder(
        // The Figma frames your designers used:
        devices: const [
          OmniDevices.iphone17,
        ],
        // Fine-tuning per aspect-ratio range and platform:
        multipliers: const [
          // Very tall Androids render a touch smaller.
          OmniMultiplier.above(2.2, 0.97, platform: OmniPlatform.android),
          // Squarish screens (tablets, split screen) get a little more air.
          OmniMultiplier.below(1.6, 1.05),
        ],
        // Floating bubble with everything OmniPixel resolved. Drag it
        // around, tap to expand. Hidden in release builds.
        debugOverlay: true,
        child: child!,
      ),
      home: const DemoPage(),
    );
  }
}

/// Recreates a card specced in Figma on the registered iPhone 17 frame:
/// card 343 wide, radius 16, padding 20, title 20, body 14, button 48.
class DemoPage extends StatelessWidget {
  const DemoPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('omni_pixel')),
      body: Center(
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              // --- The Figma card, written with the exact Figma numbers ---
              Container(
                width: 343.opx,
                padding: EdgeInsets.all(20.opx),
                decoration: BoxDecoration(
                  color: Theme.of(context).colorScheme.primaryContainer,
                  borderRadius: BorderRadius.circular(16.opx),
                ),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Pixel-perfect from Figma',
                      style: TextStyle(
                        fontSize: 20.opx,
                        fontWeight: FontWeight.w700,
                      ),
                    ),
                    SizedBox(height: 8.opx),
                    Text(
                      'Every number on this card is the raw value from the '
                      'design file, written as value.opx. It scales with the '
                      'longest side of this screen relative to the design '
                      'frame.',
                      style: TextStyle(fontSize: 14.opx, height: 1.4),
                    ),
                    SizedBox(height: 20.opx),
                    SizedBox(
                      width: double.infinity,
                      height: 48.opx, // 48 px button in Figma
                      child: FilledButton(
                        onPressed: () {},
                        child: Text(
                          'Continue',
                          style: TextStyle(fontSize: 16.opx),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              SizedBox(height: 4.dh), // classic helpers still work
              // --- What the helpers evaluate to on this screen ---
              // Everything OmniPixel *resolved* (design device, scale,
              // multiplier, device class...) lives in the floating debug
              // bubble instead — see debugOverlay above.
              Container(
                width: 90.dw,
                padding: EdgeInsets.all(12.opx),
                decoration: BoxDecoration(
                  color: Theme.of(context).colorScheme.secondaryContainer,
                  borderRadius: BorderRadius.circular(12.opx),
                ),
                child: DefaultTextStyle(
                  style: TextStyle(
                    fontSize: 12.opx,
                    fontFamily: 'monospace',
                    color: Theme.of(context).colorScheme.onSurface,
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text('48.opx : ${48.opx.toStringAsFixed(2)}'),
                      Text('10.h   : ${10.h.toStringAsFixed(2)}'),
                      Text('10.w   : ${10.w.toStringAsFixed(2)}'),
                    ],
                  ),
                ),
              ),
              SizedBox(height: 16.opx),
              // --- Device class + orientation, live ---
              OmniResponsiveBuilder(
                watch: _chip('watch', Colors.purple),
                mobile: _chip('mobile', Colors.blue),
                tablet: _chip('tablet', Colors.orange),
                desktop: _chip('desktop', Colors.red),
              ),
              SizedBox(height: 8.opx),
              OmniOrientationBuilder(
                portrait: (context) => _chip('portrait', Colors.green),
                landscape: (context) => _chip('landscape', Colors.pink),
              ),
            ],
          ),
        ),
      ),
    );
  }

  /// A colored pill used by the responsive / orientation demos above.
  Widget _chip(String label, Color color) => Container(
        padding: EdgeInsets.symmetric(horizontal: 16.opx, vertical: 8.opx),
        decoration: BoxDecoration(
          color: color,
          borderRadius: BorderRadius.circular(999),
        ),
        child: Text(
          label,
          style: TextStyle(color: Colors.white, fontSize: 14.opx),
        ),
      );
}
3
likes
160
points
156
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Figma-first responsive sizing for Flutter. Register the device frames your designers use, then write 48.opx to get pixel-perfect scaling on any screen.

Repository (GitHub)
View/report issues

Topics

#responsive #sizing #layout #figma #orientation

License

MIT (license)

Dependencies

flutter

More

Packages that depend on omni_pixel