@@ -39,6 +39,19 @@ bool _hasBoxUtilities(String classNames) {
3939 return false ;
4040}
4141
42+ (String ? , String ) _splitMarginToken (String base ) {
43+ const prefixes = ['mx-' , 'my-' , 'mt-' , 'mr-' , 'mb-' , 'ml-' , 'm-' ];
44+ for (final prefix in prefixes) {
45+ if (base .startsWith (prefix)) {
46+ return (
47+ prefix.substring (0 , prefix.length - 1 ),
48+ base .substring (prefix.length),
49+ );
50+ }
51+ }
52+ return (null , base );
53+ }
54+
4255/// Extract margin value from tokens for a given prefix (e.g., 'mb-').
4356/// Returns null if not found.
4457EdgeInsets ? _extractMargin (String classNames, TwConfig cfg) {
@@ -49,41 +62,27 @@ EdgeInsets? _extractMargin(String classNames, TwConfig cfg) {
4962 final colonIdx = findLastColonOutsideBrackets (token);
5063 final base = colonIdx >= 0 ? token.substring (colonIdx + 1 ) : token;
5164
52- if (base .startsWith ('m-' )) {
53- final value = cfg.spaceOf (base .substring (2 ), fallback: double .nan);
54- if (! value.isNaN) {
65+ final (prefix, suffix) = _splitMarginToken (base );
66+ if (prefix == null ) continue ;
67+
68+ final value = cfg.spaceOf (suffix, fallback: double .nan);
69+ if (value.isNaN) continue ;
70+
71+ switch (prefix) {
72+ case 'm' :
5573 top = right = bottom = left = value;
56- }
57- } else if (base .startsWith ('mx-' )) {
58- final value = cfg.spaceOf (base .substring (3 ), fallback: double .nan);
59- if (! value.isNaN) {
74+ case 'mx' :
6075 left = right = value;
61- }
62- } else if (base .startsWith ('my-' )) {
63- final value = cfg.spaceOf (base .substring (3 ), fallback: double .nan);
64- if (! value.isNaN) {
76+ case 'my' :
6577 top = bottom = value;
66- }
67- } else if (base .startsWith ('mt-' )) {
68- final value = cfg.spaceOf (base .substring (3 ), fallback: double .nan);
69- if (! value.isNaN) {
78+ case 'mt' :
7079 top = value;
71- }
72- } else if (base .startsWith ('mr-' )) {
73- final value = cfg.spaceOf (base .substring (3 ), fallback: double .nan);
74- if (! value.isNaN) {
80+ case 'mr' :
7581 right = value;
76- }
77- } else if (base .startsWith ('mb-' )) {
78- final value = cfg.spaceOf (base .substring (3 ), fallback: double .nan);
79- if (! value.isNaN) {
82+ case 'mb' :
8083 bottom = value;
81- }
82- } else if (base .startsWith ('ml-' )) {
83- final value = cfg.spaceOf (base .substring (3 ), fallback: double .nan);
84- if (! value.isNaN) {
84+ case 'ml' :
8585 left = value;
86- }
8786 }
8887 }
8988
@@ -392,6 +391,24 @@ class Span extends StatelessWidget {
392391 }
393392}
394393
394+ Widget _buildHeading (
395+ BuildContext context,
396+ String text,
397+ String classNames,
398+ TwConfig ? config,
399+ ) {
400+ final cfg = config ?? TwConfigProvider .of (context);
401+ final style = TwParser (config: cfg).parseText (classNames);
402+ Widget result = StyledText (text, style: style);
403+
404+ final margin = _extractMargin (classNames, cfg);
405+ if (margin != null ) {
406+ result = Padding (padding: margin, child: result);
407+ }
408+
409+ return result;
410+ }
411+
395412/// Heading level 1 element with Tailwind styling.
396413///
397414/// Equivalent to HTML `<h1>` . Note: Like Tailwind's Preflight, headings have
@@ -405,18 +422,8 @@ class H1 extends StatelessWidget {
405422 final TwConfig ? config;
406423
407424 @override
408- Widget build (BuildContext context) {
409- final cfg = config ?? TwConfigProvider .of (context);
410- final style = TwParser (config: cfg).parseText (classNames);
411- Widget result = StyledText (text, style: style);
412-
413- final margin = _extractMargin (classNames, cfg);
414- if (margin != null ) {
415- result = Padding (padding: margin, child: result);
416- }
417-
418- return result;
419- }
425+ Widget build (BuildContext context) =>
426+ _buildHeading (context, text, classNames, config);
420427}
421428
422429/// Heading level 2 element with Tailwind styling.
@@ -432,18 +439,8 @@ class H2 extends StatelessWidget {
432439 final TwConfig ? config;
433440
434441 @override
435- Widget build (BuildContext context) {
436- final cfg = config ?? TwConfigProvider .of (context);
437- final style = TwParser (config: cfg).parseText (classNames);
438- Widget result = StyledText (text, style: style);
439-
440- final margin = _extractMargin (classNames, cfg);
441- if (margin != null ) {
442- result = Padding (padding: margin, child: result);
443- }
444-
445- return result;
446- }
442+ Widget build (BuildContext context) =>
443+ _buildHeading (context, text, classNames, config);
447444}
448445
449446/// Heading level 3 element with Tailwind styling.
@@ -459,18 +456,8 @@ class H3 extends StatelessWidget {
459456 final TwConfig ? config;
460457
461458 @override
462- Widget build (BuildContext context) {
463- final cfg = config ?? TwConfigProvider .of (context);
464- final style = TwParser (config: cfg).parseText (classNames);
465- Widget result = StyledText (text, style: style);
466-
467- final margin = _extractMargin (classNames, cfg);
468- if (margin != null ) {
469- result = Padding (padding: margin, child: result);
470- }
471-
472- return result;
473- }
459+ Widget build (BuildContext context) =>
460+ _buildHeading (context, text, classNames, config);
474461}
475462
476463/// Heading level 4 element with Tailwind styling.
@@ -486,18 +473,8 @@ class H4 extends StatelessWidget {
486473 final TwConfig ? config;
487474
488475 @override
489- Widget build (BuildContext context) {
490- final cfg = config ?? TwConfigProvider .of (context);
491- final style = TwParser (config: cfg).parseText (classNames);
492- Widget result = StyledText (text, style: style);
493-
494- final margin = _extractMargin (classNames, cfg);
495- if (margin != null ) {
496- result = Padding (padding: margin, child: result);
497- }
498-
499- return result;
500- }
476+ Widget build (BuildContext context) =>
477+ _buildHeading (context, text, classNames, config);
501478}
502479
503480/// Heading level 5 element with Tailwind styling.
@@ -513,18 +490,8 @@ class H5 extends StatelessWidget {
513490 final TwConfig ? config;
514491
515492 @override
516- Widget build (BuildContext context) {
517- final cfg = config ?? TwConfigProvider .of (context);
518- final style = TwParser (config: cfg).parseText (classNames);
519- Widget result = StyledText (text, style: style);
520-
521- final margin = _extractMargin (classNames, cfg);
522- if (margin != null ) {
523- result = Padding (padding: margin, child: result);
524- }
525-
526- return result;
527- }
493+ Widget build (BuildContext context) =>
494+ _buildHeading (context, text, classNames, config);
528495}
529496
530497/// Heading level 6 element with Tailwind styling.
@@ -540,18 +507,8 @@ class H6 extends StatelessWidget {
540507 final TwConfig ? config;
541508
542509 @override
543- Widget build (BuildContext context) {
544- final cfg = config ?? TwConfigProvider .of (context);
545- final style = TwParser (config: cfg).parseText (classNames);
546- Widget result = StyledText (text, style: style);
547-
548- final margin = _extractMargin (classNames, cfg);
549- if (margin != null ) {
550- result = Padding (padding: margin, child: result);
551- }
552-
553- return result;
554- }
510+ Widget build (BuildContext context) =>
511+ _buildHeading (context, text, classNames, config);
555512}
556513
557514/// Convenience wrapper for truncated text in flex containers.
0 commit comments