@retil/control
v0.1.1
Published
Decoupled styles for your control components
Downloads
47
Readme
@retil/control
Create styled buttons and link components with standard CSS -- including :hover
, :focus
, etc. -- without coupling your styles to the underlying <button>
or <a>
tags.
See an introduction with live examples »
This package currently assumes that you're using Styled Components. Want to add Emotion support? Please file an issue!
Installation
npm install -s @retil/control
# or
yarn add @retil/control
Basic Usage
There's two parts to using @retil/control
:
- Create a styled component to render the control's styles
- Add behavior by wrapping it with a control component
1. Create a styled component
You have two options for styling your control: you can use CSS template strings, or style objects with nested selectors.
with template strings
import { active, focus, hover } from '@retil/control'
const ButtonBody = ({ children, ...rest ) => (
<span {...rest} css={css`
background-color: palevioletred;
border: 1px solid palevioletred;
border-radius: 5px;
color: white;
margin: 5px;
${active`
transform: scale(0.99);
`}
${focus`
outline: 1px solid deepskyblue;
`}
${hover`
background-color: transparent;
color: palevioletred;
`}
`}>
{children}
</span>
)
with objects with nested selectors
TODO
2. Add behavior with a Control Component
import { AControl } from '@retil/control'
export const App = () => (
<AControl href='/'>
<ButtonBody>
Home
</ButtonBody>
</AControl>
)
Full API
Control components
These components accept the same properties as the underlying element with the same name, but render without any default styles.
Control components exported by @retil/control
include:
<AControl>
<ButtonControl>
Props
All components accept the following props, in addition to the props accepted by the underlying component:
active
(boolean
)disabled
(boolean
)focus
(boolean
)hover
(boolean
)inline
(boolean
)
Styles
All components render as display: flex
by default. They can be switched to display: inline-flex
by passing an inline
prop.
Components also have the following flexbox styles applied by default -- these can be changed via className
, css
or style
prop.
flex-direction: column;
align-items: stretch;
justify-content: stretch;
Custom controls with the higher order control()
function
To create your own custom Control component, you'll first need a Styled Component (as returned directly from the Style Components styled()
function). Then, you can turn it into a control component by wrapping it with control
.
Here's an example -- this is the exact code used to create the ButtonControl
component exported by @retil/control
import styled from 'styled-components'
import { control, resetButtonCSS } from '@retil/control'
export const ButtonControl = control(
styled.button`
${resetButtonCSS}
`,
)
The control()
function also accepts a function as a second argument, which lets you define the selectors which will be made available to child components. Use this to override the default active
, disabled
, focus
and hover
selectors -- or to provide custom selectors of your own.
const StyledButtonControl = styled.button`
${resetButtonCSS}
`
// Default behavior
export const ButtonControl = control(
StyledButtonControl,
(selectorName: string) => `${Component}:${selectorName}`
)
Template helpers
The following template strings allow can be interpolated within a styled component's css to add styled which respond to events on the control itself.
active
disabled
focus
hover
Example usage:
import { hover } from '@retil/control'
const ButtonBody = styled.span`
opacity: 1;
transition: opacity 100ms ease-out;
${hover`
opacity: 0.9;
`}
`
Custom template helpers with createTemplateHelper()
If you've added your own custom selectors by passing a second argument to control()
, you may also want to create your own custom template helpers.
import { createTemplateHelper } from '@retil/control'
const hover = createTemplateHelper('hover')
useControlContext()
Returns the control context, which is internally stored on the retilControl
prop of the styled components theme.
It has the following shape:
export interface Control {
// Returns a selector which can be interpolated into styles. The default
// controls support `active`, `focus` and `hover` selectors, but this can
// be configured by creating custom controls.
getSelector: (name: string) => string
forceSelectors: {
[selectorName: string]: boolean
}
}
Types
The following TypeScript types are exported:
AControlProps
ButtonControlsProps
Control
CSS reset strings
The CSS strings used to reset the default styles on <a>
and <button>
are exported for your convenience:
import {
resetACSS,
resetButtonCSS,
} from '@retil/control`
License
MIT licensed.