primer_flutter 1.0.0 copy "primer_flutter: ^1.0.0" to clipboard
primer_flutter: ^1.0.0 copied to clipboard

Flutter themes consistent with GitHub's Primer style guidelines

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_syntax_view/flutter_syntax_view.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:primer_flutter/primer_flutter.dart' hide Border;

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Primer Demo',
      builder: (context, child) => PrimerApp(
        parentBrightness: Theme.of(context).brightness,
        child: child!,
      ),
      theme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      themeMode: ThemeMode.dark,
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final primerTheme = PrimerTheme.of(context);
    return Scaffold(
      backgroundColor: primerTheme.canvas.dflt,
      body: CustomScrollView(
        slivers: [
          SliverToBoxAdapter(
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Text(
                'Typography',
                style: primerTheme.typography.h1,
              ),
            ),
          ),
          SliverPadding(
            padding: const EdgeInsets.all(8.0),
            sliver: SliverList(
              delegate: SliverChildListDelegate(
                [
                  Text('Heading styles', style: primerTheme.typography.h2),
                  Divider(color: primerTheme.neutral.emphasis),
                  RichText(
                    text: TextSpan(
                      style: TextStyle(
                        color: primerTheme.foreground.dflt,
                      ),
                      children: [
                        const TextSpan(text: 'Use '),
                        WidgetSpan(
                          child: DecoratedBox(
                            decoration: BoxDecoration(
                              color: primerTheme.neutral.muted,
                              borderRadius: BorderRadius.circular(6),
                            ),
                            child: Padding(
                              padding:
                                  const EdgeInsets.symmetric(horizontal: 6.0),
                              child: Text(
                                'PrimerTypography.h1',
                                style: GoogleFonts.jetBrainsMono(),
                              ),
                            ),
                          ),
                        ),
                        const TextSpan(text: ' - '),
                        WidgetSpan(
                          child: DecoratedBox(
                            decoration: BoxDecoration(
                              color: primerTheme.neutral.muted,
                              borderRadius: BorderRadius.circular(6),
                            ),
                            child: Padding(
                              padding:
                                  const EdgeInsets.symmetric(horizontal: 6.0),
                              child: Text(
                                'PrimerTypography.h6',
                                style: GoogleFonts.jetBrainsMono(),
                              ),
                            ),
                          ),
                        ),
                        const TextSpan(
                          text:
                              ' to change the font size and weight to match Primer\'s styles.',
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(height: 8),
                  DecoratedBox(
                    decoration: BoxDecoration(
                      border: Border.all(
                        color: primerTheme.neutral.muted,
                        width: 1,
                      ),
                      borderRadius: BorderRadius.circular(6),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Text('Heading 1', style: primerTheme.typography.h1),
                          const SizedBox(height: 8),
                          Text('Heading 2', style: primerTheme.typography.h2),
                          const SizedBox(height: 8),
                          Text('Heading 3', style: primerTheme.typography.h3),
                          const SizedBox(height: 8),
                          Text('Heading 4', style: primerTheme.typography.h4),
                          const SizedBox(height: 8),
                          Text('Heading 5', style: primerTheme.typography.h5),
                          const SizedBox(height: 8),
                          Text('Heading 6', style: primerTheme.typography.h6),
                        ],
                      ),
                    ),
                  ),
                  const SizedBox(height: 24),
                  Text(
                    'Typographic styles',
                    style: primerTheme.typography.h2,
                  ),
                  Divider(color: primerTheme.neutral.emphasis),
                  RichText(
                    text: TextSpan(
                      style: TextStyle(
                        color: primerTheme.foreground.dflt,
                      ),
                      children: [
                        const TextSpan(
                            text:
                                'Change the font weight, styles, and alignment with these '),
                        WidgetSpan(
                          child: DecoratedBox(
                            decoration: BoxDecoration(
                              color: primerTheme.neutral.muted,
                              borderRadius: BorderRadius.circular(6),
                            ),
                            child: Padding(
                              padding:
                                  const EdgeInsets.symmetric(horizontal: 6.0),
                              child: Text(
                                'TextStyle',
                                style: GoogleFonts.jetBrainsMono(),
                              ),
                            ),
                          ),
                        ),
                        const TextSpan(text: 's.'),
                      ],
                    ),
                  ),
                  const SizedBox(height: 8),
                  DecoratedBox(
                    decoration: BoxDecoration(
                      border: Border.all(
                        color: primerTheme.neutral.muted,
                        width: 1,
                      ),
                      borderRadius: BorderRadius.circular(6),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Text('Normal', style: primerTheme.typography.normal),
                          const SizedBox(height: 8),
                          Text('Italic', style: primerTheme.typography.italic),
                          const SizedBox(height: 8),
                          Text('Bold', style: primerTheme.typography.bold),
                          const SizedBox(height: 8),
                          Text('Semi-bold',
                              style: primerTheme.typography.semiBold),
                          const SizedBox(height: 8),
                          Text('Light', style: primerTheme.typography.light),
                          const SizedBox(height: 8),
                          Text(
                            'Underline',
                            style: primerTheme.typography.underline,
                          ),
                          const SizedBox(height: 8),
                          Text('Small', style: primerTheme.typography.small),
                          const SizedBox(height: 8),
                          Text(
                            'Small bold',
                            style: primerTheme.typography.smallBold,
                          ),
                          const SizedBox(height: 8),
                          Text('Monospace', style: primerTheme.typography.mono),
                          const SizedBox(height: 8),
                          Text('Lead', style: primerTheme.typography.lead),
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
          SliverToBoxAdapter(
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Text(
                'Colors',
                style: primerTheme.typography.h1,
              ),
            ),
          ),
          SliverPadding(
            padding: const EdgeInsets.all(8.0),
            sliver: SliverList(
              delegate: SliverChildListDelegate(
                [
                  const Text(
                      'You can use the colors below in the following ways:'),
                  const SizedBox(height: 8),
                  Row(
                    children: [
                      SyntaxView(
                        code:
                            '''/// 1: Via the current `PrimerThemeData` (recommended)
PrimerTheme.of(context).foreground.dflt;
PrimerTheme.of(context).accent.foreground;
                        
/// 2: Via the color classes themselves (not recommended)
Accent().foreground;
Attention.dark().foreground;''',
                        syntax: Syntax.DART,
                        syntaxTheme: SyntaxTheme.vscodeDark(),
                        withZoom: false,
                        fontSize: 14.0,
                      ),
                    ],
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'Foreground',
                    style: primerTheme.typography.h3,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'The primary color for text and icons in any given interface.',
                    style: primerTheme.typography.h6,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: [
                      ColorCell(
                        color: primerTheme.foreground.dflt,
                        label: 'default',
                      ),
                      ColorCell(
                        color: primerTheme.foreground.muted,
                        label: 'muted',
                      ),
                      ColorCell(
                        color: primerTheme.foreground.subtle,
                        label: 'subtle',
                      ),
                      ColorCell(
                        color: primerTheme.foreground.onEmphasis,
                        label: 'onEmphasis',
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                  Text(
                    'Canvas',
                    style: primerTheme.typography.h3,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'Colors used for the backgrounds of user interfaces.',
                    style: primerTheme.typography.h6,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: [
                      ColorCell(
                        color: primerTheme.canvas.dflt,
                        label: 'default',
                      ),
                      ColorCell(
                        color: primerTheme.canvas.overlay,
                        label: 'overlay',
                      ),
                      ColorCell(
                        color: primerTheme.canvas.inset,
                        label: 'inset',
                      ),
                      ColorCell(
                        color: primerTheme.canvas.subtle,
                        label: 'subtle',
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                  Text(
                    'Border',
                    style: primerTheme.typography.h3,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'Colors used for drawing borders.',
                    style: primerTheme.typography.h6,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: [
                      ColorCell(
                        color: primerTheme.border.dflt,
                        label: 'default',
                      ),
                      ColorCell(
                        color: primerTheme.border.muted,
                        label: 'muted',
                      ),
                      ColorCell(
                        color: primerTheme.border.subtle,
                        label: 'subtle',
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                  Text(
                    'Neutral',
                    style: primerTheme.typography.h3,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'Colors used to highlight content without any added meaning.',
                    style: primerTheme.typography.h6,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: [
                      ColorCell(
                        color: primerTheme.neutral.emphasisPlus,
                        label: 'emphasisPlus',
                      ),
                      ColorCell(
                        color: primerTheme.neutral.emphasis,
                        label: 'emphasis',
                      ),
                      ColorCell(
                        color: primerTheme.neutral.muted,
                        label: 'muted',
                      ),
                      ColorCell(
                        color: primerTheme.neutral.subtle,
                        label: 'subtle',
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                  Text(
                    'Accent',
                    style: primerTheme.typography.h3,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'Colors for drawing attention to interactive elements, like links or buttons.',
                    style: primerTheme.typography.h6,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: [
                      ColorCell(
                        color: primerTheme.accent.foreground,
                        label: 'foreground',
                      ),
                      ColorCell(
                        color: primerTheme.accent.emphasis,
                        label: 'emphasis',
                      ),
                      ColorCell(
                        color: primerTheme.accent.muted,
                        label: 'muted',
                      ),
                      ColorCell(
                        color: primerTheme.accent.subtle,
                        label: 'subtle',
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                  Text(
                    'Success',
                    style: primerTheme.typography.h3,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'Colors for emphasizing a positive message. Commonly used to expresses the completion or positive outcome of a task.',
                    style: primerTheme.typography.h6,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: [
                      ColorCell(
                        color: primerTheme.success.foreground,
                        label: 'foreground',
                      ),
                      ColorCell(
                        color: primerTheme.success.emphasis,
                        label: 'emphasis',
                      ),
                      ColorCell(
                        color: primerTheme.success.muted,
                        label: 'muted',
                      ),
                      ColorCell(
                        color: primerTheme.success.subtle,
                        label: 'subtle',
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                  Text(
                    'Attention',
                    style: primerTheme.typography.h3,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'Colors for highlighting text or icons that require the user\'s attention. Commonly used to warn of pending tasks or to highlight active content.',
                    style: primerTheme.typography.h6,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: [
                      ColorCell(
                        color: primerTheme.attention.foreground,
                        label: 'foreground',
                      ),
                      ColorCell(
                        color: primerTheme.attention.emphasis,
                        label: 'emphasis',
                      ),
                      ColorCell(
                        color: primerTheme.attention.muted,
                        label: 'muted',
                      ),
                      ColorCell(
                        color: primerTheme.attention.subtle,
                        label: 'subtle',
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                  Text(
                    'Severe',
                    style: primerTheme.typography.h3,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'Colors for emphasizing a level of severity between Attention and Danger. Commonly used when there are more than 3 levels of states, for example in heatmaps.',
                    style: primerTheme.typography.h6,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: [
                      ColorCell(
                        color: primerTheme.severe.foreground,
                        label: 'foreground',
                      ),
                      ColorCell(
                        color: primerTheme.severe.emphasis,
                        label: 'emphasis',
                      ),
                      ColorCell(
                        color: primerTheme.severe.muted,
                        label: 'muted',
                      ),
                      ColorCell(
                        color: primerTheme.severe.subtle,
                        label: 'subtle',
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                  Text(
                    'Danger',
                    style: primerTheme.typography.h3,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'Colors for emphasizing an error or a blocking status. Action is required. Commonly used to inform of errors or other negative messages.',
                    style: primerTheme.typography.h6,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: [
                      ColorCell(
                        color: primerTheme.danger.foreground,
                        label: 'foreground',
                      ),
                      ColorCell(
                        color: primerTheme.danger.emphasis,
                        label: 'emphasis',
                      ),
                      ColorCell(
                        color: primerTheme.danger.muted,
                        label: 'muted',
                      ),
                      ColorCell(
                        color: primerTheme.danger.subtle,
                        label: 'subtle',
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                  Text(
                    'Open',
                    style: primerTheme.typography.h3,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'Colors for styling UI elements that refer to open tasks or workflows.',
                    style: primerTheme.typography.h6,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: [
                      ColorCell(
                        color: primerTheme.open.foreground,
                        label: 'foreground',
                      ),
                      ColorCell(
                        color: primerTheme.open.emphasis,
                        label: 'emphasis',
                      ),
                      ColorCell(
                        color: primerTheme.open.muted,
                        label: 'muted',
                      ),
                      ColorCell(
                        color: primerTheme.open.subtle,
                        label: 'subtle',
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                  Text(
                    'Closed',
                    style: primerTheme.typography.h3,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'Colors for styling UI elements that refer to closed tasks or workflows.',
                    style: primerTheme.typography.h6,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: [
                      ColorCell(
                        color: primerTheme.closed.foreground,
                        label: 'foreground',
                      ),
                      ColorCell(
                        color: primerTheme.closed.emphasis,
                        label: 'emphasis',
                      ),
                      ColorCell(
                        color: primerTheme.closed.muted,
                        label: 'muted',
                      ),
                      ColorCell(
                        color: primerTheme.closed.subtle,
                        label: 'subtle',
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                  Text(
                    'Done',
                    style: primerTheme.typography.h3,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'Completion colors for productivity and code review workflows.',
                    style: primerTheme.typography.h6,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: [
                      ColorCell(
                        color: primerTheme.done.foreground,
                        label: 'foreground',
                      ),
                      ColorCell(
                        color: primerTheme.done.emphasis,
                        label: 'emphasis',
                      ),
                      ColorCell(
                        color: primerTheme.done.muted,
                        label: 'muted',
                      ),
                      ColorCell(
                        color: primerTheme.done.subtle,
                        label: 'subtle',
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                  Text(
                    'Sponsors',
                    style: primerTheme.typography.h3,
                  ),
                  const SizedBox(height: 8),
                  Text(
                    'Colors for styling Sponsors-related UI.',
                    style: primerTheme.typography.h6,
                  ),
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: [
                      ColorCell(
                        color: primerTheme.sponsors.foreground,
                        label: 'foreground',
                      ),
                      ColorCell(
                        color: primerTheme.sponsors.emphasis,
                        label: 'emphasis',
                      ),
                      ColorCell(
                        color: primerTheme.sponsors.muted,
                        label: 'muted',
                      ),
                      ColorCell(
                        color: primerTheme.sponsors.subtle,
                        label: 'subtle',
                      ),
                    ],
                  ),
                  const SizedBox(height: 16),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class ColorCell extends StatelessWidget {
  const ColorCell({
    Key? key,
    required this.color,
    required this.label,
  }) : super(key: key);

  final Color color;
  final String label;

  @override
  Widget build(BuildContext context) {
    final primerTheme = PrimerTheme.of(context);
    Color labelColor =
        color.computeLuminance() > 0.5 ? Colors.black : Colors.white;
    return SizedBox(
      height: 70,
      width: 150,
      child: DecoratedBox(
        decoration: BoxDecoration(
          color: color,
          borderRadius: BorderRadius.circular(6),
        ),
        child: Center(
          child: Text(
            label,
            style: primerTheme.typography.h4.copyWith(
              color: labelColor,
            ),
          ),
        ),
      ),
    );
  }
}
1
likes
150
points
18
downloads

Publisher

verified publishergroovinchip.dev

Weekly Downloads

Flutter themes consistent with GitHub's Primer style guidelines

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on primer_flutter