diff --git a/migration-guide.md b/migration-guide.md index d86649f..1339b97 100644 --- a/migration-guide.md +++ b/migration-guide.md @@ -2,6 +2,36 @@ ## 🚨 Breaking Changes +### Breakpoint Boundaries + +Prior to `v4.0.0` `twrnc` displayed subtly different behavior for media query ranges from +TailwindCSS. Specifically, TailwindCSS media queries are **inclusive** of the _minimum_, +and older versions of `twrnc` were **exclusive** of the range minimum. In practical terms +that means that a utility like `md:bg-black` is applicable in TailwindCSS _when the screen +size is **exactly** `768px` wide,_ whereas in `twrnc@3.x.x` that class would only begin to +apply at **`769px`.** Version `4.0.0` corrects this off-by-one error, making the library +more consistent with TailwindCSS. + +We think that this will not affect most library consumers, but it is possible that you +could see a difference in appearance if your device window size is precisely the same as a +media query range minimum, so this is technically a breaking change. + +If you'd like to restore the prior behavior, you can customize your theme's `screens`, +settings: + +```js +module.exports = { + theme: { + screens: { + sm: '641px', + md: '769px', + lg: '1025px', + xl: '1281px', + }, + }, +}; +``` + ### `useAppColorScheme()` Initialization _NB: If you were not using dark mode, or were only observing the device's color scheme diff --git a/src/ClassParser.ts b/src/ClassParser.ts index f7cafd6..7dfd081 100644 --- a/src/ClassParser.ts +++ b/src/ClassParser.ts @@ -63,7 +63,7 @@ export default class ClassParser { const windowWidth = device.windowDimensions?.width; if (windowWidth) { const [min, max] = widthBreakpoints[prefix] ?? [0, 0]; - if (windowWidth <= min || windowWidth > max) { + if (windowWidth < min || windowWidth >= max) { // breakpoint does not match this.isNull = true; } diff --git a/src/__tests__/screens.spec.ts b/src/__tests__/screens.spec.ts index 282ba05..16c4b43 100644 --- a/src/__tests__/screens.spec.ts +++ b/src/__tests__/screens.spec.ts @@ -54,7 +54,6 @@ describe(`screens()`, () => { ]; // https://tailwindcss.com/docs/breakpoints#custom-media-queries - test.each(cases)(`converts tw screens to ranges`, (input, expected) => { expect(screens(input)).toEqual(expected); }); diff --git a/src/__tests__/tw.spec.ts b/src/__tests__/tw.spec.ts index c9c8162..13cef8e 100644 --- a/src/__tests__/tw.spec.ts +++ b/src/__tests__/tw.spec.ts @@ -30,6 +30,37 @@ describe(`tw`, () => { expect(tw`md:text-lg text-xs`).toMatchObject({ fontSize: 18 }); }); + test(`media queries boundaries`, () => { + tw = create(); + // default breakpoints + const utilities = `text-xs sm:text-lg md:text-xl lg:text-2xl xl:text-3xl`; + expect(tw.style(utilities)).toMatchObject({ fontSize: 12 }); + tw.setWindowDimensions({ width: 500, height: 500 }); + expect(tw.style(utilities)).toMatchObject({ fontSize: 12 }); + tw.setWindowDimensions({ width: 639, height: 500 }); + expect(tw.style(utilities)).toMatchObject({ fontSize: 12 }); + tw.setWindowDimensions({ width: 640, height: 500 }); + expect(tw.style(utilities)).toMatchObject({ fontSize: 18 }); + tw.setWindowDimensions({ width: 767, height: 500 }); + expect(tw.style(utilities)).toMatchObject({ fontSize: 18 }); + tw.setWindowDimensions({ width: 768, height: 500 }); + expect(tw.style(utilities)).toMatchObject({ fontSize: 20 }); + tw.setWindowDimensions({ width: 1023, height: 500 }); + expect(tw.style(utilities)).toMatchObject({ fontSize: 20 }); + tw.setWindowDimensions({ width: 1024, height: 500 }); + expect(tw.style(utilities)).toMatchObject({ fontSize: 24 }); + tw.setWindowDimensions({ width: 1279, height: 500 }); + expect(tw.style(utilities)).toMatchObject({ fontSize: 24 }); + tw.setWindowDimensions({ width: 1280, height: 500 }); + expect(tw.style(utilities)).toMatchObject({ fontSize: 30 }); + // custom breakpoints + tw = create({ theme: { screens: { custom: `555px` } } }); + tw.setWindowDimensions({ width: 554, height: 500 }); + expect(tw`text-xs custom:text-lg`).toMatchObject({ fontSize: 12 }); + tw.setWindowDimensions({ width: 555, height: 500 }); + expect(tw`text-xs custom:text-lg`).toMatchObject({ fontSize: 18 }); + }); + test(`multiple media queries`, () => { const config: TwConfig = { theme: { screens: { sm: `640px`, md: `768px` } } }; tw = create(config); diff --git a/src/create.ts b/src/create.ts index 6e1aa56..5129ecb 100644 --- a/src/create.ts +++ b/src/create.ts @@ -65,11 +65,6 @@ export function create(customConfig: TwConfig, platform: Platform): TailwindFn { tailwindFn.memoBuster = ``; configureCache(); - // get back to cjs - // probably need to implement the check for if isset - // in order to not be a breaking change - // also, in this branch, add _unstableUpdateContext func - function configureCache(): void { const cacheGroup = deriveCacheGroup(); tailwindFn.memoBuster = `twrnc-memobuster-key--${cacheGroup}`;