Skip to content

Commit

Permalink
fix media query range minimum off-by-one
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredh159 committed Feb 13, 2024
1 parent 1dc0197 commit bda0569
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 7 deletions.
30 changes: 30 additions & 0 deletions migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `[email protected]` 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
Expand Down
2 changes: 1 addition & 1 deletion src/ClassParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
1 change: 0 additions & 1 deletion src/__tests__/screens.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand Down
31 changes: 31 additions & 0 deletions src/__tests__/tw.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 0 additions & 5 deletions src/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}`;
Expand Down

0 comments on commit bda0569

Please sign in to comment.