Force TextInput and Select to be `block`. Also, removed props regarding styling.tags/0.3.0
@@ -68,3 +68,4 @@ typings/ | |||
dist/ | |||
.gitignore | |||
.docz/ | |||
/docz.config.js |
@@ -21,5 +21,5 @@ Component for values that have an on/off state. | |||
## See Also | |||
- <Link to="../lib-components-select-select">Select</Link> for a similar component suitable for selecting more values. | |||
- <Link to="../lib-components-radio-button-radio-button">Radio Button</Link> for a similar component on selecting a single value among very few choices. | |||
- <Link to="../select">Select</Link> for a similar component suitable for selecting more values. | |||
- <Link to="../radiobutton">RadioButton</Link> for a similar component on selecting a single value among very few choices. |
@@ -119,6 +119,10 @@ const propTypes = { | |||
* Short textual description indicating the nature of the component's value. | |||
*/ | |||
label: PropTypes.any, | |||
/** | |||
* Name of the form field associated with this component. | |||
*/ | |||
name: PropTypes.string, | |||
} | |||
type Props = PropTypes.InferProps<typeof propTypes> | |||
@@ -129,10 +133,10 @@ type Props = PropTypes.InferProps<typeof propTypes> | |||
* @see {@link RadioButton} for a similar component on selecting a single value among very few choices. | |||
* @type {React.ComponentType<{readonly label?: string} & React.ClassAttributes<unknown>>} | |||
*/ | |||
const Checkbox = React.forwardRef<HTMLInputElement, Props>(({ label = '', ...etcProps }, ref) => ( | |||
const Checkbox = React.forwardRef<HTMLInputElement, Props>(({ label = '', name, }, ref) => ( | |||
<Base> | |||
<CaptureArea> | |||
<Input {...etcProps} ref={ref} type="checkbox" /> | |||
<Input ref={ref} type="checkbox" name={name!} /> | |||
<IndicatorWrapper> | |||
<Border /> | |||
<Indicator> | |||
@@ -35,18 +35,10 @@ const propTypes = { | |||
* Size of the icon. This controls both the width and the height. | |||
*/ | |||
size: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), | |||
/** | |||
* CSS style of the icon. For icon dimensions, use `size` instead. | |||
*/ | |||
style: PropTypes.object, | |||
/** | |||
* Describe of what the component represents. | |||
*/ | |||
label: PropTypes.string, | |||
/** | |||
* Class name used for styling. | |||
*/ | |||
className: PropTypes.string, | |||
} | |||
type Props = PropTypes.InferProps<typeof propTypes> | |||
@@ -55,10 +47,7 @@ const Icon: React.FC<Props> = ({ | |||
name, | |||
weight = '0.125rem', | |||
size = '1.5rem', | |||
style = {}, | |||
label = name, | |||
className = '', | |||
...etcProps | |||
}) => { | |||
const iconName = pascalCase(name, { transform: pascalCaseTransformMerge }) | |||
const { [iconName as keyof typeof FeatherIcon]: TheIcon = null } = FeatherIcon | |||
@@ -68,9 +57,8 @@ const Icon: React.FC<Props> = ({ | |||
if (TheIcon !== null) { | |||
return ( | |||
<span {...etcProps} style={style!}> | |||
<span> | |||
<StyledIcon | |||
className={className!} | |||
as={TheIcon} | |||
size={undefined} | |||
color={undefined} | |||
@@ -1,22 +1,24 @@ | |||
--- | |||
name: Radio Button | |||
route: /components/radio-button | |||
name: RadioButton | |||
route: /components/radiobutton | |||
menu: Components | |||
--- | |||
import { Playground, Props, Link } from 'docz' | |||
import RadioButton from './RadioButton' | |||
# Radio Button | |||
# RadioButton | |||
Component for values which are to be selected from a few list of options. | |||
<Playground> | |||
<div style={{ margin: '1rem 0' }}> | |||
<RadioButton name="flavor" label="Chocolate" /> | |||
</div> | |||
<div style={{ margin: '1rem 0' }}> | |||
<RadioButton name="flavor" label="Vanilla" /> | |||
<div style={{ display: 'grid', gap: '1rem', }}> | |||
<div> | |||
<RadioButton name="flavor" label="Chocolate" /> | |||
</div> | |||
<div> | |||
<RadioButton name="flavor" label="Vanilla" /> | |||
</div> | |||
</div> | |||
</Playground> | |||
@@ -26,5 +28,5 @@ Component for values which are to be selected from a few list of options. | |||
## See Also | |||
- <Link to="../lib-components-checkbox-checkbox">Checkbox</Link> for a similar component on selecting values among very few choices. | |||
- <Link to="../lib-components-select-select">Select</Link> for a similar component suitable for selecting more values. | |||
- <Link to="../checkbox">Checkbox</Link> for a similar component on selecting values among very few choices. | |||
- <Link to="../select">Select</Link> for a similar component suitable for selecting more values. |
@@ -133,12 +133,12 @@ type Props = PropTypes.InferProps<typeof propTypes> | |||
*/ | |||
const RadioButton = React.forwardRef<HTMLInputElement, Props>( | |||
( | |||
{ label = '', name, ...etcProps }, | |||
{ label = '', name, }, | |||
ref | |||
) => ( | |||
<Base> | |||
<CaptureArea> | |||
<Input {...etcProps} ref={ref} name={name} type="radio" /> | |||
<Input ref={ref} name={name} type="radio" /> | |||
<IndicatorWrapper> | |||
<Border /> | |||
<Indicator /> | |||
@@ -12,14 +12,34 @@ import Select from './Select' | |||
Component for selecting values from a larger number of options. | |||
<Playground> | |||
<Select /> | |||
<Select> | |||
<optgroup | |||
label="Fruits" | |||
> | |||
<option value="mango">Mango</option> | |||
<option value="strawberry">Strawberry</option> | |||
<option value="blueberry">Blueberry</option> | |||
</optgroup> | |||
<optgroup | |||
label="Classic" | |||
> | |||
<option value="chocolate">Chocolate</option> | |||
<option value="vanilla">Vanilla</option> | |||
</optgroup> | |||
</Select> | |||
</Playground> | |||
## Props | |||
<Props of={Select} /> | |||
## Usage Notes | |||
The component will behave as `block`, i.e. it takes the remaining of the horizontal space. | |||
To use the component together with layouts, see [TextInput](./textinput) for examples. Both `Select` and | |||
`TextInput` have similar strategies on usage with layouts. | |||
## See Also | |||
- <Link to="../lib-components-checkbox-checkbox">Checkbox</Link> for a similar component on selecting values among very few choices. | |||
- <Link to="../lib-components-radio-button-radio-button">Radio Button</Link> for a similar component on selecting a single value among very few choices. | |||
- <Link to="../checkbox">Checkbox</Link> for a similar component on selecting values among very few choices. | |||
- <Link to="../radiobutton">RadioButton</Link> for a similar component on selecting a single value among very few choices. |
@@ -87,8 +87,9 @@ const Input = styled('select')({ | |||
margin: 0, | |||
font: 'inherit', | |||
minHeight: '4rem', | |||
minWidth: '8rem', | |||
minWidth: '3rem', | |||
maxWidth: '100%', | |||
width: '100%', | |||
zIndex: 1, | |||
cursor: 'pointer', | |||
transitionProperty: 'background-color, color', | |||
@@ -177,10 +178,6 @@ const propTypes = { | |||
* Short textual description indicating the nature of the component's value. | |||
*/ | |||
label: PropTypes.any, | |||
/** | |||
* Class name for the component, used for styling. | |||
*/ | |||
className: PropTypes.string, | |||
/** | |||
* Short textual description as guidelines for valid input values. | |||
*/ | |||
@@ -198,9 +195,9 @@ const propTypes = { | |||
*/ | |||
disabled: PropTypes.bool, | |||
/** | |||
* CSS styles. | |||
* Name of the form field associated with this component. | |||
*/ | |||
style: PropTypes.object, | |||
name: PropTypes.string, | |||
} | |||
type Props = PropTypes.InferProps<typeof propTypes> | |||
@@ -209,13 +206,12 @@ const Select = React.forwardRef<HTMLSelectElement, Props>( | |||
( | |||
{ | |||
label = '', | |||
className = '', | |||
hint = '', | |||
size = 'medium', | |||
multiple = false, | |||
disabled = false, | |||
style = {}, | |||
...etcProps | |||
name, | |||
children, | |||
}, | |||
ref, | |||
) => { | |||
@@ -226,7 +222,7 @@ const Select = React.forwardRef<HTMLSelectElement, Props>( | |||
}} | |||
> | |||
<Border /> | |||
<CaptureArea className={className!}> | |||
<CaptureArea> | |||
<LabelWrapper | |||
style={{ | |||
paddingTop: LABEL_VERTICAL_PADDING_SIZES[size!], | |||
@@ -239,12 +235,11 @@ const Select = React.forwardRef<HTMLSelectElement, Props>( | |||
</LabelWrapper> | |||
{stringify(label).length > 0 && ' '} | |||
<Input | |||
{...etcProps} | |||
ref={ref} | |||
disabled={disabled!} | |||
multiple={multiple!} | |||
name={name!} | |||
style={{ | |||
...style, | |||
verticalAlign: 'top', | |||
fontSize: INPUT_FONT_SIZES[size!], | |||
height: multiple ? undefined : MIN_HEIGHTS[size!], | |||
@@ -254,7 +249,9 @@ const Select = React.forwardRef<HTMLSelectElement, Props>( | |||
paddingBottom: VERTICAL_PADDING_SIZES[size!], | |||
paddingRight: !multiple ? MIN_HEIGHTS[size!] : '1rem', | |||
}} | |||
/> | |||
> | |||
{children} | |||
</Input> | |||
</CaptureArea> | |||
{stringify(hint).length > 0 && ' '} | |||
{stringify(hint).length > 0 && ( | |||
@@ -21,3 +21,7 @@ the component falls back into the original `<input type="range">` element. | |||
## Props | |||
<Props of={Slider} /> | |||
## See Also | |||
- [Reach UI Slider](//reacttraining.com/reach-ui/slider/#sliderinput) for the client-side implementation. |
@@ -200,10 +200,6 @@ const propTypes = { | |||
* CSS size for the component length. | |||
*/ | |||
length: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), | |||
/** | |||
* Class name used for styling. | |||
*/ | |||
className: PropTypes.string, | |||
/** | |||
* Is the component active? | |||
*/ | |||
@@ -222,18 +218,14 @@ type Props = PropTypes.InferProps<typeof propTypes> | |||
* @param {'vertical' | 'horizontal'} [orientation] - The component orientation. | |||
* @param {*} [label] - Short textual description indicating the nature of the component's value. | |||
* @param {string | number} [length] - CSS size for the component length. | |||
* @param {string} [className] - Class name used for styling. | |||
* @param {boolean} [disabled] - Is the component active? | |||
* @param {object} etcProps - The component props. | |||
* @returns {React.ReactElement} The component elements. | |||
*/ | |||
const Slider: React.FC<Props> = ({ | |||
orientation = 'horizontal', | |||
label = '', | |||
length = '16rem', | |||
className = '', | |||
disabled = false, | |||
...etcProps | |||
}) => { | |||
const [isClient, setIsClient] = React.useState(false) | |||
@@ -250,10 +242,17 @@ const Slider: React.FC<Props> = ({ | |||
const perpendicularTransform = orientation === 'horizontal' ? 'translateY' : 'translateX' | |||
const customBaseProps: any = { | |||
orientation, | |||
} | |||
const customFallbackProps: any = { | |||
orient: orientation, | |||
} | |||
if (isClient) { | |||
return ( | |||
<Wrapper | |||
className={className!} | |||
style={{ | |||
opacity: disabled ? 0.5 : undefined, | |||
[parallelDimension]: length!, | |||
@@ -288,7 +287,7 @@ const Slider: React.FC<Props> = ({ | |||
</TransformWrapper> | |||
</SizingWrapper> | |||
<Base | |||
{...etcProps} | |||
{...customBaseProps} | |||
disabled={disabled!} | |||
style={{ | |||
[parallelDimension]: length, | |||
@@ -319,7 +318,6 @@ const Slider: React.FC<Props> = ({ | |||
return ( | |||
<Wrapper | |||
className={className!} | |||
style={{ | |||
opacity: disabled ? 0.5 : undefined, | |||
[parallelDimension]: length!, | |||
@@ -358,7 +356,7 @@ const Slider: React.FC<Props> = ({ | |||
</LabelWrapper> | |||
{stringify(label).length > 0 && ' '} | |||
<FallbackSlider | |||
{...etcProps} | |||
{...customFallbackProps} | |||
style={{ | |||
width: length!, | |||
}} | |||
@@ -1,13 +1,13 @@ | |||
--- | |||
name: Text Input | |||
route: /components/text-input | |||
name: TextInput | |||
route: /components/textinput | |||
menu: Components | |||
--- | |||
import { Playground, Props } from 'docz' | |||
import { Playground, Props, Link } from 'docz' | |||
import TextInput from './TextInput' | |||
# Text Input | |||
# TextInput | |||
Component for inputting textual values. | |||
@@ -18,3 +18,54 @@ Component for inputting textual values. | |||
## Props | |||
<Props of={TextInput} /> | |||
## Usage Notes | |||
The component will behave as `block`, i.e. it takes the remaining of the horizontal space. | |||
To use the component together with layouts, see the following examples. | |||
### Inline | |||
The components are surrounded by `inline-block` elements. These surrounding elements have specified widths, which could | |||
act as guide to the user on how long the expected input values are. | |||
<Playground> | |||
<form> | |||
I am <span style={{ display: 'inline-block', width: '16rem', }}><TextInput label="Full name" hint="given and family name" /></span> and I live in <span style={{ display: 'inline-block', width: '24rem', }}><TextInput label="Address" hint="city, state and country" /></span>. | |||
</form> | |||
</Playground> | |||
### Grid | |||
It is advisable to put surrounding elements instead of the `TextInput` components themselves as children of the | |||
element specified as `grid`. This is to be able to add complementing content to the components, if for example there are | |||
some content that is best displayed outside the component instead of putting in the `hint` prop. | |||
<Playground> | |||
<form | |||
style={{ display: 'grid', gridTemplateColumns: '4fr 4fr 5fr', gap: '1rem', }} | |||
> | |||
<div style={{ gridColumnStart: 1, gridColumnEnd: 4, }}> | |||
<TextInput label="Address line 1" hint="unit/house number, building" /> | |||
</div> | |||
<div style={{ gridColumnStart: 1, gridColumnEnd: 4, }}> | |||
<TextInput label="Address line 2" hint="street, area" /> | |||
</div> | |||
<div> | |||
<TextInput size="large" label="City/Town" /> | |||
</div> | |||
<div> | |||
<TextInput size="large" label="State/Province" /> | |||
</div> | |||
<div> | |||
<TextInput size="large" label="Country" hint="abbreviations are accepted" /> | |||
<small> | |||
Consult the <a href="#">fees table</a> for shipping fee details. | |||
</small> | |||
</div> | |||
</form> | |||
</Playground> | |||
## See Also | |||
- <Link to="../select">Select</Link> for a graphically-similar component suitable for selecting more values. |
@@ -124,6 +124,7 @@ const Input = styled('input')({ | |||
minHeight: '4rem', | |||
minWidth: '8rem', | |||
maxWidth: '100%', | |||
width: '100%', | |||
zIndex: 1, | |||
transitionProperty: 'background-color, color', | |||
':focus': { | |||
@@ -151,7 +152,7 @@ const TextArea = styled('textarea')({ | |||
margin: 0, | |||
font: 'inherit', | |||
minHeight: '4rem', | |||
minWidth: '16rem', | |||
minWidth: '3rem', | |||
maxWidth: '100%', | |||
zIndex: 1, | |||
transitionProperty: 'background-color, color', | |||
@@ -201,10 +202,6 @@ const propTypes = { | |||
* Short textual description indicating the nature of the component's value. | |||
*/ | |||
label: PropTypes.any, | |||
/** | |||
* Class name for the component, used for styling. | |||
*/ | |||
className: PropTypes.string, | |||
/** | |||
* Short textual description as guidelines for valid input values. | |||
*/ | |||
@@ -233,6 +230,10 @@ const propTypes = { | |||
* Placeholder of the component when there is no value. | |||
*/ | |||
placeholder: PropTypes.string, | |||
/** | |||
* How many rows should the component display if it accepts multiline input? | |||
*/ | |||
rows: PropTypes.number, | |||
} | |||
type Props = PropTypes.InferProps<typeof propTypes> | |||
@@ -241,7 +242,6 @@ const TextInput = React.forwardRef<HTMLInputElement | HTMLTextAreaElement, Props | |||
( | |||
{ | |||
label = '', | |||
className = '', | |||
hint = '', | |||
indicator = null, | |||
size = 'medium', | |||
@@ -249,6 +249,7 @@ const TextInput = React.forwardRef<HTMLInputElement | HTMLTextAreaElement, Props | |||
disabled = false, | |||
autoResize = false, | |||
placeholder = '', | |||
rows = 3, | |||
}, | |||
ref, | |||
) => ( | |||
@@ -258,7 +259,7 @@ const TextInput = React.forwardRef<HTMLInputElement | HTMLTextAreaElement, Props | |||
}} | |||
> | |||
<Border /> | |||
<CaptureArea className={className!}> | |||
<CaptureArea> | |||
<LabelWrapper | |||
style={{ | |||
paddingTop: LABEL_VERTICAL_PADDING_SIZES[size!], | |||
@@ -275,7 +276,9 @@ const TextInput = React.forwardRef<HTMLInputElement | HTMLTextAreaElement, Props | |||
placeholder={placeholder!} | |||
ref={ref as React.Ref<HTMLTextAreaElement>} | |||
disabled={disabled!} | |||
rows={rows!} | |||
style={{ | |||
height: `calc(${MIN_HEIGHTS[size!]} * ${rows})`, | |||
fontSize: INPUT_FONT_SIZES[size!], | |||
minHeight: MIN_HEIGHTS[size!], | |||
paddingTop: VERTICAL_PADDING_SIZES[size!], | |||