From 76966de1d90736616184ce7109ae045916e40bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20Rouleau?= Date: Sat, 5 Oct 2024 09:32:29 -0400 Subject: [PATCH] Add safe alignment utilities --- CHANGELOG.md | 1 + .../__snapshots__/intellisense.test.ts.snap | 18 ++++ packages/tailwindcss/src/feature-flags.ts | 1 + packages/tailwindcss/src/utilities.test.ts | 90 +++++++++++++++++++ packages/tailwindcss/src/utilities.ts | 38 +++++++- 5 files changed, 147 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90bf51e49fd8..99ab5eb4cc90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - _Experimental_: Add `items-baseline-last` utility ([#12128](https://github.com/tailwindlabs/tailwindcss/pull/12128)) - _Experimental_: Add `pointer-none`, `pointer-coarse`, and `pointer-fine` variant ([#16946](https://github.com/tailwindlabs/tailwindcss/pull/16946)) - _Experimental_: Add `any-pointer-none`, `any-pointer-coarse`, and `any-pointer-fine` variants ([#16941](https://github.com/tailwindlabs/tailwindcss/pull/16941)) +- _Experimental_: Add safe alignment utilities ([#14607](https://github.com/tailwindlabs/tailwindcss/pull/14607)) - _Experimental_: Add `user-valid` and `user-invalid` variants ([#12370](https://github.com/tailwindlabs/tailwindcss/pull/12370)) - _Experimental_: Add `wrap-anywhere`, `wrap-break-word`, and `wrap-normal` utilities ([#12128](https://github.com/tailwindlabs/tailwindcss/pull/12128)) - _Experimental_: Add `@source inline(…)` ([#17147](https://github.com/tailwindlabs/tailwindcss/pull/17147)) diff --git a/packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snap b/packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snap index bab443a14ad3..7fef73d37e71 100644 --- a/packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snap +++ b/packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snap @@ -3746,7 +3746,9 @@ exports[`getClassList 1`] = ` "content-baseline", "content-between", "content-center", + "content-center-safe", "content-end", + "content-end-safe", "content-evenly", "content-none", "content-normal", @@ -4877,24 +4879,32 @@ exports[`getClassList 1`] = ` "items-baseline", "items-baseline-last", "items-center", + "items-center-safe", "items-end", + "items-end-safe", "items-start", "items-stretch", "justify-around", "justify-baseline", "justify-between", "justify-center", + "justify-center-safe", "justify-end", + "justify-end-safe", "justify-evenly", "justify-items-center", + "justify-items-center-safe", "justify-items-end", + "justify-items-end-safe", "justify-items-normal", "justify-items-start", "justify-items-stretch", "justify-normal", "justify-self-auto", "justify-self-center", + "justify-self-center-safe", "justify-self-end", + "justify-self-end-safe", "justify-self-start", "justify-self-stretch", "justify-start", @@ -6005,18 +6015,24 @@ exports[`getClassList 1`] = ` "place-content-baseline", "place-content-between", "place-content-center", + "place-content-center-safe", "place-content-end", + "place-content-end-safe", "place-content-evenly", "place-content-start", "place-content-stretch", "place-items-baseline", "place-items-center", + "place-items-center-safe", "place-items-end", + "place-items-end-safe", "place-items-start", "place-items-stretch", "place-self-auto", "place-self-center", + "place-self-center-safe", "place-self-end", + "place-self-end-safe", "place-self-start", "place-self-stretch", "placeholder-current", @@ -7280,7 +7296,9 @@ exports[`getClassList 1`] = ` "self-auto", "self-baseline", "self-center", + "self-center-safe", "self-end", + "self-end-safe", "self-start", "self-stretch", "sepia", diff --git a/packages/tailwindcss/src/feature-flags.ts b/packages/tailwindcss/src/feature-flags.ts index d29a8f6cadd4..203bfe335af8 100644 --- a/packages/tailwindcss/src/feature-flags.ts +++ b/packages/tailwindcss/src/feature-flags.ts @@ -2,6 +2,7 @@ export const enableBaselineLast = process.env.FEATURES_ENV !== 'stable' export const enableDetailsContent = process.env.FEATURES_ENV !== 'stable' export const enableInvertedColors = process.env.FEATURES_ENV !== 'stable' export const enablePointerVariants = process.env.FEATURES_ENV !== 'stable' +export const enableSafeAlignment = process.env.FEATURES_ENV !== 'stable' export const enableScripting = process.env.FEATURES_ENV !== 'stable' export const enableSourceInline = process.env.FEATURES_ENV !== 'stable' export const enableUserValid = process.env.FEATURES_ENV !== 'stable' diff --git a/packages/tailwindcss/src/utilities.test.ts b/packages/tailwindcss/src/utilities.test.ts index b55ffe4e4838..5b4c6eba94aa 100644 --- a/packages/tailwindcss/src/utilities.test.ts +++ b/packages/tailwindcss/src/utilities.test.ts @@ -7125,8 +7125,10 @@ test('place-content', async () => { expect( await run([ 'place-content-center', + 'place-content-center-safe', 'place-content-start', 'place-content-end', + 'place-content-end-safe', 'place-content-between', 'place-content-around', 'place-content-evenly', @@ -7150,10 +7152,18 @@ test('place-content', async () => { place-content: center; } + .place-content-center-safe { + place-content: safe center; + } + .place-content-end { place-content: end; } + .place-content-end-safe { + place-content: safe end; + } + .place-content-evenly { place-content: space-evenly; } @@ -7194,7 +7204,9 @@ test('place-items', async () => { await run([ 'place-items-start', 'place-items-end', + 'place-items-end-safe', 'place-items-center', + 'place-items-center-safe', 'place-items-baseline', 'place-items-stretch', ]), @@ -7207,10 +7219,18 @@ test('place-items', async () => { place-items: center; } + .place-items-center-safe { + place-items: safe center; + } + .place-items-end { place-items: end; } + .place-items-end-safe { + place-items: safe end; + } + .place-items-start { place-items: start; } @@ -7241,8 +7261,10 @@ test('align-content', async () => { await run([ 'content-normal', 'content-center', + 'content-center-safe', 'content-start', 'content-end', + 'content-end-safe', 'content-between', 'content-around', 'content-evenly', @@ -7266,10 +7288,18 @@ test('align-content', async () => { align-content: center; } + .content-center-safe { + align-content: safe center; + } + .content-end { align-content: flex-end; } + .content-end-safe { + align-content: safe flex-end; + } + .content-evenly { align-content: space-evenly; } @@ -7316,7 +7346,9 @@ test('items', async () => { await run([ 'items-start', 'items-end', + 'items-end-safe', 'items-center', + 'items-center-safe', 'items-baseline', 'items-baseline-last', 'items-stretch', @@ -7334,10 +7366,18 @@ test('items', async () => { align-items: center; } + .items-center-safe { + align-items: safe center; + } + .items-end { align-items: flex-end; } + .items-end-safe { + align-items: safe flex-end; + } + .items-start { align-items: flex-start; } @@ -7371,7 +7411,9 @@ test('justify', async () => { 'justify-normal', 'justify-start', 'justify-end', + 'justify-end-safe', 'justify-center', + 'justify-center-safe', 'justify-between', 'justify-around', 'justify-evenly', @@ -7390,10 +7432,18 @@ test('justify', async () => { justify-content: center; } + .justify-center-safe { + justify-content: safe center; + } + .justify-end { justify-content: flex-end; } + .justify-end-safe { + justify-content: safe flex-end; + } + .justify-evenly { justify-content: space-evenly; } @@ -7438,7 +7488,9 @@ test('justify-items', async () => { await run([ 'justify-items-start', 'justify-items-end', + 'justify-items-end-safe', 'justify-items-center', + 'justify-items-center-safe', 'justify-items-stretch', ]), ).toMatchInlineSnapshot(` @@ -7446,10 +7498,18 @@ test('justify-items', async () => { justify-items: center; } + .justify-items-center-safe { + justify-items: safe center; + } + .justify-items-end { justify-items: end; } + .justify-items-end-safe { + justify-items: safe end; + } + .justify-items-start { justify-items: start; } @@ -8298,7 +8358,9 @@ test('place-self', async () => { 'place-self-auto', 'place-self-start', 'place-self-end', + 'place-self-end-safe', 'place-self-center', + 'place-self-center-safe', 'place-self-stretch', ]), ).toMatchInlineSnapshot(` @@ -8310,10 +8372,18 @@ test('place-self', async () => { place-self: center; } + .place-self-center-safe { + place-self: safe center; + } + .place-self-end { place-self: end; } + .place-self-end-safe { + place-self: safe end; + } + .place-self-start { place-self: start; } @@ -8345,7 +8415,9 @@ test('self', async () => { 'self-auto', 'self-start', 'self-end', + 'self-end-safe', 'self-center', + 'self-center-safe', 'self-stretch', 'self-baseline', ]), @@ -8362,10 +8434,18 @@ test('self', async () => { align-self: center; } + .self-center-safe { + align-self: safe center; + } + .self-end { align-self: flex-end; } + .self-end-safe { + align-self: safe flex-end; + } + .self-start { align-self: flex-start; } @@ -8399,7 +8479,9 @@ test('justify-self', async () => { 'justify-self-auto', 'justify-self-start', 'justify-self-end', + 'justify-self-end-safe', 'justify-self-center', + 'justify-self-center-safe', 'justify-self-stretch', 'justify-self-baseline', ]), @@ -8412,10 +8494,18 @@ test('justify-self', async () => { justify-self: center; } + .justify-self-center-safe { + justify-self: safe center; + } + .justify-self-end { justify-self: flex-end; } + .justify-self-end-safe { + justify-self: safe flex-end; + } + .justify-self-start { justify-self: flex-start; } diff --git a/packages/tailwindcss/src/utilities.ts b/packages/tailwindcss/src/utilities.ts index 70dedd7c3135..9d8568f686c4 100644 --- a/packages/tailwindcss/src/utilities.ts +++ b/packages/tailwindcss/src/utilities.ts @@ -11,7 +11,7 @@ import { } from './ast' import type { Candidate, CandidateModifier, NamedUtilityValue } from './candidate' import type { DesignSystem } from './design-system' -import { enableBaselineLast, enableWrapAnywhere } from './feature-flags' +import { enableBaselineLast, enableSafeAlignment, enableWrapAnywhere } from './feature-flags' import type { Theme, ThemeKey } from './theme' import { compareBreakpoints } from './utils/compare-breakpoints' import { DefaultMap } from './utils/default-map' @@ -1856,6 +1856,10 @@ export function createUtilities(theme: Theme) { staticUtility('place-content-center', [['place-content', 'center']]) staticUtility('place-content-start', [['place-content', 'start']]) staticUtility('place-content-end', [['place-content', 'end']]) + if (enableSafeAlignment) { + staticUtility('place-content-center-safe', [['place-content', 'safe center']]) + staticUtility('place-content-end-safe', [['place-content', 'safe end']]) + } staticUtility('place-content-between', [['place-content', 'space-between']]) staticUtility('place-content-around', [['place-content', 'space-around']]) staticUtility('place-content-evenly', [['place-content', 'space-evenly']]) @@ -1865,6 +1869,10 @@ export function createUtilities(theme: Theme) { staticUtility('place-items-center', [['place-items', 'center']]) staticUtility('place-items-start', [['place-items', 'start']]) staticUtility('place-items-end', [['place-items', 'end']]) + if (enableSafeAlignment) { + staticUtility('place-items-center-safe', [['place-items', 'safe center']]) + staticUtility('place-items-end-safe', [['place-items', 'safe end']]) + } staticUtility('place-items-baseline', [['place-items', 'baseline']]) staticUtility('place-items-stretch', [['place-items', 'stretch']]) @@ -1872,6 +1880,10 @@ export function createUtilities(theme: Theme) { staticUtility('content-center', [['align-content', 'center']]) staticUtility('content-start', [['align-content', 'flex-start']]) staticUtility('content-end', [['align-content', 'flex-end']]) + if (enableSafeAlignment) { + staticUtility('content-center-safe', [['align-content', 'safe center']]) + staticUtility('content-end-safe', [['align-content', 'safe flex-end']]) + } staticUtility('content-between', [['align-content', 'space-between']]) staticUtility('content-around', [['align-content', 'space-around']]) staticUtility('content-evenly', [['align-content', 'space-evenly']]) @@ -1881,6 +1893,10 @@ export function createUtilities(theme: Theme) { staticUtility('items-center', [['align-items', 'center']]) staticUtility('items-start', [['align-items', 'flex-start']]) staticUtility('items-end', [['align-items', 'flex-end']]) + if (enableSafeAlignment) { + staticUtility('items-center-safe', [['align-items', 'safe center']]) + staticUtility('items-end-safe', [['align-items', 'safe flex-end']]) + } staticUtility('items-baseline', [['align-items', 'baseline']]) if (enableBaselineLast) { staticUtility('items-baseline-last', [['align-items', 'last baseline']]) @@ -1891,6 +1907,10 @@ export function createUtilities(theme: Theme) { staticUtility('justify-center', [['justify-content', 'center']]) staticUtility('justify-start', [['justify-content', 'flex-start']]) staticUtility('justify-end', [['justify-content', 'flex-end']]) + if (enableSafeAlignment) { + staticUtility('justify-center-safe', [['justify-content', 'safe center']]) + staticUtility('justify-end-safe', [['justify-content', 'safe flex-end']]) + } staticUtility('justify-between', [['justify-content', 'space-between']]) staticUtility('justify-around', [['justify-content', 'space-around']]) staticUtility('justify-evenly', [['justify-content', 'space-evenly']]) @@ -1901,6 +1921,10 @@ export function createUtilities(theme: Theme) { staticUtility('justify-items-center', [['justify-items', 'center']]) staticUtility('justify-items-start', [['justify-items', 'start']]) staticUtility('justify-items-end', [['justify-items', 'end']]) + if (enableSafeAlignment) { + staticUtility('justify-items-center-safe', [['justify-items', 'safe center']]) + staticUtility('justify-items-end-safe', [['justify-items', 'safe end']]) + } staticUtility('justify-items-stretch', [['justify-items', 'stretch']]) spacingUtility('gap', ['--gap', '--spacing'], (value) => [decl('gap', value)]) @@ -1981,12 +2005,20 @@ export function createUtilities(theme: Theme) { staticUtility('place-self-start', [['place-self', 'start']]) staticUtility('place-self-end', [['place-self', 'end']]) staticUtility('place-self-center', [['place-self', 'center']]) + if (enableSafeAlignment) { + staticUtility('place-self-end-safe', [['place-self', 'safe end']]) + staticUtility('place-self-center-safe', [['place-self', 'safe center']]) + } staticUtility('place-self-stretch', [['place-self', 'stretch']]) staticUtility('self-auto', [['align-self', 'auto']]) staticUtility('self-start', [['align-self', 'flex-start']]) staticUtility('self-end', [['align-self', 'flex-end']]) staticUtility('self-center', [['align-self', 'center']]) + if (enableSafeAlignment) { + staticUtility('self-end-safe', [['align-self', 'safe flex-end']]) + staticUtility('self-center-safe', [['align-self', 'safe center']]) + } staticUtility('self-stretch', [['align-self', 'stretch']]) staticUtility('self-baseline', [['align-self', 'baseline']]) @@ -1994,6 +2026,10 @@ export function createUtilities(theme: Theme) { staticUtility('justify-self-start', [['justify-self', 'flex-start']]) staticUtility('justify-self-end', [['justify-self', 'flex-end']]) staticUtility('justify-self-center', [['justify-self', 'center']]) + if (enableSafeAlignment) { + staticUtility('justify-self-end-safe', [['justify-self', 'safe flex-end']]) + staticUtility('justify-self-center-safe', [['justify-self', 'safe center']]) + } staticUtility('justify-self-stretch', [['justify-self', 'stretch']]) for (let value of ['auto', 'hidden', 'clip', 'visible', 'scroll']) {