Last active
August 25, 2018 09:25
-
-
Save at0g/013dc05805f0fd21db5f15dd622e655a to your computer and use it in GitHub Desktop.
Typing Fela
This file contains hidden or 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
| // @flow | |
| // file: src/FelaComponent.js | |
| import * as React from 'react' | |
| import { createComponent } from 'react-fela' | |
| // Our basic component props, without any fela guff. | |
| type PropsType = { | |
| children: React.Node, | |
| color?: string | |
| } | |
| // Our style rules function, typed as such. | |
| // passing PropsType ensures type checking against PropsType | |
| const styleRules:StyleFn<PropsType> = ({ color = 'red' }) => ({ | |
| color: color, | |
| display: 'block', | |
| }); | |
| // The component that will be styled with fela. | |
| // In the case of createComponent / createComponentWithProxy, a `className` prop is added by fela | |
| // Note that `as` will probably not be set and setting a default during destructuring causes a flow error, | |
| // hence the need to create the Component const inside the function body. | |
| const MyComponent = ({ as, children, extend, ...props }: FelaInjectedProps<PropsType>) => { | |
| const Component = as || 'div' | |
| return ( | |
| <Component {...props}> | |
| {children} | |
| </Component> | |
| ) | |
| }; | |
| // The "finished" component, with styles attached. | |
| const StyledComponent: FelaComponent<PropsType> = createComponent(styleRules, MyComponent) | |
| export default StyledComponent |
This file contains hidden or 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
| // @flow | |
| import * as React from 'react' | |
| import { connect } from 'react-fela' | |
| import ChildComponent from './FelaComponent' | |
| type PropTypes = { | |
| title: React.Node, | |
| subTitle?: React.Node, | |
| children: React.Node, | |
| } | |
| const styleRules:StyleFn<PropTypes> = ({ subTitle }) => ({ | |
| title: { | |
| borderLeft: '1em solid papayawhip', | |
| color: 'papayawhip', | |
| textIndent: '20px', | |
| ...(() => { | |
| if (subTitle) { | |
| return { | |
| marginBottom: 0, | |
| } | |
| } | |
| return {} | |
| })() | |
| }, | |
| subTitle: { | |
| backgroundColor: 'papayawhip', | |
| color: 'rebeccapurple', | |
| marginTop: 0 | |
| } | |
| }) | |
| const MyComponent = ({ as, children, styles, subTitle, title }: FelaInjectedConnectProps<PropTypes>) => { | |
| const Component = as || 'section' | |
| return ( | |
| <Component> | |
| <header> | |
| <ChildComponent as="h1">{title}</ChildComponent> | |
| {!!subTitle && ( | |
| <React.Fragment> | |
| <hr key="hr" /> | |
| <ChildComponent as="h2" key="subTitle">{subTitle}</ChildComponent> | |
| </React.Fragment> | |
| )} | |
| </header> | |
| {children} | |
| </Component> | |
| ) | |
| } | |
| const StyledComponent:FelaConnectComponent<PropTypes> = connect(styleRules)(MyComponent) | |
| export default StyledComponent |
This file contains hidden or 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
| // file: flow-typed/react-fela.js | |
| // Ensure flow@~0.69.0 is installed due to an issue with later versions: | |
| // @see: https://github.com/facebook/flow/issues/6284 | |
| import * as React from 'react' | |
| /** | |
| * The function that is called to generate the styles for this component. | |
| * If a theme is being used, it is merged with the components props as a `theme` property. | |
| * The merged props are provided as the first argument, and the fela renderer as the second. | |
| */ | |
| declare type StyleFn<PropsType> = ( | |
| props: FelaExpectedProps<PropsType> & { theme: {} }, | |
| renderer: {} | |
| ) => FelaRuleType | |
| /** | |
| * The props that are injected into a component that has been decorated by fela. | |
| */ | |
| declare type FelaInjectedProps<PropsType: {}> = | |
| PropsType & { | |
| as?: string | React.ComponentType<*>, | |
| className: string, | |
| extend: StyleFn<PropsType> | |
| } | |
| /** | |
| * When using { connect }, the injected props are very similar to { createComponent* }, with the following differences: | |
| * - instead of a single className, each key from the styleRules function will become a key in the styles prop, just | |
| * like a css module. | |
| * - a new rules prop is injected. Each key from the styleRules function will be a key in rules, the value being a | |
| * function used to generate css rules. Useful when extending an internal component as the applicable rules can be | |
| * further extended from the outside. | |
| */ | |
| declare type FelaInjectedConnectProps<PropsType: {}> = | |
| $Diff<FelaInjectedProps<PropsType>, { className?: string }> & { | |
| +rules: { | |
| [key: string]: StyleFn<PropsType> | |
| }, | |
| +styles: { | |
| [key: string]: string | |
| } | |
| } | |
| /** | |
| * The return type of a component created with createComponent or createComponentWithProxy | |
| */ | |
| declare type FelaComponent<PropsType: {}> = | |
| React.ComponentType<FelaExpectedProps<PropsType>> | |
| declare type FelaConnectComponent<PropsType: {}> = React.ComponentType<FelaExpectedProps<PropsType>> | |
| /** | |
| * Basic style rule. | |
| * example: { color: 'red', margin: 0 } | |
| * example: { | |
| * color: 'red', | |
| * ':hover': { | |
| * color: 'blue', | |
| * ':after': { display: 'none' } | |
| * } | |
| * } | |
| */ | |
| type FelaRuleType = { | |
| [key: string]: string | |
| | number | |
| | FelaRuleType | |
| } | |
| /** | |
| * The outward props that expected to the component. | |
| * Fela makes as, className and extend all optional props | |
| * when creating the node | |
| */ | |
| declare type FelaExpectedProps<PropsType: {}> = | |
| PropsType & { | |
| as?: string | React.ComponentType<PropsType>, | |
| className?: string, | |
| extend?: StyleFn<PropsType> | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment