Skip to content

Commit

Permalink
fix: internal changes
Browse files Browse the repository at this point in the history
  • Loading branch information
mg901 committed Mar 31, 2022
1 parent a7749e7 commit 240b527
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 71 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ const Component = styled.div`

### Object notation

When using object notation, make sure to explicitly pass `props` to breakpoint
Make sure to explicitly pass `props` to breakpoint
methods. Please see the example below using default configuration:

```js
Expand Down
110 changes: 54 additions & 56 deletions core/breakpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,62 +19,60 @@ const defaultOptions = {
exports.DEFAULT_BREAKPOINTS = DEFAULT_BREAKPOINTS;
exports.ERROR_PREFIX = ERROR_PREFIX;

exports.createBreakpoints = memoize(
({ breakpoints, errorPrefix } = defaultOptions) => {
const names = Object.keys(breakpoints);
const validation = createValidation({
names,
breakpoints,
errorPrefix,
});

const getValueByName = memoize((name) => {
validation.checkIsValidName(name);
validation.checkIsFirstName(name);

return breakpoints[name];
});

const getNextName = (name) => {
const nextIndex = names.indexOf(name) + 1;

return names[nextIndex];
};

const getNextValueByName = memoize((name) => {
validation.checkIsValidName(name);
validation.checkIsLastName(name);

return breakpoints[getNextName(name)];
});

// Maximum breakpoint width. Null for the largest (last) breakpoint.
// The maximum value is calculated as the minimum of the next one less 0.02px
// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.
// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max
// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.
// See https://bugs.webkit.org/show_bug.cgi?id=178261
const calcMaxWidth = memoize((value) => {
return `${parseFloat(value) - 0.02}px`;
});

return {
up: getValueByName,

down: (max) => calcMaxWidth(getValueByName(max)),

between: (min, max) => ({
min: getValueByName(min),
max: calcMaxWidth(getValueByName(max)),
}),

only: (name) => ({
min: getValueByName(name),
max: calcMaxWidth(getNextValueByName(name)),
}),
};
}
);
exports.createBreakpoints = ({ breakpoints, errorPrefix } = defaultOptions) => {
const names = Object.keys(breakpoints);
const validation = createValidation({
names,
breakpoints,
errorPrefix,
});

const getValueByName = memoize((name) => {
validation.checkIsValidName(name);
validation.checkIsFirstName(name);

return breakpoints[name];
});

const getNextName = (name) => {
const nextIndex = names.indexOf(name) + 1;

return names[nextIndex];
};

const getNextValueByName = memoize((name) => {
validation.checkIsValidName(name);
validation.checkIsLastName(name);

return breakpoints[getNextName(name)];
});

// Maximum breakpoint width. Null for the largest (last) breakpoint.
// The maximum value is calculated as the minimum of the next one less 0.02px
// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.
// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max
// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.
// See https://bugs.webkit.org/show_bug.cgi?id=178261
const calcMaxWidth = memoize((value) => {
return `${parseFloat(value) - 0.02}px`;
});

return {
up: getValueByName,

down: (max) => calcMaxWidth(getValueByName(max)),

between: (min, max) => ({
min: getValueByName(min),
max: calcMaxWidth(getValueByName(max)),
}),

only: (name) => ({
min: getValueByName(name),
max: calcMaxWidth(getNextValueByName(name)),
}),
};
};

function createValidation({ names, breakpoints, errorPrefix }) {
const invariant = createInvariantWithPrefix(errorPrefix);
Expand Down
3 changes: 2 additions & 1 deletion styled-breakpoints/styled-breakpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ exports.createStyledBreakpoints = (options = defaultOptions) => {

const withBreakpoints = (fn) => (props) => {
const mediaQueriesFromTheme = getMediaQueriesFromTheme(props);
const createMemoizedBreakpoints = memoize(createBreakpoints);

const breakpoints = createBreakpoints({
const breakpoints = createMemoizedBreakpoints({
breakpoints: mediaQueriesFromTheme,
errorPrefix: options.errorPrefix,
});
Expand Down
46 changes: 33 additions & 13 deletions styled-breakpoints/styled-breakpoints.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,32 @@ describe('styled-breakpoints', () => {
});
});

const { up, down, between, only } = createStyledBreakpoints();
describe('up', () => {
let bp;
beforeEach(() => {
bp = createStyledBreakpoints();
});
it('should render a media query if the screen width is greater than or equal to 576px', () => {
expect(up('sm')(PROPS_WITH_EMPTY_THEME)).toEqual(
expect(bp.up('sm')(PROPS_WITH_EMPTY_THEME)).toEqual(
'@media (min-width: 576px)'
);
});

it('should render a media query if the screen width is greater than or equal to 576px for portrait orientation', () => {
expect(up('sm', 'portrait')(PROPS_WITH_EMPTY_THEME)).toEqual(
expect(bp.up('sm', 'portrait')(PROPS_WITH_EMPTY_THEME)).toEqual(
'@media (min-width: 576px) and (orientation: portrait)'
);
});

it('should render a media query if the screen width is greater than or equal to 576px for landscape orientation', () => {
expect(up('sm', 'landscape')(PROPS_WITH_EMPTY_THEME)).toEqual(
expect(bp.up('sm', 'landscape')(PROPS_WITH_EMPTY_THEME)).toEqual(
'@media (min-width: 576px) and (orientation: landscape)'
);
});

it('should throw an exception if device orientation is not valid', () => {
try {
up('sm', 'wtf')(PROPS_WITH_EMPTY_THEME);
bp.up('sm', 'wtf')(PROPS_WITH_EMPTY_THEME);
} catch (error) {
expect(error.message).toEqual(
`${ERROR_PREFIX}\`wtf\` is invalid orientation. Use \`landscape\` or \`portrait\`.`
Expand All @@ -82,27 +85,31 @@ describe('styled-breakpoints', () => {
});

describe('down', () => {
let bp;
beforeEach(() => {
bp = createStyledBreakpoints();
});
it('should render a media query if the screen width is less or equal to 575.98px', () => {
expect(down('sm')(PROPS_WITH_EMPTY_THEME)).toEqual(
expect(bp.down('sm')(PROPS_WITH_EMPTY_THEME)).toEqual(
'@media (max-width: 575.98px)'
);
});

it('should render a media query if the screen width is less or equal to 767.98px for portrait orientation', () => {
expect(down('sm', 'portrait')(PROPS_WITH_EMPTY_THEME)).toEqual(
expect(bp.down('sm', 'portrait')(PROPS_WITH_EMPTY_THEME)).toEqual(
'@media (max-width: 575.98px) and (orientation: portrait)'
);
});

it('should render a media query if the screen width is less or equal to 767.98px for landscape orientation', () => {
expect(down('sm', 'landscape')(PROPS_WITH_EMPTY_THEME)).toEqual(
expect(bp.down('sm', 'landscape')(PROPS_WITH_EMPTY_THEME)).toEqual(
'@media (max-width: 575.98px) and (orientation: landscape)'
);
});

it('should throw an exception if device orientation is not valid', () => {
try {
down('sm', 'wtf')(PROPS_WITH_EMPTY_THEME);
bp.down('sm', 'wtf')(PROPS_WITH_EMPTY_THEME);
} catch (error) {
expect(error.message).toEqual(
`${ERROR_PREFIX}\`wtf\` is invalid orientation. Use \`landscape\` or \`portrait\`.`
Expand All @@ -112,28 +119,41 @@ describe('styled-breakpoints', () => {
});

describe('between', () => {
let bp;
beforeEach(() => {
bp = createStyledBreakpoints();
});
it('should render a media query if the screen width greater than equal to 576px and less than or equal to 991.98px', () => {
expect(between('sm', 'md')(PROPS_WITH_EMPTY_THEME)).toEqual(
expect(bp.between('sm', 'md')(PROPS_WITH_EMPTY_THEME)).toEqual(
'@media (min-width: 576px) and (max-width: 767.98px)'
);
});

it('should render a media query if the screen width greater than equal to 576px and less than or equal to 991.98px and portrait orientation', () => {
expect(between('sm', 'md', 'portrait')(PROPS_WITH_EMPTY_THEME)).toEqual(
expect(
bp.between('sm', 'md', 'portrait')(PROPS_WITH_EMPTY_THEME)
).toEqual(
'@media (min-width: 576px) and (max-width: 767.98px) and (orientation: portrait)'
);
});

it('should render a media query if the screen width greater than equal to 576px and less than or equal to 991.98px and landscape orientation', () => {
expect(between('sm', 'md', 'landscape')(PROPS_WITH_EMPTY_THEME)).toEqual(
expect(
bp.between('sm', 'md', 'landscape')(PROPS_WITH_EMPTY_THEME)
).toEqual(
'@media (min-width: 576px) and (max-width: 767.98px) and (orientation: landscape)'
);
});
});

describe('only', () => {
let bp;
beforeEach(() => {
bp = createStyledBreakpoints();
});

it('should render a media query if the screen width greater than equal to 576px and less than or equal to 767.98px', () => {
expect(only('sm')(PROPS_WITH_EMPTY_THEME)).toEqual(
expect(bp.only('sm')(PROPS_WITH_EMPTY_THEME)).toEqual(
'@media (min-width: 576px) and (max-width: 767.98px)'
);
});
Expand Down

0 comments on commit 240b527

Please sign in to comment.