diff --git a/packages/mirai/lib/src/utils/color_type.dart b/packages/mirai/lib/src/utils/color_type.dart index dda03f5a..2d33847f 100644 --- a/packages/mirai/lib/src/utils/color_type.dart +++ b/packages/mirai/lib/src/utils/color_type.dart @@ -1,4 +1,4 @@ -enum ColorType { +enum MiraiColorType { primary, onPrimary, primaryContainer, @@ -32,3 +32,44 @@ enum ColorType { scaffoldBackgroundColor, none, } + +enum MiraiColors { + amber, + amberAccent, + black, + blue, + blueAccent, + blueGrey, + brown, + cyan, + cyanAccent, + deepOrange, + deepOrangeAccent, + deepPurple, + deepPurpleAccent, + green, + greenAccent, + grey, + indigo, + indigoAccent, + lightBlue, + lightBlueAccent, + lightGreen, + lightGreenAccent, + lime, + limeAccent, + orange, + orangeAccent, + pink, + pinkAccent, + purple, + purpleAccent, + red, + redAccent, + teal, + tealAccent, + transparent, + white, + yellow, + yellowAccent, +} diff --git a/packages/mirai/lib/src/utils/color_utils.dart b/packages/mirai/lib/src/utils/color_utils.dart index 1079f795..aa7288e7 100644 --- a/packages/mirai/lib/src/utils/color_utils.dart +++ b/packages/mirai/lib/src/utils/color_utils.dart @@ -1,85 +1,244 @@ import 'package:flutter/material.dart'; import 'package:mirai/src/utils/color_type.dart'; +const String _hashtag = "#"; +const String _empty = ""; +const String _defaultOpacity = "ff"; + extension ColorExt on String? { Color? toColor(BuildContext context) { if (this?.isEmpty ?? true) return null; - switch (colorType) { - case ColorType.primary: - return Theme.of(context).colorScheme.primary; - case ColorType.onPrimary: - return Theme.of(context).colorScheme.onPrimary; - case ColorType.primaryContainer: - return Theme.of(context).colorScheme.primaryContainer; - case ColorType.onPrimaryContainer: - return Theme.of(context).colorScheme.onPrimaryContainer; - case ColorType.secondary: - return Theme.of(context).colorScheme.secondary; - case ColorType.onSecondary: - return Theme.of(context).colorScheme.onSecondary; - case ColorType.secondaryContainer: - return Theme.of(context).colorScheme.secondaryContainer; - case ColorType.onSecondaryContainer: - return Theme.of(context).colorScheme.onSecondaryContainer; - case ColorType.tertiary: - return Theme.of(context).colorScheme.tertiary; - case ColorType.onTertiary: - return Theme.of(context).colorScheme.onTertiary; - case ColorType.tertiaryContainer: - return Theme.of(context).colorScheme.tertiaryContainer; - case ColorType.onTertiaryContainer: - return Theme.of(context).colorScheme.onTertiaryContainer; - case ColorType.error: - return Theme.of(context).colorScheme.error; - case ColorType.onError: - return Theme.of(context).colorScheme.onError; - case ColorType.errorContainer: - return Theme.of(context).colorScheme.errorContainer; - case ColorType.onErrorContainer: - return Theme.of(context).colorScheme.onErrorContainer; - case ColorType.background: - return Theme.of(context).colorScheme.surface; - case ColorType.onBackground: - return Theme.of(context).colorScheme.onSurface; - case ColorType.surface: - return Theme.of(context).colorScheme.surface; - case ColorType.onSurface: - return Theme.of(context).colorScheme.onSurface; - case ColorType.surfaceVariant: - return Theme.of(context).colorScheme.surfaceContainerHighest; - case ColorType.onSurfaceVariant: - return Theme.of(context).colorScheme.onSurfaceVariant; - case ColorType.outline: - return Theme.of(context).colorScheme.outline; - case ColorType.outlineVariant: - return Theme.of(context).colorScheme.outlineVariant; - case ColorType.shadow: - return Theme.of(context).colorScheme.shadow; - case ColorType.scrim: - return Theme.of(context).colorScheme.scrim; - case ColorType.inverseSurface: - return Theme.of(context).colorScheme.inverseSurface; - case ColorType.onInverseSurface: - return Theme.of(context).colorScheme.onInverseSurface; - case ColorType.inversePrimary: - return Theme.of(context).colorScheme.inversePrimary; - case ColorType.surfaceTint: - return Theme.of(context).colorScheme.surfaceTint; - case ColorType.scaffoldBackgroundColor: - return Theme.of(context).scaffoldBackgroundColor; - case ColorType.none: - final buffer = StringBuffer(); - if (this!.length == 6 || this!.length == 7) buffer.write('ff'); - buffer.write(this!.replaceFirst('#', '')); - int? intColor = int.tryParse(buffer.toString(), radix: 16); - intColor = intColor ?? 0x00000000; - return Color(intColor); + final parsedColor = _parseThemeColor(this!, context); + if (parsedColor != null) { + return parsedColor; + } else if (this!.startsWith(_hashtag)) { + return _parseHexColor(this!); + } else { + return _parseNameColor(this!); } } +} - ColorType get colorType => ColorType.values.firstWhere( - (e) => e.name == this, - orElse: () => ColorType.none, - ); +Color? _parseThemeColor(String color, BuildContext context) { + // Ex: primary + MiraiColorType colorType = MiraiColorType.values.firstWhere( + (e) => e.name == color, + orElse: () => MiraiColorType.none, + ); + + switch (colorType) { + case MiraiColorType.primary: + return Theme.of(context).colorScheme.primary; + case MiraiColorType.onPrimary: + return Theme.of(context).colorScheme.onPrimary; + case MiraiColorType.primaryContainer: + return Theme.of(context).colorScheme.primaryContainer; + case MiraiColorType.onPrimaryContainer: + return Theme.of(context).colorScheme.onPrimaryContainer; + case MiraiColorType.secondary: + return Theme.of(context).colorScheme.secondary; + case MiraiColorType.onSecondary: + return Theme.of(context).colorScheme.onSecondary; + case MiraiColorType.secondaryContainer: + return Theme.of(context).colorScheme.secondaryContainer; + case MiraiColorType.onSecondaryContainer: + return Theme.of(context).colorScheme.onSecondaryContainer; + case MiraiColorType.tertiary: + return Theme.of(context).colorScheme.tertiary; + case MiraiColorType.onTertiary: + return Theme.of(context).colorScheme.onTertiary; + case MiraiColorType.tertiaryContainer: + return Theme.of(context).colorScheme.tertiaryContainer; + case MiraiColorType.onTertiaryContainer: + return Theme.of(context).colorScheme.onTertiaryContainer; + case MiraiColorType.error: + return Theme.of(context).colorScheme.error; + case MiraiColorType.onError: + return Theme.of(context).colorScheme.onError; + case MiraiColorType.errorContainer: + return Theme.of(context).colorScheme.errorContainer; + case MiraiColorType.onErrorContainer: + return Theme.of(context).colorScheme.onErrorContainer; + case MiraiColorType.background: + return Theme.of(context).colorScheme.surface; + case MiraiColorType.onBackground: + return Theme.of(context).colorScheme.onSurface; + case MiraiColorType.surface: + return Theme.of(context).colorScheme.surface; + case MiraiColorType.onSurface: + return Theme.of(context).colorScheme.onSurface; + case MiraiColorType.surfaceVariant: + return Theme.of(context).colorScheme.surfaceContainerHighest; + case MiraiColorType.onSurfaceVariant: + return Theme.of(context).colorScheme.onSurfaceVariant; + case MiraiColorType.outline: + return Theme.of(context).colorScheme.outline; + case MiraiColorType.outlineVariant: + return Theme.of(context).colorScheme.outlineVariant; + case MiraiColorType.shadow: + return Theme.of(context).colorScheme.shadow; + case MiraiColorType.scrim: + return Theme.of(context).colorScheme.scrim; + case MiraiColorType.inverseSurface: + return Theme.of(context).colorScheme.inverseSurface; + case MiraiColorType.onInverseSurface: + return Theme.of(context).colorScheme.onInverseSurface; + case MiraiColorType.inversePrimary: + return Theme.of(context).colorScheme.inversePrimary; + case MiraiColorType.surfaceTint: + return Theme.of(context).colorScheme.surfaceTint; + case MiraiColorType.scaffoldBackgroundColor: + return Theme.of(context).scaffoldBackgroundColor; + case MiraiColorType.none: + return null; + } +} + +Color _parseHexColor(String color) { + // Ex: #000000 + final buffer = StringBuffer(); + if (color.length == 6 || color.length == 7) buffer.write(_defaultOpacity); + buffer.write(color.replaceFirst(_hashtag, _empty)); + int? intColor = int.tryParse(buffer.toString(), radix: 16); + intColor = intColor ?? 0x00000000; + return Color(intColor); +} + +Color? _parseNameColor(String colorString) { + String color; + int? opacity; + if (colorString.startsWith(MiraiColors.white.name) || + colorString.startsWith(MiraiColors.black.name)) { + // Ex: black54 + color = colorString.substring(0, colorString.length - 2); + opacity = int.tryParse( + colorString.substring(colorString.length - 2, colorString.length), + ); + if (opacity == null) { + // Ex: black + color = colorString; + } + } else { + // Ex: red + color = colorString; + } + + MiraiColors miraiColor = MiraiColors.values.firstWhere( + (e) => e.name == color, + orElse: () => MiraiColors.transparent, + ); + + switch (miraiColor) { + case MiraiColors.amber: + return Colors.amber; + case MiraiColors.amberAccent: + return Colors.amberAccent; + case MiraiColors.black: + switch (opacity) { + case 12: + return Colors.black12; + case 26: + return Colors.black26; + case 38: + return Colors.black38; + case 45: + return Colors.black45; + case 54: + return Colors.black54; + case 87: + return Colors.black87; + default: + return Colors.black; + } + case MiraiColors.blue: + return Colors.blue; + case MiraiColors.blueAccent: + return Colors.blueAccent; + case MiraiColors.blueGrey: + return Colors.blueGrey; + case MiraiColors.brown: + return Colors.brown; + case MiraiColors.cyan: + return Colors.cyan; + case MiraiColors.cyanAccent: + return Colors.cyanAccent; + case MiraiColors.deepOrange: + return Colors.deepOrange; + case MiraiColors.deepOrangeAccent: + return Colors.deepOrangeAccent; + case MiraiColors.deepPurple: + return Colors.deepPurple; + case MiraiColors.deepPurpleAccent: + return Colors.deepPurpleAccent; + case MiraiColors.green: + return Colors.green; + case MiraiColors.greenAccent: + return Colors.greenAccent; + case MiraiColors.grey: + return Colors.grey; + case MiraiColors.indigo: + return Colors.indigo; + case MiraiColors.indigoAccent: + return Colors.indigoAccent; + case MiraiColors.lightBlue: + return Colors.lightBlue; + case MiraiColors.lightBlueAccent: + return Colors.lightBlueAccent; + case MiraiColors.lightGreen: + return Colors.lightGreen; + case MiraiColors.lightGreenAccent: + return Colors.lightGreenAccent; + case MiraiColors.lime: + return Colors.lime; + case MiraiColors.limeAccent: + return Colors.limeAccent; + case MiraiColors.orange: + return Colors.orange; + case MiraiColors.orangeAccent: + return Colors.orangeAccent; + case MiraiColors.pink: + return Colors.pink; + case MiraiColors.pinkAccent: + return Colors.pinkAccent; + case MiraiColors.purple: + return Colors.purple; + case MiraiColors.purpleAccent: + return Colors.purpleAccent; + case MiraiColors.red: + return Colors.red; + case MiraiColors.redAccent: + return Colors.redAccent; + case MiraiColors.teal: + return Colors.teal; + case MiraiColors.tealAccent: + return Colors.tealAccent; + case MiraiColors.transparent: + return Colors.transparent; + case MiraiColors.white: + switch (opacity) { + case 10: + return Colors.white10; + case 12: + return Colors.white12; + case 24: + return Colors.white24; + case 30: + return Colors.white30; + case 38: + return Colors.white38; + case 54: + return Colors.white54; + case 60: + return Colors.white60; + case 70: + return Colors.white70; + default: + return Colors.white; + } + case MiraiColors.yellow: + return Colors.yellow; + case MiraiColors.yellowAccent: + return Colors.yellowAccent; + } } diff --git a/website/docs/styles/colors.md b/website/docs/styles/colors.md new file mode 100644 index 00000000..8c9cc538 --- /dev/null +++ b/website/docs/styles/colors.md @@ -0,0 +1,62 @@ +# Color + +The `Color` that can apply to different Flutter widgets for example text color, background color, border color etc. [official documentation](https://api.flutter.dev/flutter/material/Colors-class.html). + +## Types of color + +There are three different types of colors. Theme color, Hex color and Name color. + +### Theme colors + +The Theme colors are theme based colors which we define in theme. + +These are the theme colors [`primary`, `onPrimary`,`primaryContainer`, `onPrimaryContainer`, `secondary`, `onSecondary`, `secondaryContainer`, `onSecondaryContainer`, `tertiary`, `onTertiary`, `tertiaryContainer`, `onTertiaryContainer`, `error`, `onError`, `errorContainer`, `onErrorContainer`, `background`, `onBackground`, `surface`, `onSurface`, `surfaceVariant`, `onSurfaceVariant`, `outline`, `outlineVariant`, `shadow`, `scrim`, `inverseSurface`, `onInverseSurface`, `inversePrimary`, `surfaceTint`, `scaffoldBackgroundColor`]. + +### Hex colors + +The Hex colors will allows to define custom hex value. It could be 6 digit Hex code(`#FF0000`) or it could be 8 digit Hex code(`#88FF0000`) where first 2 digits are for opacity. + +### Name colors + +The Name colors will allows to provide color by using color names and opacity for black and white colors. + +These are the name colors [`amber`, `amberAccent`, `black`, `blue`, `blueAccent`, `blueGrey`, `brown`, `cyan`, `cyanAccent`, `deepOrange`, `deepOrangeAccent`, `deepPurple`, `deepPurpleAccent`, `green`, `greenAccent`, `grey`, `indigo`, `indigoAccent`, `lightBlue`, `lightBlueAccent`, `lightGreen`, `lightGreenAccent`, `lime`, `limeAccent`, `orange`, `orangeAccent`, `pink`, `pinkAccent`, `purple`, `purpleAccent`, `red`, `redAccent`, `teal`, `tealAccent`, `transparent`, `white`, `yellow`, `yellowAccent`]. + +These are the opacities for white color [`10`, `12`, `24`, `30`, `38`, `54`, `60`, `70`]. + +These are the opacities for black color [`12`, `26`, `38`, `45`, `54`, `87`]. + +## Example + +### Example 1: Theme color +```json +{ + "type": "text", + "data": "Hello World!", + "style": { + "color": "primary" + } +} +``` + +### Example 2: Hex color +```json +{ + "type": "text", + "data": "Hello World!", + "style": { + "color": "#000000" + } +} +``` + +### Example 3: Name color +```json +{ + "type": "text", + "data": "Hello World!", + "style": { + "color": "black45" + } +} +```