Created
February 12, 2022 09:13
-
-
Save 100lvlmaster/e5fd65684aad80a2ae78d0718e8b90bb to your computer and use it in GitHub Desktop.
A helper class to parse css styles from css text to appropriate flutter textstyles and buttonstyles. Also supports gradients
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
class CssParser { | |
const CssParser(); | |
/// | |
static Color getColorFromHashCode(String colorCode) { | |
String color = colorCode.replaceAll("#", "0xff").toLowerCase(); | |
return Color(int.parse(color)); | |
} | |
/// Take [CSS] string and return TextStyle | |
static TextStyle cssToTextStyle(String css) { | |
final List<List<String>> cssArray = _cssLexer(css); | |
TextStyle textStyle = const TextStyle(); | |
for (var e in cssArray) { | |
if (e[0] == 'color') { | |
textStyle = textStyle.copyWith(color: getColorFromHashCode(e[1])); | |
} | |
if (e[0] == 'font-weight') { | |
textStyle = | |
textStyle.copyWith(fontWeight: _parseFontWeight(e[1].trim())); | |
} | |
if (e[0] == 'font-size') { | |
textStyle = textStyle.copyWith( | |
fontSize: double.tryParse(e[1]) ?? 16, | |
); | |
} | |
} | |
return textStyle; | |
} | |
/// Take [CSS] string & return BoxDecoration | |
static BoxDecoration cssToBoxDecoration(String css) { | |
BoxDecoration boxDecoration = const BoxDecoration(); | |
final List<List<String>> cssArray = _cssLexer(css); | |
for (List<String> style in cssArray) { | |
/// Parse background attribute of cards | |
/// | |
if (style[0] == 'background') { | |
/// Css property is a [linear-gradient] | |
if (style[1].trim().startsWith("linear-gradient")) { | |
boxDecoration = boxDecoration.copyWith( | |
gradient: _parseLinearGradient(style[1]), | |
); | |
} | |
/// Css property is a [radial-gradient] | |
if (style[1].trim().startsWith("radial-gradient")) { | |
boxDecoration = boxDecoration.copyWith( | |
gradient: _parseRadialGradient(style[1]), | |
); | |
} | |
} | |
} | |
return boxDecoration; | |
} | |
static RadialGradient? _parseRadialGradient(String gradientstring) { | |
final List<String> valueArray = gradientstring | |
.replaceAll("radial-gradient(", '') | |
.replaceAll("[", "") | |
.replaceAll("]", "") | |
.replaceAll(")", "") | |
.replaceAll(" ", ",") | |
.split(","); | |
List<Color> colors = []; | |
List<double> percents = []; | |
for (String e in valueArray) { | |
if (e.trim().startsWith("#")) { | |
colors.add(getColorFromHashCode(e)); | |
} | |
if (e.trim().endsWith("%")) { | |
final double? parsedVal = double.tryParse(e.trim().replaceAll("%", "")); | |
if (parsedVal != null) { | |
percents.add(parsedVal); | |
} | |
} | |
} | |
return RadialGradient( | |
center: Alignment(percents.removeAt(0) / 100, percents.removeAt(0) / 100), | |
colors: colors, | |
focalRadius: percents.removeLast(), | |
); | |
} | |
/// Parse [linear-gradient] from gradient css attribute | |
static LinearGradient? _parseLinearGradient(String gradientString) { | |
final List<String> valueArray = gradientString | |
.replaceAll("linear-gradient(", '') | |
.replaceAll("[", "") | |
.replaceAll("]", "") | |
.replaceAll(")", "") | |
.replaceAll(" ", ",") | |
.split(","); | |
List<Color> colors = []; | |
List<double> stops = []; | |
double degrees = 0.0; | |
for (var e in valueArray) { | |
if (e.trim().startsWith("#")) { | |
colors.add(getColorFromHashCode(e)); | |
} | |
if (e.trim().endsWith("%")) { | |
final double stop = double.parse(e.replaceAll("%", "")) / 100; | |
stops.add(stop); | |
} | |
if (e.trim().endsWith("deg")) { | |
final double? parsedDegrees = | |
double.tryParse(e.trim().replaceAll("deg", "")); | |
if (parsedDegrees != null) { | |
degrees = parsedDegrees; | |
} | |
} | |
} | |
/// Linear gradient requires the stops to be | |
/// equal to the length of colors | |
if (colors.length >= 2) { | |
return LinearGradient( | |
colors: colors, | |
stops: stops.length == colors.length ? stops : null, | |
transform: GradientRotation(degrees), | |
); | |
} | |
} | |
/// Take [CSS] string & return ButtonStyle | |
static ButtonStyle cssToButtonStyle(String css) { | |
ButtonStyle buttonStyle = ButtonStyle( | |
foregroundColor: MaterialStateProperty.all(Colors.black), | |
backgroundColor: MaterialStateProperty.all(Colors.white), | |
shape: MaterialStateProperty.all( | |
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))), | |
); | |
final List<List<String>> styles = _cssLexer(css); | |
for (var e in styles) { | |
if (e[0] == 'background-color') { | |
buttonStyle = buttonStyle.copyWith( | |
backgroundColor: MaterialStateProperty.all( | |
e[1].trim().length == 7 ? getColorFromHashCode(e[1]) : Colors.white, | |
), | |
); | |
} | |
if (e[0] == 'background') { | |
buttonStyle = buttonStyle.copyWith( | |
backgroundColor: MaterialStateProperty.all( | |
e[1].trim().length == 7 ? getColorFromHashCode(e[1]) : Colors.white, | |
), | |
); | |
} | |
if (e[0] == "color") { | |
buttonStyle = buttonStyle.copyWith( | |
foregroundColor: | |
MaterialStateProperty.all(getColorFromHashCode(e[1])), | |
); | |
} | |
} | |
return buttonStyle; | |
} | |
/// Split a css attribute to key value array | |
static List<List<String>> _cssLexer(String css) { | |
List<List<String>> values = css | |
.replaceAll("}", "") | |
.replaceAll("{", "") | |
.split(';') | |
.map((String e) => e.trim().split(":")) | |
.toList(); | |
return values; | |
} | |
/// Parse [FontWeight] | |
static FontWeight _parseFontWeight(String fontWeight) { | |
switch (fontWeight.substring(fontWeight.length - 3, fontWeight.length)) { | |
case '100': | |
return FontWeight.w100; | |
case '200': | |
return FontWeight.w200; | |
case '300': | |
return FontWeight.w300; | |
case '400': | |
return FontWeight.w400; | |
case '500': | |
return FontWeight.w500; | |
case '600': | |
return FontWeight.w600; | |
case '700': | |
return FontWeight.w700; | |
case '800': | |
return FontWeight.w800; | |
case '900': | |
return FontWeight.w900; | |
default: | |
return FontWeight.normal; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment