diff --git a/CHANGELOG.md b/CHANGELOG.md index 872da98b6c43..19dc2a86ceba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Nothing yet! +### Fixed + +- Ensure individual logical property utilities are sorted later than left/right pair utilities ([#14777](https://github.com/tailwindlabs/tailwindcss/pull/14777)) ## [4.0.0-alpha.29] - 2024-10-23 diff --git a/packages/tailwindcss/src/index.test.ts b/packages/tailwindcss/src/index.test.ts index 5c1f6286c6a5..ccae67e19651 100644 --- a/packages/tailwindcss/src/index.test.ts +++ b/packages/tailwindcss/src/index.test.ts @@ -674,6 +674,100 @@ describe('sorting', () => { `) }) + it('should sort individual logical properties later than left/right pairs', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-1: 1px; + --spacing-2: 2px; + --spacing-3: 3px; + } + @tailwind utilities; + `, + [ + // scroll-margin + 'scroll-ms-1', + 'scroll-me-2', + 'scroll-mx-3', + + // scroll-padding + 'scroll-ps-1', + 'scroll-pe-2', + 'scroll-px-3', + + // margin + 'ms-1', + 'me-2', + 'mx-3', + + // padding + 'ps-1', + 'pe-2', + 'px-3', + ].sort(() => Math.random() - 0.5), + ), + ).toMatchInlineSnapshot(` + ":root { + --spacing-1: 1px; + --spacing-2: 2px; + --spacing-3: 3px; + } + + .mx-3 { + margin-left: var(--spacing-3, 3px); + margin-right: var(--spacing-3, 3px); + } + + .ms-1 { + margin-inline-start: var(--spacing-1, 1px); + } + + .me-2 { + margin-inline-end: var(--spacing-2, 2px); + } + + .scroll-mx-3 { + scroll-margin-left: var(--spacing-3, 3px); + scroll-margin-right: var(--spacing-3, 3px); + } + + .scroll-ms-1 { + scroll-margin-inline-start: var(--spacing-1, 1px); + } + + .scroll-me-2 { + scroll-margin-inline-end: var(--spacing-2, 2px); + } + + .scroll-px-3 { + scroll-padding-left: var(--spacing-3, 3px); + scroll-padding-right: var(--spacing-3, 3px); + } + + .scroll-ps-1 { + scroll-padding-inline-start: var(--spacing-1, 1px); + } + + .scroll-pe-2 { + scroll-padding-inline-end: var(--spacing-2, 2px); + } + + .px-3 { + padding-left: var(--spacing-3, 3px); + padding-right: var(--spacing-3, 3px); + } + + .ps-1 { + padding-inline-start: var(--spacing-1, 1px); + } + + .pe-2 { + padding-inline-end: var(--spacing-2, 2px); + }" + `) + }) + it('should move variants to the end while sorting', async () => { expect( await run( diff --git a/packages/tailwindcss/src/property-order.ts b/packages/tailwindcss/src/property-order.ts index d448ec05bd5f..0305f173ca98 100644 --- a/packages/tailwindcss/src/property-order.ts +++ b/packages/tailwindcss/src/property-order.ts @@ -99,6 +99,8 @@ export default [ 'scroll-snap-align', 'scroll-snap-stop', 'scroll-margin', + 'scroll-margin-inline', + 'scroll-margin-block', 'scroll-margin-inline-start', 'scroll-margin-inline-end', 'scroll-margin-top', @@ -107,6 +109,8 @@ export default [ 'scroll-margin-left', 'scroll-padding', + 'scroll-padding-inline', + 'scroll-padding-block', 'scroll-padding-inline-start', 'scroll-padding-inline-end', 'scroll-padding-top', diff --git a/packages/tailwindcss/src/sort.test.ts b/packages/tailwindcss/src/sort.test.ts index 992c1d14102e..6ced80929cfb 100644 --- a/packages/tailwindcss/src/sort.test.ts +++ b/packages/tailwindcss/src/sort.test.ts @@ -16,14 +16,14 @@ function loadDesign() { const table = [ // Utilities - ['px-3 p-1 py-3', 'p-1 py-3 px-3'], + ['py-3 p-1 px-3', 'p-1 px-3 py-3'], // Utilities with variants - ['px-3 focus:hover:p-3 hover:p-1 py-3', 'py-3 px-3 hover:p-1 focus:hover:p-3'], + ['px-3 focus:hover:p-3 hover:p-1 py-3', 'px-3 py-3 hover:p-1 focus:hover:p-3'], // Utilities with important - ['px-3 py-4! p-1', 'p-1 py-4! px-3'], - ['py-4! px-3 p-1', 'p-1 py-4! px-3'], + ['px-3 py-4! p-1', 'p-1 px-3 py-4!'], + ['py-4! px-3 p-1', 'p-1 px-3 py-4!'], // User CSS order is the same and moved to the front ['b p-1 a', 'b a p-1'], @@ -48,11 +48,11 @@ test('can sort classes deterministically across multiple class lists', async () let classes = [ [ 'a-class px-3 p-1 b-class py-3 bg-red-500 bg-blue-500', - 'a-class b-class bg-blue-500 bg-red-500 p-1 py-3 px-3', + 'a-class b-class bg-blue-500 bg-red-500 p-1 px-3 py-3', ], [ 'px-3 b-class p-1 py-3 bg-blue-500 a-class bg-red-500', - 'b-class a-class bg-blue-500 bg-red-500 p-1 py-3 px-3', + 'b-class a-class bg-blue-500 bg-red-500 p-1 px-3 py-3', ], ] diff --git a/packages/tailwindcss/src/utilities.ts b/packages/tailwindcss/src/utilities.ts index 5d46c7f32ab2..b0ab8519fdae 100644 --- a/packages/tailwindcss/src/utilities.ts +++ b/packages/tailwindcss/src/utilities.ts @@ -1743,13 +1743,21 @@ export function createUtilities(theme: Theme) { functionalUtility('scroll-mx', { supportsNegative: true, themeKeys: ['--scroll-margin', '--spacing'], - handle: (value) => [decl('scroll-margin-left', value), decl('scroll-margin-right', value)], + handle: (value) => [ + decl('--tw-sort', 'scroll-margin-inline'), + decl('scroll-margin-left', value), + decl('scroll-margin-right', value), + ], }) functionalUtility('scroll-my', { supportsNegative: true, themeKeys: ['--scroll-margin', '--spacing'], - handle: (value) => [decl('scroll-margin-top', value), decl('scroll-margin-bottom', value)], + handle: (value) => [ + decl('--tw-sort', 'scroll-margin-block'), + decl('scroll-margin-top', value), + decl('scroll-margin-bottom', value), + ], }) functionalUtility('scroll-ms', { @@ -1798,13 +1806,21 @@ export function createUtilities(theme: Theme) { functionalUtility('scroll-px', { supportsNegative: true, themeKeys: ['--scroll-padding', '--spacing'], - handle: (value) => [decl('scroll-padding-left', value), decl('scroll-padding-right', value)], + handle: (value) => [ + decl('--tw-sort', 'scroll-padding-inline'), + decl('scroll-padding-left', value), + decl('scroll-padding-right', value), + ], }) functionalUtility('scroll-py', { supportsNegative: true, themeKeys: ['--scroll-padding', '--spacing'], - handle: (value) => [decl('scroll-padding-top', value), decl('scroll-padding-bottom', value)], + handle: (value) => [ + decl('--tw-sort', 'scroll-padding-block'), + decl('scroll-padding-top', value), + decl('scroll-padding-bottom', value), + ], }) functionalUtility('scroll-ps', { @@ -2960,12 +2976,20 @@ export function createUtilities(theme: Theme) { functionalUtility('px', { themeKeys: ['--padding', '--spacing'], - handle: (value) => [decl('padding-left', value), decl('padding-right', value)], + handle: (value) => [ + decl('--tw-sort', 'padding-inline'), + decl('padding-left', value), + decl('padding-right', value), + ], }) functionalUtility('py', { themeKeys: ['--padding', '--spacing'], - handle: (value) => [decl('padding-top', value), decl('padding-bottom', value)], + handle: (value) => [ + decl('--tw-sort', 'padding-block'), + decl('padding-top', value), + decl('padding-bottom', value), + ], }) functionalUtility('pt', {