diff --git a/.npmignore b/.npmignore index a70831fb..4793f194 100644 --- a/.npmignore +++ b/.npmignore @@ -10,6 +10,12 @@ .gitignore .npmignore .travis.yml +.browserlistrc +.prettierignore +.prettierrc +.vscode +babel.config.js +CODEOWNERS # folders coverage @@ -20,9 +26,12 @@ flow-typed # markdown files CONTRIBUTING.md +CODE_OF_CONDUCT.md # misc. CNAME rollup.config.js travis_after_all.py yarn.lock +.yarn +typescript-test.ts diff --git a/LICENSE.md b/LICENSE.md index 07e8823a..9c8a21db 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2016 - 2020 Brian Hough and Maximilian Stoiber +Copyright (c) 2016 - 2021 Brian Hough and Maximilian Stoiber Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/color/readableColor.js b/src/color/readableColor.js index 7eeb09e8..4776e049 100644 --- a/src/color/readableColor.js +++ b/src/color/readableColor.js @@ -2,16 +2,16 @@ import getContrast from './getContrast' import getLuminance from './getLuminance' -const defaultLightReturnColor = '#000' -const defaultDarkReturnColor = '#fff' +const defaultReturnIfLightColor = '#000' +const defaultReturnIfDarkColor = '#fff' /** - * Returns black or white (or optional light and dark return colors) for best + * Returns black or white (or optional passed colors) for best * contrast depending on the luminosity of the given color. - * When passing custom return colors, set `strict` to `true` to ensure that the + * When passing custom return colors, strict mode ensures that the * return color always meets or exceeds WCAG level AA or greater. If this test * fails, the default return color (black or white) is returned in place of the - * custom return color. + * custom return color. You can optionally turn off strict mode. * * Follows [W3C specs for readability](https://www.w3.org/TR/WCAG20-TECHS/G18.html). * @@ -42,17 +42,15 @@ const defaultDarkReturnColor = '#fff' */ export default function readableColor( color: string, - lightReturnColor?: string = defaultLightReturnColor, - darkReturnColor?: string = defaultDarkReturnColor, - strict?: boolean = false, + returnIfLightColor?: string = defaultReturnIfLightColor, + returnIfDarkColor?: string = defaultReturnIfDarkColor, + strict?: boolean = true, ): string { - const isLightColor = getLuminance(color) > 0.179 - const preferredReturnColor = isLightColor ? lightReturnColor : darkReturnColor + const isColorLight = getLuminance(color) > 0.179 + const preferredReturnColor = isColorLight ? returnIfLightColor : returnIfDarkColor - // TODO: Make `strict` the default behaviour in the next major release. - // Without `strict`, this may return a color that does not meet WCAG AA. if (!strict || getContrast(color, preferredReturnColor) >= 4.5) { return preferredReturnColor } - return isLightColor ? defaultLightReturnColor : defaultDarkReturnColor + return isColorLight ? defaultReturnIfLightColor : defaultReturnIfDarkColor } diff --git a/src/color/test/transparentize.test.js b/src/color/test/transparentize.test.js index a328a2e9..619e1daa 100644 --- a/src/color/test/transparentize.test.js +++ b/src/color/test/transparentize.test.js @@ -54,6 +54,10 @@ describe('transparentize', () => { expect(transparentize(-0.5, 'rgba(255, 0, 0, .8)')).toMatchSnapshot() }) + it('should properly round a float to 2 decimals.', () => { + expect(transparentize(0.55, '#01B0BB')).toEqual('rgba(1,176,187,0.45)') + }) + it('should reduce the opacity when passed a string for amount', () => { expect(transparentize('0.1', '#fff')).toMatchSnapshot() }) diff --git a/src/color/transparentize.js b/src/color/transparentize.js index 076092b4..dc0a28cb 100644 --- a/src/color/transparentize.js +++ b/src/color/transparentize.js @@ -37,7 +37,7 @@ function transparentize(amount: number | string, color: string): string { const alpha: number = typeof parsedColor.alpha === 'number' ? parsedColor.alpha : 1 const colorWithAlpha = { ...parsedColor, - alpha: guard(0, 1, (alpha * 100 - parseFloat(amount) * 100) / 100), + alpha: guard(0, 1, +(alpha * 100 - parseFloat(amount) * 100).toFixed(2) / 100), } return rgba(colorWithAlpha) } diff --git a/src/internalHelpers/errors.md b/src/internalHelpers/errors.md index e8f6e53a..f2732791 100644 --- a/src/internalHelpers/errors.md +++ b/src/internalHelpers/errors.md @@ -298,3 +298,7 @@ Please provide a valid CSS variable. ## 74 CSS variable not found. + +## 75 + +fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen. diff --git a/src/mixins/between.js b/src/mixins/between.js index 46b3552d..e140c039 100644 --- a/src/mixins/between.js +++ b/src/mixins/between.js @@ -54,6 +54,10 @@ export default function between( throw new PolishedError(48) } + if (fromSizeUnit !== minScreenUnit || toSizeUnit !== maxScreenUnit) { + throw new PolishedError(75) + } + const slope = (unitlessFromSize - unitlessToSize) / (unitlessMinScreen - unitlessMaxScreen) const base = unitlessToSize - slope * unitlessMaxScreen return `calc(${base.toFixed(2)}${fromSizeUnit || ''} + ${(100 * slope).toFixed(2)}vw)` diff --git a/src/mixins/test/__snapshots__/between.test.js.snap b/src/mixins/test/__snapshots__/between.test.js.snap deleted file mode 100644 index 6752db14..00000000 --- a/src/mixins/test/__snapshots__/between.test.js.snap +++ /dev/null @@ -1,9 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`between should return a valid calc formula when not passed min/max screen sizes 1`] = `"calc(-9.09px + 9.09vw)"`; - -exports[`between should return a valid calc formula when passed min/max screen sizes 1`] = `"calc(-33.33px + 13.33vw)"`; - -exports[`between should return a valid calc formula when passed unitless to/from values as numbers 1`] = `"calc(-9.09 + 9.09vw)"`; - -exports[`between should return a valid calc formula when passed unitless to/from values as strings 1`] = `"calc(-9.09 + 9.09vw)"`; diff --git a/src/mixins/test/__snapshots__/fluidRange.test.js.snap b/src/mixins/test/__snapshots__/fluidRange.test.js.snap deleted file mode 100644 index f5fdfe37..00000000 --- a/src/mixins/test/__snapshots__/fluidRange.test.js.snap +++ /dev/null @@ -1,40 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`fluidRange should return a valid object when passed a single cssValues object and min/max screen sizes 1`] = ` -Object { - "@media (min-width: 1000px)": Object { - "padding": "100px", - }, - "@media (min-width: 400px)": Object { - "padding": "calc(-33.33px + 13.33vw)", - }, - "padding": "20px", -} -`; - -exports[`fluidRange should return a valid object when passed multiple cssValues in an array and min/max screen sizes 1`] = ` -Object { - "@media (min-width: 1000px)": Object { - "margin": "25px", - "padding": "100px", - }, - "@media (min-width: 400px)": Object { - "margin": "calc(-8.33px + 3.33vw)", - "padding": "calc(-33.33px + 13.33vw)", - }, - "margin": "5px", - "padding": "20px", -} -`; - -exports[`fluidRange should use defaults when min/maxScreen are not passed 1`] = ` -Object { - "@media (min-width: 1200px)": Object { - "padding": "100px", - }, - "@media (min-width: 320px)": Object { - "padding": "calc(-9.09px + 9.09vw)", - }, - "padding": "20px", -} -`; diff --git a/src/mixins/test/__snapshots__/triangle.test.js.snap b/src/mixins/test/__snapshots__/triangle.test.js.snap index 97ffed6f..528ebd69 100644 --- a/src/mixins/test/__snapshots__/triangle.test.js.snap +++ b/src/mixins/test/__snapshots__/triangle.test.js.snap @@ -2,7 +2,8 @@ exports[`triangle should default to a transparent background when not passed a backgroundColor 1`] = ` Object { - "borderColor": "transparent transparent transparent red", + "borderColor": "transparent", + "borderLeftColor": "red", "borderStyle": "solid", "borderWidth": "5px 0 5px 20px", "height": "0", @@ -12,7 +13,8 @@ Object { exports[`triangle should generate a proper triangle when passed all parameters 1`] = ` Object { - "borderColor": "black black black red", + "borderColor": "black", + "borderLeftColor": "red", "borderStyle": "solid", "borderWidth": "5 0 5 20", "height": "0", @@ -22,7 +24,8 @@ Object { exports[`triangle should generate a proper triangle when passed all parameters with units on width/height 1`] = ` Object { - "borderColor": "black black black red", + "borderColor": "black", + "borderLeftColor": "red", "borderStyle": "solid", "borderWidth": "5em 0 5em 20em", "height": "0", @@ -32,7 +35,8 @@ Object { exports[`triangle should generate a proper triangle when passed all parameters with units on width/height with float values 1`] = ` Object { - "borderColor": "black black black red", + "borderColor": "black", + "borderLeftColor": "red", "borderStyle": "solid", "borderWidth": "5.25em 0 5.25em 20.5em", "height": "0", @@ -42,7 +46,8 @@ Object { exports[`triangle should generate a proper triangle when passed string values for height and width 1`] = ` Object { - "borderColor": "black black black red", + "borderColor": "black", + "borderLeftColor": "red", "borderStyle": "solid", "borderWidth": "5px 0 5px 20px", "height": "0", @@ -52,8 +57,9 @@ Object { exports[`triangle should properly render bottom pointing arrow with red foregroundColor, width of 20px and height 20px 1`] = ` Object { - "borderColor": "red transparent transparent transparent", + "borderColor": "transparent", "borderStyle": "solid", + "borderTopColor": "red", "borderWidth": "20px 5px 0 5px", "height": "0", "width": "0", @@ -62,7 +68,8 @@ Object { exports[`triangle should properly render bottomLeft pointing arrow with blue foregroundColor, width of 20px and height 20px 1`] = ` Object { - "borderColor": "transparent transparent transparent blue", + "borderColor": "transparent", + "borderLeftColor": "blue", "borderStyle": "solid", "borderWidth": "20px 0 0 20px", "height": "0", @@ -72,7 +79,8 @@ Object { exports[`triangle should properly render bottomRight pointing arrow with blue foregroundColor, width of 20px and height 20px 1`] = ` Object { - "borderColor": "transparent transparent blue transparent", + "borderBottomColor": "blue", + "borderColor": "transparent", "borderStyle": "solid", "borderWidth": "0 0 20px 20px", "height": "0", @@ -82,7 +90,8 @@ Object { exports[`triangle should properly render left pointing arrow with blue foregroundColor, width of 10px and height 20px 1`] = ` Object { - "borderColor": "transparent blue transparent transparent", + "borderColor": "transparent", + "borderRightColor": "blue", "borderStyle": "solid", "borderWidth": "10px 10px 10px 0", "height": "0", @@ -92,7 +101,8 @@ Object { exports[`triangle should properly render right pointing arrow with width of 20px and height 10px 1`] = ` Object { - "borderColor": "transparent transparent transparent red", + "borderColor": "transparent", + "borderLeftColor": "red", "borderStyle": "solid", "borderWidth": "5px 0 5px 20px", "height": "0", @@ -102,7 +112,8 @@ Object { exports[`triangle should properly render top pointing arrow with green foregroundColor, width of 20px and height 20px 1`] = ` Object { - "borderColor": "transparent transparent green transparent", + "borderBottomColor": "green", + "borderColor": "transparent", "borderStyle": "solid", "borderWidth": "0 10px 20px 10px", "height": "0", @@ -112,8 +123,9 @@ Object { exports[`triangle should properly render topLeft pointing arrow with blue foregroundColor, width of 20px and height 20px 1`] = ` Object { - "borderColor": "blue transparent transparent transparent", + "borderColor": "transparent", "borderStyle": "solid", + "borderTopColor": "blue", "borderWidth": "20px 20px 0 0", "height": "0", "width": "0", @@ -122,7 +134,8 @@ Object { exports[`triangle should properly render topRight pointing arrow with blue foregroundColor, width of 20px and height 20px 1`] = ` Object { - "borderColor": "transparent blue transparent transparent", + "borderColor": "transparent", + "borderRightColor": "blue", "borderStyle": "solid", "borderWidth": "0 20px 20px 0", "height": "0", diff --git a/src/mixins/test/between.test.js b/src/mixins/test/between.test.js index 7d9e3a5c..53880e07 100644 --- a/src/mixins/test/between.test.js +++ b/src/mixins/test/between.test.js @@ -3,20 +3,13 @@ import between from '../between' describe('between', () => { it('should return a valid calc formula when passed min/max screen sizes', () => { - expect(between('20px', '100px', '400px', '1000px')).toMatchSnapshot() + expect(between('20px', '100px', '400px', '1000px')).toEqual('calc(-33.33px + 13.33vw)') }) it('should return a valid calc formula when not passed min/max screen sizes', () => { - expect(between('20px', '100px')).toMatchSnapshot() + expect(between('20px', '100px')).toEqual('calc(-9.09px + 9.09vw)') }) - it('should return a valid calc formula when passed unitless to/from values as numbers', () => { - expect(between(20, 100)).toMatchSnapshot() - }) - - it('should return a valid calc formula when passed unitless to/from values as strings', () => { - expect(between('20', '100')).toMatchSnapshot() - }) // Errors it('should throw an error when not passed min/max screen size as a string', () => { expect(() => { @@ -42,4 +35,22 @@ describe('between', () => { between('1em', '100px', '400px', '1000px') }).toThrow('fromSize and toSize must be provided as stringified numbers with the same units.') }) + + it('should throw an error when passed to/from size with different units than mix/max screen', () => { + expect(() => { + // $FlowFixMe + between('1em', '100em', '400px', '1000px') + }).toThrow( + 'fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.', + ) + }) + + it('should throw an error when passed to/from size with no units but mix/max with units', () => { + expect(() => { + // $FlowFixMe + between(20, 100) + }).toThrow( + 'fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.', + ) + }) }) diff --git a/src/mixins/test/fluidRange.test.js b/src/mixins/test/fluidRange.test.js index 07650c35..9c8809cd 100644 --- a/src/mixins/test/fluidRange.test.js +++ b/src/mixins/test/fluidRange.test.js @@ -13,7 +13,15 @@ describe('fluidRange', () => { '400px', '1000px', ), - ).toMatchSnapshot() + ).toEqual({ + '@media (min-width: 1000px)': { + padding: '100px', + }, + '@media (min-width: 400px)': { + padding: 'calc(-33.33px + 13.33vw)', + }, + padding: '20px', + }) }) it('should return a valid object when passed multiple cssValues in an array and min/max screen sizes', () => { @@ -34,7 +42,18 @@ describe('fluidRange', () => { '400px', '1000px', ), - ).toMatchSnapshot() + ).toEqual({ + '@media (min-width: 1000px)': { + margin: '25px', + padding: '100px', + }, + '@media (min-width: 400px)': { + margin: 'calc(-8.33px + 3.33vw)', + padding: 'calc(-33.33px + 13.33vw)', + }, + margin: '5px', + padding: '20px', + }) }) it('should use defaults when min/maxScreen are not passed', () => { @@ -44,7 +63,15 @@ describe('fluidRange', () => { fromSize: '20px', toSize: '100px', }), - ).toMatchSnapshot() + ).toEqual({ + '@media (min-width: 1200px)': { + padding: '100px', + }, + '@media (min-width: 320px)': { + padding: 'calc(-9.09px + 9.09vw)', + }, + padding: '20px', + }) }) // Errors diff --git a/src/mixins/triangle.js b/src/mixins/triangle.js index a5acc669..6ee1428b 100644 --- a/src/mixins/triangle.js +++ b/src/mixins/triangle.js @@ -37,24 +37,20 @@ const getBorderWidth = ( } } -const getBorderColor = ( - pointingDirection: SideKeyword, - foregroundColor: string, - backgroundColor: string, -): string => { +const getBorderColor = (pointingDirection: SideKeyword, foregroundColor: string): Object => { switch (pointingDirection) { case 'top': case 'bottomRight': - return `${backgroundColor} ${backgroundColor} ${foregroundColor} ${backgroundColor}` + return { borderBottomColor: foregroundColor } case 'right': case 'bottomLeft': - return `${backgroundColor} ${backgroundColor} ${backgroundColor} ${foregroundColor}` + return { borderLeftColor: foregroundColor } case 'bottom': case 'topLeft': - return `${foregroundColor} ${backgroundColor} ${backgroundColor} ${backgroundColor}` + return { borderTopColor: foregroundColor } case 'left': case 'topRight': - return `${backgroundColor} ${foregroundColor} ${backgroundColor} ${backgroundColor}` + return { borderRightColor: foregroundColor } default: throw new PolishedError(59) @@ -104,7 +100,8 @@ export default function triangle({ return { width: '0', height: '0', - borderColor: getBorderColor(pointingDirection, foregroundColor, backgroundColor), + borderColor: backgroundColor, + ...getBorderColor(pointingDirection, foregroundColor), borderStyle: 'solid', borderWidth: getBorderWidth(pointingDirection, heightAndUnit, widthAndUnit), }