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
pub points
0%
popularity

Publisher

verified publishergroovinchip.dev

Flutter themes consistent with GitHub's Primer style guidelines

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on primer_flutter