Goals
- Allow flexibility for designs
- Keep core Components maintainable and useful
Aims
We want to be able to have the following options:
- Positioning
- Place components anywhere (static, absolute, fixed)
- Have components positioned via grid, specifying grid location
- (possibly) Size
- Have components be specific size
- Have components be percentage size
- Have components sized via flex, specifying grow / shrink / basis
What we don't want to be able to do:
- Change the style of the core component itself from the client, outside of semantic props. We don't want to override any styles that the component itself defines, as that will prevent any future changes to the component, as well as cause regressions.
Ideally, positioning of the components will be defined via the style section of a layout and not in the functional component / layout definition.
In other words, all styles in one place, all component rendering in one place.
Option 1 - Props
Each component accepts props like:
position
margin
width
height
flex
This option seems difficult to ensure every positional css rule is catered for, and non-positional ones are not.
// style.js
const MainActions = styled.div`
margin-bottom: 20px;
display: flex;
align-items: stretch;
`
const Controls = styled.div`
display: flex;
flex-direction: column;
`
// layout.js
import { Button } from 'brave-ui'
import * as Styled from './styles'
const MyLayout = () => (
<MainActions>
<Controls>
<Button blah='blah' position={{
marginRight: '10px'
}} />
<Button blah='blah' />
</Controls>
<Styled.MainActionEndButton>
<Button blah='blah' position={{
alignSelf: 'center'
}} />
</MainActionEndButton>
</MainActions>
Option 2 - Nothing (use wrapper)
Don't allow any customization. Instead, force everything to be wrapped with a client element that is explicitly sized and positioned.
This option means that all components that support being different widths (or heights) would need to size at 100% of the container, or have the option to. Then the container would be manually sized by the client.
// style.js
const MainActions = styled.div`
margin-bottom: 20px;
display: flex;
align-items: stretch;
`
const Controls = styled.div`
display: flex;
flex-direction: column;
`
const MainActionStartButton = styled.div`
margin-right: 10px;
`
const MainActionEndButton = styled.div`
align-self: center;
`
// layout.js
import { Button } from 'brave-ui'
import * as Styled from './styles'
const MyLayout = () => (
<MainActions>
<Controls>
<Styled.MainActionStartButton>
<Button blah='blah' />
</Styled.MainActionStartButton>
<Button blah='blah' />
</Controls>
<Styled.MainActionEndButton>
<Button blah='blah' />
</MainActionEndButton>
</MainActions>
Option 3 - className
(no wrapper)
Our components can accept an additional class which can specify
Disadvantage is we need to explicitly pass the className
prop to the outermost element in the Component.
//
// style.js
import { Button } from 'brave-ui'
const MainActions = styled.div`
margin-bottom: 20px;
display: flex;
align-items: stretch;
`
const Controls = styled.div`
display: flex;
flex-direction: column;
`
export const MainActionStartButton = styled(Button)`
margin-right: 10px;
`
export const MainActionEndButton = styled(Button)`
align-self: center;
`
//
// layout.js
import { Button } from 'brave-ui'
import * as Styled from './styles'
const MyLayout = () => (
<MainActions>
<Controls>
<Styled.MainActionStartButton blah='blah' />
<Button blah='blah' />
</Controls>
<Styled.MainActionEndButton blah='blah'>
<Button blah='blah' />
</MainActionEndButton>
</MainActions>
Option 4 - Component.extend
I donβt believe this is really possible in most cases, because our Components are not styled-components, they use styled-components for their children.