diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..019b957 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,23 @@ +name: Dart CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-java@v1 + with: + java-version: '12.x' + - uses: subosito/flutter-action@v1 + with: + flutter-version: '3.0.0' + - run: flutter pub get + - run: flutter analyze + - run: flutter test diff --git a/PLAN_DE_MANTENIMIENTO.md b/PLAN_DE_MANTENIMIENTO.md new file mode 100644 index 0000000..75f1f51 --- /dev/null +++ b/PLAN_DE_MANTENIMIENTO.md @@ -0,0 +1,9 @@ +# Maintenance plan for pigment + +* **Update for latest Flutter/Dart versions:** Review the package's compatibility with current Flutter and Dart releases. Upgrade the SDK constraints and dependencies to support the latest stable versions and null safety. +* **Modernize codebase:** Refactor the code to use modern Dart and Flutter best practices, removing deprecated APIs and improving type safety and API design. +* **Automate CI/CD:** Set up GitHub Actions workflows to run unit tests, static analysis (`dart analyze`), and formatting checks on every pull request. Automate package publishing when releasing new versions. +* **Increase test coverage:** Add comprehensive unit tests for color parsing, color manipulation methods and edge cases. Ensure the library handles various color formats (hex, RGB, HSL, named colors) correctly. +* **Documentation and examples:** Update the README with clear usage instructions, examples for different color formats, and guidelines on extending the library. Provide a sample Flutter app demonstrating how to use the package. +* **Respond to issues and contributions:** Review open issues and pull requests, addressing bugs and feature requests. Close outdated issues and maintain communication with users. +* **Versioning and releases:** Adopt semantic versioning, create release tags and maintain a changelog summarizing changes for each release. diff --git a/README.md b/README.md index b1a2520..119f3d7 100644 --- a/README.md +++ b/README.md @@ -1,86 +1,34 @@ -

- -

- # Pigment -[![pub package](https://img.shields.io/pub/v/pigment.svg)](https://pub.dartlang.org/packages/pigment) - -A simple but useful plugin for use colors with Flutter - -## Features +[![Build Status](https://travis-ci.org/bregydoc/pigment.svg?branch=master)](https://travis-ci.org/bregydoc/pigment) -- You can use string colors (like #01E19F) direct in flutter -- Pigment extends to Color dar:ui class, then you can use all methods of Color class -- Pigment 1.0.1 can parse 'rgb()' (e.g. 'rgb(29, 123, 10)'). -- Added CSS colors with default name, you can access from this with CSSColor.\* (e.g. `Pigment.fromCSSColor(CSSColor.lightsalmon)`) or directly with `Pigment.fromString('lightsalmon')`. +Useful and simple flutter color handler. -## Installation +## Usage -First, add `pigment` as a [dependency in your pubspec.yaml file](https://flutter.io/using-packages/). +To use this plugin, add `pigment` as a [dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/). -## Use +### Examples -It's very simple, pigment add a new useful method to Color class, this method is `Pigment.fromString()`. -Also like Color, you can use `new Pigment()`. - - +Here are some examples of how to use this library. ```dart -Pigment.fromString() -new Pigment() +// from a CSS color name +Pigment.fromString("red") +// from a hex color +Pigment.fromString("#ff0000") +// from a short hex color +Pigment.fromString("#f00") +// from a hex color with alpha +Pigment.fromString("#80ff0000") +// from an RGB color +Pigment.fromString("rgb(255,0,0)") +// from the CSSColor enum +Pigment.fromCSSColor(CSSColor.red) ``` -## Example - -Here is a small example of the classic and simple pigment use. +## Demo -```dart -import 'package:flutter/material.dart'; -import 'package:pigment/pigment.dart'; - -void main() => runApp(new MyApp()); - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return new MaterialApp( - title: 'Pigment Demo', - theme: new ThemeData( - primarySwatch: Colors.red, - ), - home: new MyHomePage(), - ); - } -} - -class MyHomePage extends StatefulWidget { - @override - _MyHomePageState createState() => new _MyHomePageState(); -} - -class _MyHomePageState extends State { - @override - Widget build(BuildContext context) { - return new Scaffold( - appBar: new AppBar( - title: new Text('Pigment App'), - ), - body: new Center( - child: new Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - new Text('Pigment is cool', - style: new TextStyle(color: Pigment.fromString("#FE5567"))), - new Text('Pigment is cool', - style: new TextStyle(color: Pigment.fromString("#01E19F"))), - new Text('Pigment is cool', - style: new TextStyle(color: Pigment.fromString("#4A48D2"))), - new Text('Pigment is cool', - style: new TextStyle(color: Pigment.fromString("rgb(253, 196, 86)"))), - ], - ), - )); - } -} -``` +| Before | After | +|---|---| +| | | diff --git a/example/usage_example.dart b/example/usage_example.dart index fc69562..9dffd1e 100644 --- a/example/usage_example.dart +++ b/example/usage_example.dart @@ -1,25 +1,41 @@ -import 'package:pigment/pigment.dart'; import 'package:flutter/material.dart'; +import 'package:pigment/pigment.dart'; void main() { - LinearGradient g = new LinearGradient( - colors: [ - Pigment.fromString("rgb(0, 225, 170)"), - Pigment.fromString("rgb(27, 26, 64)"), - Pigment.fromString("rgb(221, 64, 86)"), - Pigment.fromString("#5442FE"), - Pigment.fromString("#50E8D7"), - Pigment.fromString("#FF3472"), - Pigment.fromString("#a0227baa"), - Pigment.fromString("#EFEFEF"), - Pigment.fromString("#AEF"), - Pigment.fromString("#01B9"), + runApp(new MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return new MaterialApp( + title: 'Pigment Example', + home: new MyHomePage(), + ); + } +} + +class MyHomePage extends StatefulWidget { + @override + _MyHomePageState createState() => new _MyHomePageState(); +} - Pigment.fromCSSColor(CSSColor.rosybrown), // #BC8F8F - Pigment.fromCSSColor(CSSColor.palegoldenrod), // #EEE8AA - Pigment.fromString('lightsalmon'), // #FFA07A - Pigment.fromString('deeppink'), // #FF1493 - new Pigment(0xFFAA23F2) // #AA23F2 - ], - ); +class _MyHomePageState extends State { + @override + Widget build(BuildContext context) { + return new Scaffold( + backgroundColor: Pigment.fromString("blue"), + appBar: new AppBar( + title: new Text("Pigment Example"), + ), + body: new Center( + child: new Text( + 'Hello, World!', + style: new TextStyle( + color: Pigment.fromCSSColor(CSSColor.lightgoldenrodyellow), + ), + ), + ), + ); + } } diff --git a/lib/pigment.dart b/lib/pigment.dart index 155df12..fecd900 100644 --- a/lib/pigment.dart +++ b/lib/pigment.dart @@ -4,34 +4,26 @@ import 'dart:ui'; part 'named_colors.dart'; class Pigment extends Color { - @override Pigment(int value) : super(value); static bool _hasCorrectHexPattern(String string) { - string = string.replaceAll("#", ""); - String validChars = "0123456789AaBbCcDdEeFf"; - for (int i = 0; i < string.length; i++) { - if (!validChars.contains(string[i])) { - return false; - } - } - return true; + return RegExp(r'^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$') + .hasMatch(string); } static Color? _getRGBColorFromString(String string) { string = string.replaceAll(" ", ""); // pseudo-trimming if (string.startsWith("rgb(") && string.endsWith(")")) { - // Correct - string = string.replaceAll("rgb(", ""); - string = string.replaceAll(")", ""); - List rgb = string.split(","); + string = string.substring(4, string.length - 1); + final rgb = string.split(","); if (rgb.length == 3) { - int r = int.parse(rgb[0]); - int g = int.parse(rgb[1]); - int b = int.parse(rgb[2]); - return new Color.fromARGB(255, r, g, b); + final r = int.tryParse(rgb[0]); + final g = int.tryParse(rgb[1]); + final b = int.tryParse(rgb[2]); + if (r != null && g != null && b != null) { + return Color.fromARGB(255, r, g, b); + } } - return null; } return null; } @@ -39,45 +31,28 @@ class Pigment extends Color { static Color _getColor(String color) { color = color.trim(); - Color? rgbColor = _getRGBColorFromString(color); + final rgbColor = _getRGBColorFromString(color); if (rgbColor != null) { return rgbColor; } - Color? finalColor; if (_hasCorrectHexPattern(color)) { - color = color.replaceAll("#", ""); - int size = color.length; - if (size == 6 || size == 3) { - if (size == 3) { - color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2]; - } - - int value = int.parse(color, radix: 16); - value = value + 0xFF000000; - finalColor = new Color(value); - } else if (size == 8 || size == 4) { - if (size == 4) { - color = - color[0] + color[0] + color[1] + color[1] + color[2] + color[2] + color[3] + color[3]; - } - String alpha = color.substring(6); - color = alpha + color.substring(0, 6); - int value = int.parse(color, radix: 16); - finalColor = new Color(value); + var hex = color.replaceAll("#", ""); + if (hex.length == 3) { + hex = hex.split('').map((c) => c + c).join(''); } + if (hex.length == 6) { + hex = "FF$hex"; + } + if (hex.length == 8) { + hex = hex.substring(6, 8) + hex.substring(0, 6); + } + return Color(int.parse("0x$hex")); } - if (finalColor != null) { - return finalColor; - } - - String? namedColor = cssColors[color]; - if (namedColor != null && namedColor != "") { - namedColor = namedColor.replaceAll("#", ""); - int value = int.parse(namedColor, radix: 16); - value = value + 0xFF000000; - return new Color(value); + final namedColor = cssColors[color.toLowerCase()]; + if (namedColor != null) { + return _getColor(namedColor); } throw 'color pattern [$color] not found! D:'; @@ -88,7 +63,8 @@ class Pigment extends Color { } static Color fromCSSColor(CSSColor color) { - String colorName = color.toString().substring(color.toString().indexOf('.') + 1); + final colorName = + color.toString().substring(color.toString().indexOf('.') + 1); return _getColor(colorName); } } diff --git a/pubspec.yaml b/pubspec.yaml index 135d963..9eb34ba 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,12 +1,15 @@ name: pigment description: Useful and simple flutter color handler. -version: 1.0.4 +version: 2.0.0 homepage: https://github.com/bregydoc/pigment + environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.17.0 <4.0.0" + dependencies: - flutter: - sdk: flutter + flutter: + sdk: flutter + dev_dependencies: - flutter_test: - sdk: flutter + flutter_test: + sdk: flutter diff --git a/test/pigment_test.dart b/test/pigment_test.dart new file mode 100644 index 0000000..ca1d113 --- /dev/null +++ b/test/pigment_test.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pigment/pigment.dart'; + +void main() { + test('Color parsing', () { + expect(Pigment.fromString('#ff0000'), equals(Colors.red)); + expect(Pigment.fromString('#f00'), equals(Colors.red)); + expect(Pigment.fromString('rgb(255,0,0)'), equals(Colors.red)); + expect(Pigment.fromString('red'), equals(Colors.red)); + }); + + test('Color parsing with alpha', () { + expect(Pigment.fromString('#80ff0000'), equals(Colors.red.withAlpha(128))); + }); + + test('CSS colors', () { + expect(Pigment.fromCSSColor(CSSColor.red), equals(Colors.red)); + }); +}