adaptive_svg 0.2.0 copy "adaptive_svg: ^0.2.0" to clipboard
adaptive_svg: ^0.2.0 copied to clipboard

Platform-adaptive SVG rendering. DOM <svg> on web, flutter_svg on native.

example/lib/main.dart

import 'package:adaptive_svg/adaptive_svg.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

import 'svg_samples.dart';

void main() {
  runApp(const App());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'AdaptiveSvg vs flutter_svg',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
        useMaterial3: true,
      ),
      home: const ComparisonPage(),
    );
  }
}

class ComparisonPage extends StatefulWidget {
  const ComparisonPage({super.key});

  @override
  State<ComparisonPage> createState() => _ComparisonPageState();
}

class _ComparisonPageState extends State<ComparisonPage> {
  String? _selectedCategory;

  List<String> get _categories =>
      svgSamples.map((s) => s.category).toSet().toList();

  List<SvgSample> get _filteredSamples => _selectedCategory == null
      ? svgSamples
      : svgSamples.where((s) => s.category == _selectedCategory).toList();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('AdaptiveSvg vs flutter_svg'),
        bottom: PreferredSize(
          preferredSize: const Size.fromHeight(48),
          child: SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
            child: Row(
              children: [
                _FilterChip(
                  label: 'All',
                  selected: _selectedCategory == null,
                  onSelected: () =>
                      setState(() => _selectedCategory = null),
                ),
                for (final cat in _categories)
                  Padding(
                    padding: const EdgeInsets.only(left: 8),
                    child: _FilterChip(
                      label: cat,
                      selected: _selectedCategory == cat,
                      onSelected: () =>
                          setState(() => _selectedCategory = cat),
                    ),
                  ),
              ],
            ),
          ),
        ),
      ),
      body: ListView.separated(
        padding: const EdgeInsets.all(16),
        itemCount: _filteredSamples.length,
        separatorBuilder: (_, _) => const SizedBox(height: 24),
        itemBuilder: (context, index) {
          final sample = _filteredSamples[index];
          return _ComparisonCard(sample: sample);
        },
      ),
    );
  }
}

class _FilterChip extends StatelessWidget {
  final String label;
  final bool selected;
  final VoidCallback onSelected;

  const _FilterChip({
    required this.label,
    required this.selected,
    required this.onSelected,
  });

  @override
  Widget build(BuildContext context) {
    return FilterChip(
      label: Text(label),
      selected: selected,
      onSelected: (_) => onSelected(),
    );
  }
}

class _ComparisonCard extends StatelessWidget {
  final SvgSample sample;

  const _ComparisonCard({required this.sample});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Card(
      clipBehavior: Clip.antiAlias,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Header
          Container(
            width: double.infinity,
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
            color: sample.flutterSvgSupported
                ? theme.colorScheme.primaryContainer
                : theme.colorScheme.errorContainer,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Row(
                  children: [
                    Expanded(
                      child: Text(
                        sample.label,
                        style: theme.textTheme.titleMedium?.copyWith(
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                    Container(
                      padding: const EdgeInsets.symmetric(
                          horizontal: 8, vertical: 2),
                      decoration: BoxDecoration(
                        color: theme.colorScheme.surface,
                        borderRadius: BorderRadius.circular(12),
                      ),
                      child: Text(
                        sample.category,
                        style: theme.textTheme.labelSmall,
                      ),
                    ),
                  ],
                ),
                if (sample.notes != null) ...[
                  const SizedBox(height: 4),
                  Text(
                    sample.notes!,
                    style: theme.textTheme.bodySmall?.copyWith(
                      color: sample.flutterSvgSupported
                          ? theme.colorScheme.onPrimaryContainer
                          : theme.colorScheme.onErrorContainer,
                      fontStyle: FontStyle.italic,
                    ),
                  ),
                ],
              ],
            ),
          ),
          // Side-by-side renders
          IntrinsicHeight(
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                // AdaptiveSvg (DOM on web)
                Expanded(
                  child: _RenderPane(
                    title: 'AdaptiveSvg (DOM)',
                    child: AdaptiveSvg(sample.svg),
                  ),
                ),
                const VerticalDivider(width: 1),
                // flutter_svg
                Expanded(
                  child: _RenderPane(
                    title: 'flutter_svg',
                    child: SvgPicture.string(sample.svg),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class _RenderPane extends StatelessWidget {
  final String title;
  final Widget child;

  const _RenderPane({required this.title, required this.child});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.only(top: 8),
          child: Text(
            title,
            style: theme.textTheme.labelMedium?.copyWith(
              fontWeight: FontWeight.w600,
            ),
          ),
        ),
        const Divider(height: 8),
        Container(
          height: 200,
          padding: const EdgeInsets.all(12),
          alignment: Alignment.center,
          child: child,
        ),
      ],
    );
  }
}
1
likes
0
points
1.62k
downloads

Publisher

verified publisherrjmath.com

Weekly Downloads

Platform-adaptive SVG rendering. DOM <svg> on web, flutter_svg on native.

Repository (GitHub)
View/report issues

Topics

#svg #web #platform #rendering

License

unknown (license)

Dependencies

flutter, flutter_svg, web

More

Packages that depend on adaptive_svg