vize 1.0.2 copy "vize: ^1.0.2" to clipboard
vize: ^1.0.2 copied to clipboard

Vize is a modern, developer-friendly Flutter package for effortless responsive UIs that match your Figma designs perfectly.

Vize #

Vize is a modern, developer-friendly Flutter package for effortless responsive UIs that match your Figma designs perfectly.

It offers two powerful approaches:

  • Percentage-based scaling for flexible responsive layouts
  • Figma-based scaling for pixel-perfect design implementation

Perfect for clean, production-ready apps and scalable design systems. No more responsiveness headaches!

Pub Points Build Status pub package License: MIT

Features #

Features #

  • Dual Scaling Approaches:
    • Percentage-Based Layouts: Flexible width/height sizing for responsive designs
    • Figma-Based Scaling: Direct pixel-perfect scaling from your Figma designs
  • Device Detection: Automatic mobile, tablet, desktop detection
  • Orientation Support: Portrait and landscape handling
  • Clean Syntax: Elegant extensions for both approaches
  • Backward Compatible: All existing code continues to work
  • Lightweight: Minimal overhead, maximum performance
  • Flexible: Customizable breakpoints and scaling

Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  vize: ^1.0.2

Then run:

flutter pub get

Quick Start #

1a. Initialize Vize #

Initialize Vize once in your app, typically in your root widget: The best way to initialize Vize is inside the builder of your MaterialApp. This ensures Vize stays updated whenever the screen size changes.

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

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

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

  @override
  Widget build(BuildContext context) {

    return const MaterialApp(
    builder: (context, child) {
    // Initialize Vize
    Vize.init(context, figmaWidth: 390, figmaHeight: 844);
    return child!;
    },
    home: const HomePage(),
    );
  }
}

2. Choose Your Approach #

Option A: Percentage-Based (Responsive Layouts)

Perfect for flexible designs that adapt to any screen:

Container(
  width: 50.w,    // 50% of screen width
  height: 30.h,   // 30% of screen height
  padding: 16.pa, // Percentage-based padding
  child: Text('Responsive Container'),
)

Option B: Figma-Based (Pixel-Perfect)

Perfect for implementing exact Figma designs:

Container(
  width: 375.fw,  // 375px scaled from Figma width
  height: 40.fh,  // 40px scaled from Figma height
  padding: 16.pa, // Figma-based padding
  child: Text('Figma Container'),
)

3. Use Reactive Layouts #

Wrap your screens in VizeLayout for automatic responsiveness:

VizeLayout(
  builder: (context, info) {
    return Scaffold(
      body: Container(
        width: 100.w,   // 100% of screen width (percentage-based)
        padding: 20.pa, // Figma-based padding
        child: Text("Device: ${info.device}"),
      ),
    );
  },
)

Usage Examples #

When to Use Each Approach #

Use Case Recommended Approach Example
Full-screen containers Percentage-based width: 100.w, height: 50.h
Figma design elements Figma-based width: 375.fw, height: 40.fh
Responsive spacing Percentage-based 5.hs, 10.ws
Exact Figma spacing Figma-based 40.fhs, 100.fws
Adaptive layouts Percentage-based w(80), h(25)
Pixel-perfect UI Figma-based fw(200), fh(100)

Percentage-Based Examples #

Perfect for flexible, responsive designs:

Column(
  children: [
    Container(
      width: w(100),  // Full width (100%)
      height: h(25),  // 25% of screen height
      color: Colors.blue,
    ),
    hs(2),  // 2% height spacing
    Container(
      width: w(80),   // 80% width
      height: h(50),  // 50% height
      color: Colors.green,
    ),
  ],
)

Figma-Based Examples #

Implement exact designs from Figma:

// Using helper functions
Container(
  width: fw(375),     // 375px scaled from Figma
  height: fh(40),     // 40px scaled from Figma
  padding: pa(16),   // 16px scaled padding
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(r(12)), // Always uses Figma scaling
  ),
)

// Or with extensions (even cleaner!)
Container(
  width: 375.fw,
  height: 40.fh,
  padding: 16.pa,
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(12.r), // .r always uses Figma scaling
  ),
)

Mixed Approach #

Combine both for the best results:

Container(
  width: w(90),      // 90% width (responsive)
  height: 200.fh,    // 200px from Figma (fixed ratio)
  child: Column(
    children: [
      16.fhs,        // Fixed 16px spacing from Figma
      Text('Mixed Layout', style: TextStyle(fontSize: 16.ts)),
      2.hs,          // 2% responsive spacing
    ],
  ),
)

Device-Specific Layouts #

Build different layouts for different devices:

VizeBuilder(
  mobile: (context) => const MobileLayout(),
  tablet: (context) => const TabletLayout(),
  desktop: (context) => const DesktopLayout(),
)

Or use conditional logic:

@override
Widget build(BuildContext context) {
  if (isMobile) {
    return const MobileLayout();
  } else if (isTablet) {
    return const TabletLayout();
  } else {
    return const DesktopLayout();
  }
}

Responsive Padding #

Multiple ways to add responsive padding:

// Vize-based padding
Container(padding: pa(16))    // padding on all sides
Container(padding: 16.pa)     // Same with extension

// Symmetric padding
Container(padding: ps(h: 20, v: 10))  // Percentage-based
Container(padding: Vize.I.ps(h: 20, v: 10))  // Figma-based

// Individual sides
Container(padding: po(l: 10, t: 20, r: 10, b: 20))  // Percentage-based

Spacing #

Easy spacing between widgets:

// Percentage-based spacing
Column(
  children: [
    const Text('Item 1'),
    hs(2),  // 2% height spacing
    2.hs,   // Same with extension
    const Text('Item 2'),
  ],
)

// Figma-based spacing
Column(
  children: [
    const Text('Item 1'),
    fhs(40),  // 40px spacing from Figma
    40.fhs,   // Same with extension
    const Text('Item 2'),
  ],
)

Standard Spacing (8px Grid) #

Use the sp() helper for standard spacing (always Figma-based):

Column(
  children: [
    const Text('Item 1'),
    SizedBox(height: sp()),    // 8px scaled from Figma
    const Text('Item 2'),
    SizedBox(height: sp(2)),   // 16px scaled from Figma
    const Text('Item 3'),
  ],
)

Adaptive Grid #

Create responsive grid layouts:

GridView.builder(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: adaptiveColumns(
      mobile: 2,
      tablet: 4,
      desktop: 6,
    ),
    crossAxisSpacing: sp(2),   // 16px scaled spacing
    mainAxisSpacing: sp(2),
  ),
  itemBuilder: (context, index) => const Card(child: Text('Item')),
)

Adaptive Values #

Return different values based on device:

final fontSize = adaptiveValue(
  mobile: 14.0,
  tablet: 16.0,
  desktop: 18.0,
);

final columns = adaptiveValue(
  mobile: 1,
  tablet: 2,
  desktop: 3,
);

Helper Functions #

Percentage-Based Helpers

Function Description Example
w(percent) Width percentage w(50) → 50% of screen width
h(percent) Height percentage h(25) → 25% of screen height
ws(percent) Width spacing ws(5) → SizedBox(width: 5%)
hs(percent) Height spacing hs(2) → SizedBox(height: 2%)
ps({h, v}) Symmetric padding ps(h: 20, v: 10)
po({l, t, r, b}) Individual padding po(l: 10, t: 20)

Figma-Based Helpers

Function Description Example
fw(value) Figma-scaled width fw(375) → 375px scaled
fh(value) Figma-scaled height fh(40) → 40px scaled
fws(value) Figma width spacing fws(100) → SizedBox(width: 100px scaled)
fhs(value) Figma height spacing fhs(40) → SizedBox(height: 40px scaled)
sp([step]) Standard spacing sp(2) → 16px scaled

Shared Helpers

Function Description Example
ts(value) Scale text size ts(16) → scaled 16px
r(value) Scale radius r(12) → scaled 12px
isMobile Check if mobile if (isMobile) ...
isTablet Check if tablet if (isTablet) ...
isDesktop Check if desktop if (isDesktop) ...
adaptiveColumns() Responsive grid adaptiveColumns(mobile: 2)

Extensions #

Percentage-Based Extensions

50.w        // 50% of screen width
30.h        // 30% of screen height
5.ws        // SizedBox(width: 5%)
2.hs        // SizedBox(height: 2%)

Figma-Based Extensions

375.fw      // 375px scaled from Figma width
40.fh       // 40px scaled from Figma height
100.fws     // SizedBox(width: 100px scaled)
40.fhs      // SizedBox(height: 40px scaled)

Shared Extensions

18.ts       // Text size scaled
12.r        // Radius scaled (always Figma-based)

Core Methods #

Method Description Example
Vize.init(context) Initialize Vize Vize.init(context)
VizeLayout Reactive builder VizeLayout(builder:...)
Vize.getInfo() Get constraints Vize.getInfo(context,..)

Vize.I Methods #

Access these via Vize.I:

Method Description
Vize.I.wp(percent) Width percentage
Vize.I.hp(percent) Height percentage
Vize.I.sw(value) Scale width from Figma
Vize.I.sh(value) Scale height from Figma
Vize.I.ts(size) Scale text size
Vize.I.r(value) Scale radius
Vize.I.pa(value) Padding all sides
Vize.I.ps({h, v}) Symmetric padding
Vize.I.po({l, t, r, b}) Individual padding
Vize.I.isMobile Check if mobile
Vize.I.isTablet Check if tablet
Vize.I.isDesktop Check if desktop
Vize.I.device Get device type

Device Flags #

Flag Description
isMobile True if mobile device
isTablet True if tablet device
isDesktop True if desktop device

Widgets #

Widget Description
VizeBuilder Build different layouts per device
VizeLayout LayoutBuilder with VizeInfo

Best Practices #

  1. Initialize Once

    Vize.init(context); // In MaterialApp builder
    
  2. Choose the Right Approach

    • Use percentage-based (w, h, hs, ws) for responsive layouts
    • Use Figma-based (fw, fh, fhs, fws) for pixel-perfect designs
  3. Mix Approaches Wisely

    // Good: Responsive container with fixed elements
    Container(
      width: w(90),      // Responsive width
      height: 200.fh,    // Fixed height from Figma
      child: ...
    )
    
  4. Test on Multiple Devices

    • Small phones, tablets, and desktops
    • Different orientations

Migration from 1.0.x #

No migration needed! Version 1.0.2 is fully backward compatible:

  • All existing percentage-based code continues to work
  • New Figma-based functions are additive only
  • No breaking changes to existing APIs
// Your existing code still works:
50.w    // Still 50% of screen width
5.hs    // Still 5% height spacing

// New features are available:
375.fw  // New: 375px scaled from Figma
40.fhs  // New: 40px height spacing from Figma

Complete Example #

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      builder: (context, child) {
        Vize.init(
          context,
          figmaWidth: 390,
          figmaHeight: 844,
        );
        return child!;
      },
      home: const HomePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        padding: 20.pa,  // padding
        child: Column(
          children: [
            // Figma-based header
            Container(
              width: 375.fw,      // 375px from Figma
              height: 40.fh,      // 40px from Figma
              decoration: BoxDecoration(
                color: Colors.blueAccent,
                borderRadius: BorderRadius.circular(12.r),
              ),
              child: Center(
                child: Text(
                  'Header',
                  style: TextStyle(fontSize: 22.ts),
                ),
              ),
            ),

            40.fhs,  // Fixed spacing from Figma

            // Responsive grid
            GridView.builder(
              shrinkWrap: true,
              physics: const NeverScrollableScrollPhysics(),
              itemCount: 4,
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: adaptiveColumns(
                  mobile: 1,
                  tablet: 2,
                  desktop: 4,
                ),
                mainAxisSpacing: sp(2),
                crossAxisSpacing: sp(2),
              ),
              itemBuilder: (context, i) => Container(
                color: Colors.grey[200],
                alignment: Alignment.center,
                child: Text('Item $i'),
              ),
            ),

            2.hs,  // Responsive spacing at bottom
          ],
        ),
      ),
    );
  }
}

Contributing #

Contributions are very welcome! We'd love to see new features, bug fixes, documentation improvements, or anything that makes Vize better.

Local Development & Verification #

To ensure consistency, we've included a "pre-flight" script. Before pushing your changes or opening a PR, please run the checks to verify formatting, analysis, and tests:

On Windows (PowerShell):

./check.ps1

On Linux/macOS:

chmod +x check.sh # Only needed the first time
./check.sh

How to Contribute #

  1. Fork the repository
  2. Create a feature branch
    git checkout -b new-feature
    
  3. Commit your changes
    git commit -am 'Add new feature'
    
  4. Push to the branch
    git push origin new-feature
    
  5. Open a Pull Request on GitHub

Please make sure your code follows the existing style, includes tests where appropriate, and updates documentation if needed.

Thank you for helping improve Vize!

License #

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

Support #

If you find Vize helpful, please give it a ⭐ on GitHub!

Contact #


Made with ❤️ for the Flutter community

2
likes
160
points
330
downloads

Publisher

unverified uploader

Weekly Downloads

Vize is a modern, developer-friendly Flutter package for effortless responsive UIs that match your Figma designs perfectly.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on vize