diff --git a/jest.config.js b/jest.config.js index 4072abea..063ab027 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,6 +1,6 @@ module.exports = { setupFilesAfterEnv: ['/jest.setup.js'], - testPathIgnorePatterns: ['/template/', 'dist'], + testPathIgnorePatterns: ['/template/', '/dist/'], moduleNameMapper: { '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '/tests/file-mock.js', diff --git a/packages/flame/CHANGELOG.md b/packages/flame/CHANGELOG.md index 3953dd75..b0546bfb 100644 --- a/packages/flame/CHANGELOG.md +++ b/packages/flame/CHANGELOG.md @@ -12,6 +12,17 @@ Refer to the [CONTRIBUTING guide](https://github.com/lightspeed/flame/blob/maste ### Added - Add Interac icon ([#33](https://github.com/lightspeed/flame/pull/33)) +- Add InputGroup and FormField (Label + FormHelper) components ([#2](https://github.com/lightspeed/flame/pull/2)) +- Expose Input, Radio and Checkbox base components ([#2](https://github.com/lightspeed/flame/pull/2)) +- Enable `zIndex` Styled System props for Button, BaseInput and InputGroupAddon components ([#2](https://github.com/lightspeed/flame/pull/2)) + +### Changed + +- Input no longer uses objects to represent status and status message ([#2](https://github.com/lightspeed/flame/pull/2)) + +### Deprecated + +- Group component will be removed from the next major version of Flame ([#2](https://github.com/lightspeed/flame/pull/2)) ## 1.0.0 - 2019-10-08 diff --git a/packages/flame/src/Button/BaseButton.tsx b/packages/flame/src/Button/BaseButton.tsx index 3979cc77..5628694c 100644 --- a/packages/flame/src/Button/BaseButton.tsx +++ b/packages/flame/src/Button/BaseButton.tsx @@ -1,8 +1,17 @@ import { css } from '@emotion/core'; import styled from '@emotion/styled'; -import { space, SpaceProps } from 'styled-system'; +import { + space, + SpaceProps, + layout, + LayoutProps, + zIndex, + ZIndexProps, + compose, +} from 'styled-system'; import { themeGet } from '@styled-system/theme-get'; import { Merge } from 'type-fest'; +import { border, BorderProps } from '../Core'; export type ButtonHTML = React.HTMLProps & React.HTMLProps; export type ButtonSizes = 'small' | 'large' | 'xlarge' | 'medium'; @@ -13,7 +22,10 @@ export type BaseButtonProps = { disabled?: boolean; /** Sets display: block on Button */ block?: boolean; -} & SpaceProps; +} & SpaceProps & + LayoutProps & + BorderProps & + ZIndexProps; const generateSize = (height: number, px: number, font: string, radius: string) => ( props: BaseButtonProps, @@ -89,7 +101,13 @@ export const BaseButton = styled('button')>` } ${setDisabled}; - ${space}; + + ${compose( + space, + border, + layout, + zIndex, + )}; `; BaseButton.defaultProps = { diff --git a/packages/flame/src/Button/story.tsx b/packages/flame/src/Button/story.tsx index 40b80fe9..4a353383 100644 --- a/packages/flame/src/Button/story.tsx +++ b/packages/flame/src/Button/story.tsx @@ -7,9 +7,11 @@ import { Button } from './Button'; import Readme from './README.md'; import { Flex, Box } from '../Core'; import { Divider } from '../Divider'; -import { Group } from '../Group'; +import { InputGroup } from '../InputGroup'; import { Icon } from '../Icon'; +import { SpacedGroup } from '../../../../stories/components/SpacedGroup'; + const stories = storiesOf('Button', module).addDecorator(withReadme(Readme)); type ButtonPresenterState = { @@ -56,15 +58,15 @@ class ButtonPresenter extends PureComponent<{}, ButtonPresenterState> { stories.add('Styles', () => (

Outline

- + - +

Forced State - Active

- + - +

Forced State - Hover

- + - +

Fill

- + @@ -102,10 +104,10 @@ stories.add('Styles', () => ( - +

Forced State - Active

- + @@ -115,10 +117,10 @@ stories.add('Styles', () => ( - +

Forced State - Hover

- + @@ -128,14 +130,14 @@ stories.add('Styles', () => ( - +
)); stories.add('Sizes', () => (
- + - + - + @@ -160,7 +162,7 @@ stories.add('Sizes', () => ( - +

Multiline

@@ -208,7 +210,7 @@ stories.add('Button as Links', () => ( stories.add('Events', () => (
- + @@ -227,7 +229,7 @@ stories.add('Events', () => ( - +
)); @@ -235,48 +237,48 @@ stories.add('Events', () => ( stories.add('With Children', () => (
- + - + - + - + - + - + - + - + - + @@ -301,15 +303,15 @@ stories.add('With Children', () => ( Large Block - + - + @@ -323,16 +325,16 @@ stories.add('With Children', () => ( Large Block - +

Icons with details should be colored properly

- + @@ -345,7 +347,7 @@ stories.add('With Children', () => ( - +
)); @@ -353,7 +355,7 @@ stories.add('With Children', () => ( stories.add('Loading', () => (
- + - + - + @@ -377,7 +379,7 @@ stories.add('Loading', () => ( - + diff --git a/packages/flame/src/Checkbox/Checkbox.test.tsx b/packages/flame/src/Checkbox/Checkbox.test.tsx index 50db12c3..3e798dee 100644 --- a/packages/flame/src/Checkbox/Checkbox.test.tsx +++ b/packages/flame/src/Checkbox/Checkbox.test.tsx @@ -12,8 +12,8 @@ type RenderTest = { indeterminate?: boolean; id?: string; value?: string; - label?: string | Function; - description?: string | Function; + label?: any; + description?: any; }; }; @@ -34,8 +34,8 @@ describe('', () => { props: { id: 'id', value: 'value', - label: () =>
Label
, - description: () =>
Description
, + label:
Label
, + description:
Description
, }, }, ]; @@ -82,10 +82,7 @@ describe('', () => { it('renders custom components in Label and Description', () => { const { getByText } = customRender( -
my label
} - description={() =>
my description
} - />, + my label
} description={
my description
} />, ); getByText('my label'); diff --git a/packages/flame/src/Checkbox/Checkbox.tsx b/packages/flame/src/Checkbox/Checkbox.tsx index 14111a96..a470eaa9 100644 --- a/packages/flame/src/Checkbox/Checkbox.tsx +++ b/packages/flame/src/Checkbox/Checkbox.tsx @@ -4,19 +4,16 @@ import styled from '@emotion/styled'; import { themeGet } from '@styled-system/theme-get'; import { Merge } from 'type-fest'; import { IconCheckmark } from '../Icon/Checkmark'; -import { Box } from '../Core'; -import { Text, TextProps } from '../Text'; +import { TextProps } from '../Text'; +import { RadioLabel } from '../Radio'; + +const CheckboxLabel = RadioLabel; const Wrapper = styled('div')` position: relative; line-height: 1rem; `; -const Label = styled('label')` - position: relative; - display: inline-flex; -`; - const CheckboxCheckmarkWrapper = styled('div')<{ indeterminate: boolean }>` position: relative; width: 1rem; @@ -29,6 +26,7 @@ const CheckboxCheckmarkWrapper = styled('div')<{ indeterminate: boolean }>` overflow: hidden; cursor: default; background: ${themeGet('checkboxStyles.background')}; + margin-right: ${themeGet('space.2')}; ${props => props.indeterminate && @@ -93,124 +91,46 @@ const CheckboxInput = styled('input')<{ indeterminate: boolean }>` } `; -export type CheckboxLabelProps = TextProps; -export const CheckboxLabel = styled(Text)` - ${props => - !props.color && - css` - color: ${themeGet('checkboxStyles.label.color')(props)}; - `} -`; -CheckboxLabel.defaultProps = { - ml: 2, - fontWeight: 'bold', - size: 'small', - as: 'div', -}; - -// Probably wondering why we add this additional wrapper? -// This is to detach the text from a specific color and instead rely on -// a color alias from the theme -const CheckboxDescriptionWrapper = styled(Box)` - ${Text} { - ${props => - !props.color - ? css` - color: ${themeGet('checkboxStyles.description.color')(props)}; - ` - : css` - color: ${themeGet(`colors.${props.color}`, props.color)(props)}; - `} - } -`; - export type CheckboxDescriptionProps = Merge, TextProps>; -export const CheckboxDescription: React.FC = ({ - children, - color, - ...restProps -}) => ( - - - {children} - - +export interface BaseCheckboxProps extends React.InputHTMLAttributes { + indeterminate?: boolean; + checked?: boolean; + css?: any; +} +const BaseCheckbox = React.forwardRef( + ({ indeterminate, checked, ...restProps }, ref) => ( + + + + + {indeterminate && !checked && } + + + ), ); -export type CheckboxProps = Merge< - React.InputHTMLAttributes, - { - /** ClassName for the */ - inputClassName?: string; - /** Sets label for Checkbox */ - label?: string | Function; - /** Sets description text for Checkbox */ - description?: string | Function; - /** Sets indeterminate state for Checkbox */ - indeterminate?: boolean; - /** https://reactjs.org/docs/forwarding-refs.html */ - innerRef?: Function; - /** https://reactjs.org/docs/refs-and-the-dom.html */ - ref?: Function; - } -> & { css?: any }; -export const Checkbox: React.FC = ({ - className, - inputClassName, - id, - label, - description, - checked, - indeterminate, - innerRef, - ref, - ...props -}) => { - const labelId = id ? `${id}-label` : null; - const descriptionId = id ? `${id}-description` : null; - const labelledBy = label ? labelId : null; - const describedBy = description ? descriptionId : null; - - const setCheckboxRef = (elem: HTMLInputElement) => { - if (elem) { - // eslint-disable-next-line no-param-reassign - elem.indeterminate = indeterminate && !checked; - - if (innerRef && typeof innerRef === 'function') { - innerRef(elem); - } - - if (ref && typeof innerRef === 'function') { - ref(elem); - } - } - }; - - return ( - - - {typeof description === 'string' && ( - {description} - )} - {typeof description === 'function' && description(descriptionId)} - - ); -}; +export interface CheckboxProps extends BaseCheckboxProps { + label?: React.ReactNode; + description?: React.ReactNode; + css?: any; +} +const Checkbox = React.forwardRef( + ({ label, id, description, disabled, ...restProps }, ref) => { + return ( + + + + {label} + + + ); + }, +); + +export { Checkbox, CheckboxLabel, BaseCheckbox }; diff --git a/packages/flame/src/Checkbox/README.md b/packages/flame/src/Checkbox/README.md index 79bba2c0..18007891 100644 --- a/packages/flame/src/Checkbox/README.md +++ b/packages/flame/src/Checkbox/README.md @@ -25,16 +25,6 @@ On/Off --> ``. | `indeterminate` | `boolean` | Set to true true for indeterminate style | | `html property` | `string` | Any extra properties passed will be added to the underlying `` tag | -#### `` - -A prestyled flame Text element. Please consult the [Text component readme](https://github.com/lightspeed/flame/tree/master/packages/flame/src/Text) for details on which props are available. - -#### `` - -A prestyled flame Text element, with a small Box wrapper. Please note that all props forwarded will be sent to the underlying Text component, not the Box. - -Please consult the [Text component readme](https://github.com/lightspeed/flame/tree/master/packages/flame/src/Text) for details on which props are available. - ### Example #### Simple stateless Checkbox @@ -131,13 +121,42 @@ const MyComponent = () => (
Custom Label
} - description={descriptionId => ( - Custom description - )} + label={
Custom Label
} + description={Custom description} />
); export default MyComponent; ``` + +#### `` + +The primitive element of Checkbox. No labels or descriptions. + +This component has the exact same props as the native HTML checkbox. + +#### `` + +Specially styled label to be used in conjunction with the BaseCheckbox component. Use this component to properly align the description. + +| Prop | Type | Default | Description | +| --------------- | ---------------------------- | --------- | -------------------------------------------------------------- | +| `description` | `string` or `child function` | undefined | Description's text | +| `html property` | `string` | undefined | Any extra properties passed will be added to the `