diff --git a/src/UtilityParser.ts b/src/UtilityParser.ts index 6e4a805..9d7cf21 100644 --- a/src/UtilityParser.ts +++ b/src/UtilityParser.ts @@ -484,7 +484,25 @@ export default class UtilityParser { // loop through the prefixes ONE time, extracting useful info for (const prefix of prefixes) { - if (widthBreakpoints[prefix]) { + if (prefix.startsWith(`max-`) && prefix.slice(4) in widthBreakpoints) { + const breakpoint = widthBreakpoints[prefix.slice(4)]; + if (!breakpoint) { + this.isNull = true; + continue; + } + + const windowWidth = device.windowDimensions?.width; + if (!windowWidth) { + this.isNull = true; + continue; + } + + if (windowWidth <= breakpoint[0]) { + this.incrementOrder(); + } else { + this.isNull = true; + } + } else if (widthBreakpoints[prefix]) { const breakpointOrder = widthBreakpoints[prefix]?.[2]; if (breakpointOrder !== undefined) { this.order = (this.order ?? 0) + breakpointOrder; diff --git a/src/__tests__/prefix-match.spec.ts b/src/__tests__/prefix-match.spec.ts index 20e71ef..32aedba 100644 --- a/src/__tests__/prefix-match.spec.ts +++ b/src/__tests__/prefix-match.spec.ts @@ -44,6 +44,9 @@ describe(`tw.prefixMatch()`, () => { expect(tw.prefixMatch(`md`)).toBe(true); expect(tw.prefixMatch(`lg`)).toBe(true); expect(tw.prefixMatch(`xl`)).toBe(false); + expect(tw.prefixMatch(`max-md`)).toBe(false); + expect(tw.prefixMatch(`max-lg`)).toBe(false); + expect(tw.prefixMatch(`max-xl`)).toBe(true); expect(tw.prefixMatch(`landscape`)).toBe(true); expect(tw.prefixMatch(`portrait`)).toBe(false); }); diff --git a/src/__tests__/tw.spec.ts b/src/__tests__/tw.spec.ts index 31a1d5c..fe57764 100644 --- a/src/__tests__/tw.spec.ts +++ b/src/__tests__/tw.spec.ts @@ -56,12 +56,40 @@ describe(`tw`, () => { expect(tw.style(utilities)).toMatchObject({ fontSize: 24 }); tw.setWindowDimensions({ width: 1280, height: 500 }); expect(tw.style(utilities)).toMatchObject({ fontSize: 30 }); + // default max breakpoints variants + const maxUtilities = `text-3xl max-lg:text-2xl max-md:text-lg max-sm:text-base`; + expect(tw.style(maxUtilities)).toMatchObject({ fontSize: 30 }); + tw.setWindowDimensions({ width: 500, height: 500 }); + expect(tw.style(maxUtilities)).toMatchObject({ fontSize: 16 }); + tw.setWindowDimensions({ width: 639, height: 500 }); + expect(tw.style(maxUtilities)).toMatchObject({ fontSize: 16 }); + tw.setWindowDimensions({ width: 640, height: 500 }); + expect(tw.style(maxUtilities)).toMatchObject({ fontSize: 16 }); + tw.setWindowDimensions({ width: 767, height: 500 }); + expect(tw.style(maxUtilities)).toMatchObject({ fontSize: 18 }); + tw.setWindowDimensions({ width: 768, height: 500 }); + expect(tw.style(maxUtilities)).toMatchObject({ fontSize: 18 }); + tw.setWindowDimensions({ width: 1023, height: 500 }); + expect(tw.style(maxUtilities)).toMatchObject({ fontSize: 24 }); + tw.setWindowDimensions({ width: 1024, height: 500 }); + expect(tw.style(maxUtilities)).toMatchObject({ fontSize: 24 }); + tw.setWindowDimensions({ width: 1279, height: 500 }); + expect(tw.style(maxUtilities)).toMatchObject({ fontSize: 30 }); + tw.setWindowDimensions({ width: 1280, height: 500 }); + expect(tw.style(maxUtilities)).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 }); + // custom max breakpoints + tw.setWindowDimensions({ width: 554, height: 500 }); + expect(tw`text-xl max-custom:text-sm`).toMatchObject({ fontSize: 14 }); + tw.setWindowDimensions({ width: 555, height: 500 }); + expect(tw`text-xl max-custom:text-sm`).toMatchObject({ fontSize: 14 }); + tw.setWindowDimensions({ width: 556, height: 500 }); + expect(tw`text-xl max-custom:text-sm`).toMatchObject({ fontSize: 20 }); }); test(`multiple media queries`, () => {