-
-
Notifications
You must be signed in to change notification settings - Fork 209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rgba #62
Merged
Rgba #62
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
741d8df
chore(rgba): add rgba
nikgraf f64337a
chore(rgba): convert rgba with full opacity to hex
nikgraf 0c5f890
chore(rgba): add docs
nikgraf 162118a
chore(rgba): export rgba and setup docs
nikgraf 8e882b3
Merge branch 'master' into rgba
nikgraf File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// @flow | ||
|
||
import rgb from './rgb' | ||
|
||
type RgbaColor = { | ||
red: number, | ||
green: number, | ||
blue: number, | ||
alpha: number, | ||
} | ||
|
||
/** | ||
* Returns a string value for the color. The returned result is the smallest possible rgba or hex notation. | ||
* | ||
* @example | ||
* // Styles as object usage | ||
* const styles = { | ||
* background: rgba(255, 205, 100, 180), | ||
* background: rgba({ red: 255, green: 205, blue: 100, alpha: 180 }), | ||
* background: rgba(255, 205, 100, 255), | ||
* } | ||
* | ||
* // styled-components usage | ||
* const div = styled.div` | ||
* background: ${rgba(255, 205, 100, 180)}; | ||
* background: ${rgba({ red: 255, green: 205, blue: 100, alpha: 180 })}; | ||
* background: ${rgba(255, 205, 100, 255)}; | ||
* ` | ||
* | ||
* // CSS in JS Output | ||
* | ||
* element { | ||
* background: "rgba(255,205,100,180)"; | ||
* background: "rgba(255,205,100,180)"; | ||
* background: "#ffcd64"; | ||
* } | ||
*/ | ||
function rgba(value: RgbaColor | number, green?: number, blue?: number, alpha?: number): string { | ||
if (typeof value === 'number' && | ||
typeof green === 'number' && | ||
typeof blue === 'number' && | ||
typeof alpha === 'number') { | ||
return alpha === 255 ? rgb(value, green, blue) : `rgba(${value},${green},${blue},${alpha})` | ||
} else if (typeof value === 'object' && green === undefined && blue === undefined && alpha === undefined) { | ||
return value.alpha === 255 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above, should also be the case with |
||
? rgb(value.red, value.green, value.blue) | ||
: `rgba(${value.red},${value.green},${value.blue},${value.alpha})` | ||
} | ||
|
||
throw new Error('Passed invalid arguments to rgba, please pass multiple numbers e.g. rgb(255, 205, 100, 180) or an object e.g. rgb({ red: 255, green: 205, blue: 100, alpha: 180 }).') | ||
} | ||
|
||
export default rgba |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
exports[`rgb should convert a rgba object to a rgba string 1`] = ` | ||
Object { | ||
"background": "rgba(255,205,100,180)", | ||
} | ||
`; | ||
|
||
exports[`rgb should convert a rgba object with full opacity to a hex color 1`] = ` | ||
Object { | ||
"background": "#ffcd64", | ||
} | ||
`; | ||
|
||
exports[`rgb should convert a rgba object with full opacity to a reduced hex color 1`] = ` | ||
Object { | ||
"background": "#fff", | ||
} | ||
`; | ||
|
||
exports[`rgb should convert multiple numbers to a rgba string 1`] = ` | ||
Object { | ||
"background": "rgba(255,205,100,180)", | ||
} | ||
`; | ||
|
||
exports[`rgb should convert multiple numbers with full opacity to a hex color 1`] = ` | ||
Object { | ||
"background": "#ffcd64", | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// @flow | ||
import rgba from '../rgba' | ||
|
||
describe('rgb', () => { | ||
it('should convert multiple numbers to a rgba string', () => { | ||
expect({ background: rgba(255, 205, 100, 180) }).toMatchSnapshot() | ||
}) | ||
|
||
it('should convert multiple numbers with full opacity to a hex color', () => { | ||
expect({ background: rgba(255, 205, 100, 255) }).toMatchSnapshot() | ||
}) | ||
|
||
it('should convert a rgba object to a rgba string', () => { | ||
expect({ background: rgba({ red: 255, green: 205, blue: 100, alpha: 180 }) }).toMatchSnapshot() | ||
}) | ||
|
||
it('should convert a rgba object with full opacity to a hex color', () => { | ||
expect({ background: rgba({ red: 255, green: 205, blue: 100, alpha: 255 }) }).toMatchSnapshot() | ||
}) | ||
|
||
it('should convert a rgba object with full opacity to a reduced hex color', () => { | ||
expect({ background: rgba({ red: 255, green: 255, blue: 255, alpha: 255 }) }).toMatchSnapshot() | ||
}) | ||
|
||
it('should throw an error if an object and multiple arguments are passed', () => { | ||
expect(() => ({ background: rgba({ red: 255, green: 1, blue: 1, alpha: 180 }, 250, 100) })) | ||
.toThrow('Passed invalid arguments to rgba, please pass multiple numbers e.g. rgb(255, 205, 100, 180) or an object e.g. rgb({ red: 255, green: 205, blue: 100, alpha: 180 }).') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't require
alpha
imo, this should work perfectly fine (I think right now it'd throw an error):There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mxstbr this was on purpose as it doesn't work in Chrome nor Firefox
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't we make it work?
if alpha == null rgb(value, green, blue)
Much nicer experience, especially if used programmatically?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From experience
null
orundefined
often happen due a mistake. If we make alpha optional than the static analysis via Flowtype or TypeScript can't detect these errors and it would simply be opacity 1. Which also led me to another issue: what's the correct default? 1 or 0? It probably depends on the application.On the other hand I'm a big fan of the robustness principle: "Be conservative in what you do, be liberal in what you accept from others" https://en.wikipedia.org/wiki/Robustness_principle
2 related questions:
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a perfect place that we can eventual leverage #4. Throw a warning and fall back to
rgb
ifalpha
isn't provided.For alpha I think the proper fallback is
1
. A fully transparent color inrgba
tends to only be used in transition animations when going to or from a fully transparent color to a more opaque color.As far as defaults for the colors, this is a tricky one.
rgba(244)
could be shorthand for one ofrgba(244, 244, 244)
,rgba(244, 0, 0)
, orrgba(244, 255, 255)
. The last option makes little sense to me as omitting a color probably does not mean you want it at 100%. The first option, while jiving with other shorthands somewhat (likepadding(5px)
), may not be how most think about color. I think if we are going to have a default (which I believe we should),0
makes the most sense.I've been thinking a lot about this last question as I work on #4. My thoughts, and I would love everyone's opinion here, is that we should limit our internal error handling to those specific to the methods we define, offloading the rest to the browser.
For example
timingFunctions
has a set of timingFunctions, if you provide the name of one that doesn't exist we should throw an error as it is critical to how the mixin works.However, if I pass a bad backgroundSize to
retinaImage
(like say a typo in the keyword), we should let that bubble up via the browser. Otherwise we will paint ourselves into a corner where we have to maintain error checking for general CSS. Did you provide this mixin bad CSS?, did you use an unsupported color keyword?. Libraries like Bourbon (or SASS in general) let you pass bad CSS into mixins, we should as well.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sound reasonable to me to let errors bubble up via the browser. It's a helper library and not validating all of your CSS 👍
I tried to think about when I used rgba or how I would use rgba without providing the alpha. Especially in transition animations as @bhough mentioned it never would be
null
orundefined
and if it would, it would be a bug in my calculations.That's what I'm mostly worried about. If we default back to 1, people might miss bugs. Can you think of an transition animation calculation where alpha would be
null
orundefined
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @nikgraf is right here, that would only ever happen if it was a bug so it seems reasonable to not let that happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I was more making the case for if we wanted to provide a default for when it wasn't provided that 1 made more sense than 0. In that case it still is a question of defaulting to
rgb
and throwing a warning, or throwing an error.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's always throw an error –
rgba(255, 255, 255)
in CSS doesn't work either!