Skip to content

Commit

Permalink
Bug/select icon margin (#237)
Browse files Browse the repository at this point in the history
* add padding for icon on Select, add SelectField, add docs

* wip. include in docs

* wip
  • Loading branch information
mshwery authored and jeroenransijn committed Jul 20, 2018
1 parent 7630a53 commit 87c3090
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 9 deletions.
4 changes: 4 additions & 0 deletions docs/src/componentRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ module.exports = [
name: 'Colors',
path: '/components/colors'
},
{
name: 'Select',
path: '/components/select'
},
{
name: 'Select Menu',
path: '/components/select-menu'
Expand Down
3 changes: 2 additions & 1 deletion docs/src/utils/getComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import buttonsDocs from '../../../src/buttons/docs'
import autocompleteDocs from '../../../src/autocomplete/docs/'
import comboboxDocs from '../../../src/combobox/docs/'
// import badgesDocs from '../../src/badges/docs/'
// import selectDocs from '../../src/select/docs/'
import popoverDocs from '../../../src/popover/docs/'
// import portalDocs from '../../src/portal/docs/'
import textInputDocs from '../../../src/text-input/docs/'
Expand All @@ -29,6 +28,7 @@ import cornerDialogDocs from '../../../src/corner-dialog/docs/'
import alertDocs from '../../../src/alert/docs/'
import toasterDocs from '../../../src/toaster/docs/'
import selectMenuDocs from '../../../src/select-menu/docs/'
import selectDocs from '../../../src/select/docs/'

const map = {
radio: radioDocs,
Expand All @@ -41,6 +41,7 @@ const map = {
layers: layersDocs,
typography: typographyDocs,
colors: colorsDocs,
select: selectDocs,
'select menu': selectMenuDocs,
'text input': textInputDocs,
'search input': searchInputDocs,
Expand Down
4 changes: 4 additions & 0 deletions src/select/docs/examples/Select-basic.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<Select onChange={(event) => alert(event.target.value)}>
<option value="foo" checked>Foo</option>
<option value="bar">Bar</option>
</Select>
66 changes: 66 additions & 0 deletions src/select/docs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from 'react'
import Box from 'ui-box'
import Component from '@reactions/component'
import Select from '../src/Select'

/* eslint-disable import/no-unresolved, import/no-webpack-loader-syntax */
import sourceSelect from '!raw-loader!../src/Select'
/* eslint-enable import/no-unresolved, import/no-webpack-loader-syntax */

/**
* Code examples
*/
import exampleSelectBasic from './examples/Select-basic.example'

const title = 'Select'
const subTitle = 'A styled native <select> for choosing items from a list.'

const introduction = (
<div>
<p>
The <code>Select</code> component is a styled wrapper around a native{' '}
<code>select</code> element, which allows selection of one item from a
dropdown list. Anytime you would reach for a native select, use this.
</p>
</div>
)

const appearanceOptions = null

const scope = {
Box,
Select,
Component
}

const components = [
{
name: 'Select',
source: sourceSelect,
description: (
<p>
The <code>Select</code> component.
</p>
),
examples: [
{
title: 'Basic Select Example',
description: (
<div>
<p>This example shows basic usage with a selected item.</p>
</div>
),
codeText: exampleSelectBasic,
scope
}
]
}
]

export default {
title,
subTitle,
introduction,
appearanceOptions,
components
}
1 change: 1 addition & 0 deletions src/select/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export Select from './src/Select'
export SelectField from './src/SelectField'
7 changes: 5 additions & 2 deletions src/select/src/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,14 @@ class Select extends PureComponent {
const textSize = theme.getTextSizeForControlHeight(height)
const borderRadius = theme.getBorderRadiusForControlHeight(height)
const iconSize = theme.getIconSizeForSelect(height)
const iconMargin = height >= 36 ? 12 : 8

return (
<Box
display="inline-flex"
flex={1}
position="relative"
width={200}
width="auto"
height={height}
{...props}
>
Expand All @@ -130,6 +131,8 @@ class Select extends PureComponent {
borderRadius={borderRadius}
textTransform="default"
paddingLeft={Math.round(height / 3.2)}
// Provide enough space for auto-sizing select including the icon
paddingRight={iconMargin * 2 + iconSize}
>
{children}
</Text>
Expand All @@ -140,7 +143,7 @@ class Select extends PureComponent {
position="absolute"
top="50%"
marginTop={-iconSize / 2}
right={height >= 36 ? 12 : 8}
right={iconMargin}
pointerEvents="none"
/>
</Box>
Expand Down
125 changes: 125 additions & 0 deletions src/select/src/SelectField.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import { splitBoxProps } from 'ui-box'
import { FormField } from '../../form-field'
import Select from './Select'

let idCounter = 0

export default class TextInputField extends PureComponent {
static propTypes = {
/**
* Composes the Select component as the base.
*/
...Select.propTypes,
...FormField.propTypes,

/**
* The label used above the input element.
*/
label: PropTypes.node.isRequired,

/**
* Passed on the label as a htmlFor prop.
*/
labelFor: PropTypes.string,

/**
* Wether or not show a asterix after the label.
*/
isRequired: PropTypes.bool,

/**
* A optional description of the field under the label, above the input element.
*/
description: PropTypes.node,

/**
* A optional hint under the input element.
*/
hint: PropTypes.node,

/**
* If a validation message is passed it is shown under the input element
* and above the hint.
*/
validationMessage: PropTypes.node,

/**
* The height of the input element.
*/
inputHeight: PropTypes.number,

/**
* The width of the input width.
*/
inputWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
}

static defaultProps = {
/**
* The input width should be as wide as the form field.
*/
inputWidth: '100%',
inputHeight: 32
}

state = {
id: (this.props.id || idCounter++).toString()
}

render() {
const {
// We are using the id from the state
id: unusedId,

// FormField props
hint,
label,
description,
validationMessage,

// TextInput props
inputHeight,
inputWidth,
disabled,
required,
isInvalid,
appearance,

// Rest props are spread on the FormField
...props
} = this.props

const id = `SelectField-${this.state.id}`

/**
* Split the wrapper props from the input props.
*/
const { matchedProps, remainingProps } = splitBoxProps(props)

return (
<FormField
marginBottom={24}
label={label}
isRequired={required}
hint={hint}
description={description}
validationMessage={validationMessage}
labelFor={id}
{...matchedProps}
>
<Select
id={id}
width={inputWidth}
height={inputHeight}
disabled={disabled}
required={required}
isInvalid={isInvalid}
appearance={appearance}
{...remainingProps}
/>
</FormField>
)
}
}
9 changes: 3 additions & 6 deletions src/text-input/src/TextInputField.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,8 @@ export default class TextInputField extends PureComponent {
inputHeight: 32
}

constructor(props) {
super(props)
this.state = {
id: (props.id || idCounter++).toString()
}
state = {
id: (this.props.id || idCounter++).toString()
}

render() {
Expand Down Expand Up @@ -96,7 +93,7 @@ export default class TextInputField extends PureComponent {
...props
} = this.props

const { id } = this.state
const id = `TextInputField-${this.state.id}`

/**
* Split the wrapper props from the input props.
Expand Down

0 comments on commit 87c3090

Please sign in to comment.