From fd25de3956ad7437d5b4713383bff98b18d555d3 Mon Sep 17 00:00:00 2001 From: junk-debug Date: Mon, 24 Nov 2025 15:57:52 +0100 Subject: [PATCH] feat: Add safe area border utilities with offset and "or" variants, along with corresponding tests. --- index.css | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++ test/main.js | 53 ++++++++++++++++ 2 files changed, 226 insertions(+) diff --git a/index.css b/index.css index 3236943..5111269 100644 --- a/index.css +++ b/index.css @@ -1849,3 +1849,176 @@ calc(--spacing(--value(integer, [integer])) * -1) ); } + + +/* Base border utilities */ +@utility border-safe { + border-top-width: var(--twsa-safe-area-inset-top); + border-right-width: var(--twsa-safe-area-inset-right); + border-bottom-width: var(--twsa-safe-area-inset-bottom); + border-left-width: var(--twsa-safe-area-inset-left); +} +@utility border-x-safe { + border-right-width: var(--twsa-safe-area-inset-right); + border-left-width: var(--twsa-safe-area-inset-left); +} +@utility border-y-safe { + border-top-width: var(--twsa-safe-area-inset-top); + border-bottom-width: var(--twsa-safe-area-inset-bottom); +} +@utility border-s-safe { + border-inline-start-width: var(--twsa-safe-area-inset-left); +} +@utility border-e-safe { + border-inline-end-width: var(--twsa-safe-area-inset-right); +} +@utility border-t-safe { + border-top-width: var(--twsa-safe-area-inset-top); +} +@utility border-r-safe { + border-right-width: var(--twsa-safe-area-inset-right); +} +@utility border-b-safe { + border-bottom-width: var(--twsa-safe-area-inset-bottom); +} +@utility border-l-safe { + border-left-width: var(--twsa-safe-area-inset-left); +} + +/* Border utilities with offset variant */ +@utility border-safe-offset-* { + border-top-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-top) + ); + border-right-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-right) + ); + border-bottom-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-bottom) + ); + border-left-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-left) + ); +} +@utility border-x-safe-offset-* { + border-right-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-right) + ); + border-left-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-left) + ); +} +@utility border-y-safe-offset-* { + border-top-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-top) + ); + border-bottom-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-bottom) + ); +} +@utility border-s-safe-offset-* { + border-inline-start-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-left) + ); +} +@utility border-e-safe-offset-* { + border-inline-end-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-right) + ); +} +@utility border-t-safe-offset-* { + border-top-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-top) + ); +} +@utility border-r-safe-offset-* { + border-right-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-right) + ); +} +@utility border-b-safe-offset-* { + border-bottom-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-bottom) + ); +} +@utility border-l-safe-offset-* { + border-left-width: --spacing( + --value(integer, [integer]) + var(--twsa-safe-area-inset-left) + ); +} + +/* Border utilities with or variant */ +@utility border-safe-or-* { + border-top-width: max( + var(--twsa-safe-area-inset-top), + --spacing(--value(integer, [integer])) + ); + border-right-width: max( + var(--twsa-safe-area-inset-right), + --spacing(--value(integer, [integer])) + ); + border-bottom-width: max( + var(--twsa-safe-area-inset-bottom), + --spacing(--value(integer, [integer])) + ); + border-left-width: max( + var(--twsa-safe-area-inset-left), + --spacing(--value(integer, [integer])) + ); +} +@utility border-x-safe-or-* { + border-right-width: max( + var(--twsa-safe-area-inset-right), + --spacing(--value(integer, [integer])) + ); + border-left-width: max( + var(--twsa-safe-area-inset-left), + --spacing(--value(integer, [integer])) + ); +} +@utility border-y-safe-or-* { + border-top-width: max( + var(--twsa-safe-area-inset-top), + --spacing(--value(integer, [integer])) + ); + border-bottom-width: max( + var(--twsa-safe-area-inset-bottom), + --spacing(--value(integer, [integer])) + ); +} +@utility border-s-safe-or-* { + border-inline-start-width: max( + var(--twsa-safe-area-inset-left), + --spacing(--value(integer, [integer])) + ); +} +@utility border-e-safe-or-* { + border-inline-end-width: max( + var(--twsa-safe-area-inset-right), + --spacing(--value(integer, [integer])) + ); +} +@utility border-t-safe-or-* { + border-top-width: max( + var(--twsa-safe-area-inset-top), + --spacing(--value(integer, [integer])) + ); +} +@utility border-r-safe-or-* { + border-right-width: max( + var(--twsa-safe-area-inset-right), + --spacing(--value(integer, [integer])) + ); +} +@utility border-b-safe-or-* { + border-bottom-width: max( + var(--twsa-safe-area-inset-bottom), + --spacing(--value(integer, [integer])) + ); +} +@utility border-l-safe-or-* { + border-left-width: max( + var(--twsa-safe-area-inset-left), + --spacing(--value(integer, [integer])) + ); +} diff --git a/test/main.js b/test/main.js index 6accb42..e832142 100644 --- a/test/main.js +++ b/test/main.js @@ -384,4 +384,57 @@ describe("Safe Area Utilities", () => { "--twsa-safe-area-inset-left": "0px", }); }); + + test("border", () => { + expectSelectors([ + ".border-safe", + ".border-x-safe", + ".border-y-safe", + ".border-s-safe", + ".border-e-safe", + ".border-t-safe", + ".border-r-safe", + ".border-b-safe", + ".border-l-safe", + ]); + + expectCSSProperties( + Object.fromEntries( + directions.map((d) => [ + `border-${d}-width`, + `var(--twsa-safe-area-inset-${d})`, + ]), + ), + ); + }); + + test("border offset", () => { + expectSelectors([ + ".border-safe-offset-4", + ".border-x-safe-offset-4", + ".border-y-safe-offset-4", + ".border-s-safe-offset-4", + ".border-e-safe-offset-4", + ".border-t-safe-offset-4", + ".border-r-safe-offset-4", + ".border-b-safe-offset-4", + ".border-l-safe-offset-4", + ]); + }); + + test("border or", () => { + expectSelectors([ + ".border-safe-or-4", + ".border-x-safe-or-4", + ".border-y-safe-or-4", + ".border-s-safe-or-4", + ".border-e-safe-or-4", + ".border-t-safe-or-4", + ".border-r-safe-or-4", + ".border-b-safe-or-4", + ".border-l-safe-or-4", + ]); + + ok(css.includes("max(")); + }); });