diff --git a/.gitignore b/.gitignore
index bee7d76fc..c221276eb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,3 @@
-# Created by https://www.gitignore.io/api/node
-
-### Node ###
# Logs
logs
*.log
@@ -74,6 +71,3 @@ typings/
# Serverless directories
.serverless
-
-
-# End of https://www.gitignore.io/api/node
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..e7e82126a
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,81 @@
+# Contribution Guidelines
+
+**30 seconds of React** is a community effort, so feel free to contribute in any way you can. Every contribution helps!
+
+Here's what you can do to help:
+
+- Submit [pull requests](https://github.com/30-seconds/30-seconds-of-react/pulls) with snippets that you have created (see below for guidelines).
+- [Open issues](https://github.com/30-seconds/30-seconds-of-react/issues/new) for things you want to see added or modified.
+- Be part of the discussion by helping out with [existing issues](https://github.com/30-seconds/30-seconds-of-react/issues).
+- Fix typos in existing snippets, improve snippet descriptions and explanations or provide better examples.
+
+### Snippet submission and Pull request guidelines
+
+- **DO NOT MODIFY THE README.md or index.html FILES!** Make changes to individual snippet files. **Travis CI** will automatically build the `README.md` and `index.html` files when your pull request is merged.
+- **Snippet filenames** must correspond to the title of the snippet. For example, if your snippet is titled `### AwesomeComponent` the filename should be `AwesomeComponent.md`.
+ - Use `TitleCase`, not `camelCase`, `kebab-case` or `snake_case` when naming components.
+ - Avoid capitalization of words, except if the whole word is capitalized (e.g. `URL` should be capitalized in the filename and the snippet title).
+- **Snippet titles** should be the same as the name of the component that is present in the snippet.
+ - All snippet titles must be prefixed with `###` and be at the very first line of your snippet.
+ - Snippet titles must be unique (although if you cannot find a better title, just add some placeholder at the end of the filename and title and we will figure it out).
+ - Follow snippet titles with an empty line.
+- **Snippet descriptions** must be short and to the point. Try to explain *what* the snippet does and *how* the snippet works and what Javascript/React features are used. Remember to include what functions you are using and why.
+ - Follow snippet descriptions with an empty line.
+- **Snippet code** must be enclosed inside ` ```jsx ` and ` ``` `.
+ - If your snippet is accompanied by CSS code, enclose it inside ` ```css ` and ` ``` ` and present it before the JS/JSX code.
+ - Remember to start your snippet's code on a new line below the opening backticks.
+ - Use standard function notation to define your component. For example `function MyComponent(props) { ... }`.
+ - Do not write components using classes, use [React Hooks](https://reactjs.org/docs/hooks-intro.html) instead.
+ - Please use Javascript [Semi-Standard Style](https://github.com/Flet/semistandard).
+ - Try to keep your snippets' code short and to the point. Use modern techniques and features. Make sure to test your code before submitting.
+ - All snippets must be followed by one (more if necessary) test case after the code, in a new block enclosed inside ` ```jsx ` and ` ``` `. The syntax for this is `ReactDOM.render(
| ID | +Value | +
|---|---|
| {i} | +{val} | +
| ` element. +Use `Array.prototype.map` to render each object in the `filteredData` array as a ` | ||
|---|---|---|
` for each key in the object.
+
+```jsx
+function MappedTable({ data, propertyNames }) {
+ let filteredData = data.map(v =>
+ Object.keys(v)
+ .filter(k => propertyNames.includes(k))
+ .reduce((acc, key) => ((acc[key] = v[key]), acc), {})
+ );
+ return (
+
+
+
+Examples+ +```jsx +const people = [ + { name: 'John', surname: 'Smith', age: 42 }, + { name: 'Adam', surname: 'Smith', gender: 'male' } +]; +const propertyNames = ['name', 'surname', 'age']; +ReactDOM.render( +[⬆ Back to top](#table-of-contents) + + +## Input +### Input + +Renders an `` element that uses a callback function to pass its value to the parent component. + +Use object destructuring to set defaults for certain attributes of the `` element. +Render an `` element with the appropriate attributes and use the `callback` function in the `onChange` event to pass the value of the input to the parent. + +```jsx +function Input ({ callback, type = 'text', disabled = false, readOnly = false, placeholder = '' }) { + return ( + callback(value)} + /> + ); +} +``` + +
+
+
+Examples+ +```jsx +ReactDOM.render( + console.log(val)}/>, + document.getElementById('root') +); +``` +[⬆ Back to top](#table-of-contents) + +### LimitedTextarea + +Renders a textarea component with a character limit. + +Use the `React.useState()` hook to create the `content` state variable and set its value to `value`. +Create a method `setFormattedContent`, which trims the content of the input if it's longer than `limit`. +Use the `React.useEffect()` hook to call the `setFormattedContent` method on the value of the `content` state variable. +Use a` ` to wrap both the` |