@@ -526,4 +526,52 @@ describe('Edge Cases', () => {
526526 expect ( css ) . toContain ( '-' )
527527 } )
528528 } )
529+
530+ // ============================================================================
531+ // Regression: Tailwind-style cascade ordering. Shorthand utilities (`m-0`,
532+ // `p-0`, etc.) MUST emit before directional counterparts (`mx-auto`) so that
533+ // a combination like `class="m-0 mx-auto"` keeps the auto margins — the
534+ // shorthand coming last would otherwise reset them and silently break
535+ // horizontal centering.
536+ // ============================================================================
537+ describe ( 'Cascade order — shorthand vs directional' , ( ) => {
538+ it ( 'emits m-0 BEFORE mx-auto regardless of generate() order' , ( ) => {
539+ const gen = new CSSGenerator ( defaultConfig )
540+ // Authoring order: mx-auto first, m-0 second — the buggy case
541+ gen . generate ( 'mx-auto' )
542+ gen . generate ( 'm-0' )
543+ const css = gen . toCSS ( false )
544+ const mPos = css . indexOf ( '.m-0' )
545+ const mxPos = css . indexOf ( '.mx-auto' )
546+ expect ( mPos ) . toBeGreaterThan ( - 1 )
547+ expect ( mxPos ) . toBeGreaterThan ( - 1 )
548+ // mx-auto must appear AFTER m-0 in the output
549+ expect ( mxPos ) . toBeGreaterThan ( mPos )
550+ } )
551+
552+ it ( 'emits p-2 BEFORE py-4 so py overrides shorthand on equal specificity' , ( ) => {
553+ const gen = new CSSGenerator ( defaultConfig )
554+ gen . generate ( 'py-4' )
555+ gen . generate ( 'p-2' )
556+ const css = gen . toCSS ( false )
557+ expect ( css . indexOf ( '.py-4' ) ) . toBeGreaterThan ( css . indexOf ( '.p-2' ) )
558+ } )
559+
560+ it ( 'emits mx-auto BEFORE mt-4 (axis before single-side)' , ( ) => {
561+ const gen = new CSSGenerator ( defaultConfig )
562+ gen . generate ( 'mt-4' )
563+ gen . generate ( 'mx-auto' )
564+ const css = gen . toCSS ( false )
565+ expect ( css . indexOf ( '.mt-4' ) ) . toBeGreaterThan ( css . indexOf ( '.mx-auto' ) )
566+ } )
567+
568+ it ( 'stably preserves order within the same rank' , ( ) => {
569+ const gen = new CSSGenerator ( defaultConfig )
570+ gen . generate ( 'p-2' )
571+ gen . generate ( 'm-0' )
572+ const css = gen . toCSS ( false )
573+ // Both rank 0; p-2 was emitted first, so it stays first
574+ expect ( css . indexOf ( '.p-2' ) ) . toBeLessThan ( css . indexOf ( '.m-0' ) )
575+ } )
576+ } )
529577} )
0 commit comments