Skip to content

Commit

Permalink
feat(CustomInput): add more custom inputs (#991)
Browse files Browse the repository at this point in the history
Closes #534
  • Loading branch information
TheSharpieOne committed May 1, 2018
1 parent 312e729 commit ccdb7f2
Show file tree
Hide file tree
Showing 12 changed files with 546 additions and 305 deletions.
14 changes: 13 additions & 1 deletion docs/lib/Components/FormPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ export default class FormPage extends React.Component {
addon: PropTypes.bool,
className: PropTypes.string,
cssModule: PropTypes.object,
};`}
{`CustomInput.propTypes = {
className: PropTypes.string,
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
type: PropTypes.string.isRequired, // radio, checkbox, select, range.
label: PropTypes.string, // used for checkbox and radios
inline: PropTypes.bool,
valid: PropTypes.bool, // applied the is-invalid class when true, does nothing when false
invalid: PropTypes.bool, // applied the is-valid class when true, does nothing when false
bsSize: PropTypes.string,
cssModule: PropTypes.object,
children: PropTypes.oneOfType(PropTypes.node, PropTypes.array, PropTypes.func) // for type="select"
};`}
</PrismCode>
</pre>
Expand Down Expand Up @@ -152,7 +164,7 @@ export default class FormPage extends React.Component {
</PrismCode>
</pre>

<SectionTitle>Custom Controls</SectionTitle>
<SectionTitle>Custom Inputs</SectionTitle>
<div className="docs-example">
<CustomControlsExample />
</div>
Expand Down
74 changes: 65 additions & 9 deletions docs/lib/examples/CustomControls.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { CustomCheckbox, CustomRadio, Form, FormGroup, Label } from 'reactstrap';
import { CustomInput, Form, FormGroup, Label } from 'reactstrap';

export default class Example extends React.Component {
render() {
Expand All @@ -8,26 +8,82 @@ export default class Example extends React.Component {
<FormGroup>
<Label for="exampleCheckbox">Checkboxes</Label>
<div>
<CustomCheckbox id="exampleCustomCheckbox" description="Check this custom checkbox" />
<CustomCheckbox id="exampleCustomCheckbox2" description="Or this one" />
<CustomCheckbox id="exampleCustomCheckbox3" description="But not this disabled one" disabled />
<CustomInput type="checkbox" id="exampleCustomCheckbox" label="Check this custom checkbox" />
<CustomInput type="checkbox" id="exampleCustomCheckbox2" label="Or this one" />
<CustomInput type="checkbox" id="exampleCustomCheckbox3" label="But not this disabled one" disabled />
</div>
</FormGroup>
<FormGroup>
<Label for="exampleCheckbox">Radios</Label>
<div>
<CustomRadio id="exampleCustomRadio" name="customRadio" description="Select this custom radio" />
<CustomRadio id="exampleCustomRadio2" name="customRadio" description="Or this one" />
<CustomRadio id="exampleCustomRadio3" description="But not this disabled one" disabled />
<CustomInput type="radio" id="exampleCustomRadio" name="customRadio" label="Select this custom radio" />
<CustomInput type="radio" id="exampleCustomRadio2" name="customRadio" label="Or this one" />
<CustomInput type="radio" id="exampleCustomRadio3" label="But not this disabled one" disabled />
</div>
</FormGroup>
<FormGroup>
<Label for="exampleCheckbox">Inline</Label>
<div>
<CustomCheckbox id="exampleCustomInline" description="An inline custom input" inline />
<CustomCheckbox id="exampleCustomInline2" description="and another one" inline />
<CustomInput type="checkbox" id="exampleCustomInline" label="An inline custom input" inline />
<CustomInput type="checkbox" id="exampleCustomInline2" label="and another one" inline />
</div>
</FormGroup>
<FormGroup>
<Label for="exampleCustomSelect">Custom Select</Label>
<CustomInput type="select" id="exampleCustomSelect" name="customSelect">
<option value="">Select</option>
<option>Value 1</option>
<option>Value 2</option>
<option>Value 3</option>
<option>Value 4</option>
<option>Value 5</option>
</CustomInput>
</FormGroup>
<FormGroup>
<Label for="exampleCustomMutlipleSelect">Custom Multiple Select</Label>
<CustomInput type="select" id="exampleCustomMutlipleSelect" name="customSelect" multiple>
<option value="">Select</option>
<option>Value 1</option>
<option>Value 2</option>
<option>Value 3</option>
<option>Value 4</option>
<option>Value 5</option>
</CustomInput>
</FormGroup>
<FormGroup>
<Label for="exampleCustomSelectDisabled">Custom Select Disabled</Label>
<CustomInput type="select" id="exampleCustomSelectDisabled" name="customSelect" disabled>
<option value="">Select</option>
<option>Value 1</option>
<option>Value 2</option>
<option>Value 3</option>
<option>Value 4</option>
<option>Value 5</option>
</CustomInput>
</FormGroup>
<FormGroup>
<Label for="exampleCustomMutlipleSelectDisabled">Custom Multiple Select Disabled</Label>
<CustomInput type="select" id="exampleCustomMutlipleSelectDisabled" name="customSelect" multiple disabled>
<option value="">Select</option>
<option>Value 1</option>
<option>Value 2</option>
<option>Value 3</option>
<option>Value 4</option>
<option>Value 5</option>
</CustomInput>
</FormGroup>
<FormGroup>
<Label for="exampleCustomFileBrowser">File Browser</Label>
<CustomInput type="file" id="exampleCustomFileBrowser" name="customFile" />
</FormGroup>
<FormGroup>
<Label for="exampleCustomFileBrowser">File Browser with Custom Label</Label>
<CustomInput type="file" id="exampleCustomFileBrowser" name="customFile" label="Yo, pick a file!" />
</FormGroup>
<FormGroup>
<Label for="exampleCustomFileBrowser">File Browser Disabled</Label>
<CustomInput type="file" id="exampleCustomFileBrowser" name="customFile" disabled />
</FormGroup>
</Form>
);
}
Expand Down
33 changes: 18 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"main": "dist/reactstrap.cjs.js",
"jsnext:main": "dist/reactstrap.es.js",
"module": "dist/reactstrap.es.js",
"jsdelivr": "dist/reactstrap.min.js",
"unpkg": "dist/reactstrap.min.js",
"cdn": "dist/reactstrap.min.js",
"scripts": {
"report-coverage": "coveralls < ./coverage/lcov.info",
"test": "cross-env BABEL_ENV=test react-scripts test --env=jsdom",
Expand Down Expand Up @@ -93,8 +96,8 @@
"lodash.isobject": "^3.0.2",
"lodash.tonumber": "^4.0.3",
"prop-types": "^15.5.8",
"react-popper": "^0.10.1",
"react-transition-group": "^2.2.1"
"react-popper": "^0.10.4",
"react-transition-group": "^2.3.1"
},
"peerDependencies": {
"react": "^16.0.0",
Expand All @@ -107,20 +110,20 @@
"babel-preset-es2015-rollup": "^3.0.0",
"babel-preset-react": "^6.11.1",
"babel-preset-react-app": "^0.2.1",
"bootstrap": "^4.1.0",
"clean-webpack-plugin": "^0.1.18",
"conventional-changelog-cli": "^1.3.14",
"bootstrap": "^4.1.1",
"clean-webpack-plugin": "^0.1.19",
"conventional-changelog-cli": "^1.3.22",
"conventional-recommended-bump": "^0.3.0",
"copy-webpack-plugin": "^3.0.1",
"coveralls": "^2.11.12",
"cross-env": "^2.0.0",
"css-loader": "^0.25.0",
"ejs": "^2.5.1",
"ejs": "^2.5.9",
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"eslint": "^4.18.1",
"eslint": "^4.19.1",
"eslint-config-airbnb": "^15.1.0",
"eslint-plugin-import": "^2.9.0",
"eslint-plugin-import": "^2.11.0",
"eslint-plugin-jsx-a11y": "^5.1.1",
"eslint-plugin-react": "^7.7.0",
"eslint-plugin-standard": "^2.0.0",
Expand All @@ -129,18 +132,18 @@
"holderjs": "^2.9.3",
"json-loader": "^0.5.4",
"raw-loader": "^0.5.1",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react": "^16.3.2",
"react-dom": "^16.3.2",
"react-helmet": "^5.0.3",
"react-prism": "^4.3.2",
"react-router": "^3.2.0",
"react-scripts": "^1.1.1",
"react-test-renderer": "^16.0.0",
"react-router": "^3.2.1",
"react-scripts": "^1.1.4",
"react-test-renderer": "^16.3.2",
"rollup": "^0.43.0",
"rollup-plugin-babel": "^2.7.1",
"rollup-plugin-babel-minify": "^3.1.2",
"rollup-plugin-commonjs": "^8.3.0",
"rollup-plugin-node-resolve": "^3.0.3",
"rollup-plugin-commonjs": "^8.4.1",
"rollup-plugin-node-resolve": "^3.3.0",
"rollup-plugin-replace": "^1.1.1",
"static-site-generator-webpack-plugin": "^2.0.1",
"style-loader": "^0.13.1",
Expand Down
9 changes: 0 additions & 9 deletions src/CustomCheckbox.js

This file was deleted.

51 changes: 0 additions & 51 deletions src/CustomCheckboxOrRadio.js

This file was deleted.

84 changes: 84 additions & 0 deletions src/CustomInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { mapToCssModules } from './utils';

const propTypes = {
className: PropTypes.string,
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
type: PropTypes.string.isRequired,
label: PropTypes.string,
inline: PropTypes.bool,
valid: PropTypes.bool,
invalid: PropTypes.bool,
bsSize: PropTypes.string,
cssModule: PropTypes.object,
children: PropTypes.oneOfType(PropTypes.node, PropTypes.array, PropTypes.func)
};

function CustomInput(props) {
const {
className,
label,
inline,
valid,
invalid,
cssModule,
children,
bsSize,
...attributes
} = props;

const type = attributes.type;

const customClass = mapToCssModules(classNames(
className,
`custom-${type}`,
bsSize ? `custom-${type}-${bsSize}` : false,
), cssModule);

const validationClassNames = mapToCssModules(classNames(
invalid && 'is-invalid',
valid && 'is-valid',
), cssModule);

if (type === 'select') {
return <select {...attributes} className={classNames(validationClassNames, customClass)}>{children}</select>;
}

if (type === 'file') {
return (
<div className={customClass}>
<input {...attributes} className={classNames(validationClassNames, mapToCssModules('custom-file-input', cssModule))} />
<label className={mapToCssModules('custom-file-label', cssModule)} htmlFor={attributes.id}>{label || 'Choose file'}</label>
</div>
);
}

if (type !== 'checkbox' && type !== 'radio') {
return <input {...attributes} className={classNames(validationClassNames, customClass)} />;
}

const wrapperClasses = classNames(
customClass,
mapToCssModules(classNames(
'custom-control',
{ 'custom-control-inline': inline }
), cssModule)
);

return (
<div className={wrapperClasses}>
<input
{...attributes}
className={classNames(validationClassNames, mapToCssModules('custom-control-input', cssModule))}
/>
<label className={mapToCssModules('custom-control-label', cssModule)} htmlFor={attributes.id}>{label}</label>
{children}
</div>
);
}

CustomInput.propTypes = propTypes;

export default CustomInput;
9 changes: 0 additions & 9 deletions src/CustomRadio.js

This file was deleted.

32 changes: 0 additions & 32 deletions src/__tests__/CustomCheckbox.spec.js

This file was deleted.

0 comments on commit ccdb7f2

Please sign in to comment.