Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/diegohaz/singel
Single Element Pattern
https://github.com/diegohaz/singel
cli linter react react-patterns reactjs
Last synced: about 1 month ago
JSON representation
Single Element Pattern
- Host: GitHub
- URL: https://github.com/diegohaz/singel
- Owner: diegohaz
- License: mit
- Created: 2018-06-01T00:45:45.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2022-12-08T18:54:12.000Z (about 2 years ago)
- Last Synced: 2024-10-26T02:34:07.296Z (about 2 months ago)
- Topics: cli, linter, react, react-patterns, reactjs
- Language: JavaScript
- Homepage: https://medium.freecodecamp.org/introducing-the-single-element-pattern-dfbd2c295c5d
- Size: 703 KB
- Stars: 408
- Watchers: 11
- Forks: 20
- Open Issues: 24
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome - singel - Single Element Pattern (JavaScript)
- awesome-list - singel
README
#
[![Generated with nod](https://img.shields.io/badge/generator-nod-2196F3.svg?style=flat-square)](https://github.com/diegohaz/nod)
[![NPM version](https://img.shields.io/npm/v/singel.svg?style=flat-square)](https://npmjs.org/package/singel)
[![Build Status](https://img.shields.io/travis/diegohaz/singel/master.svg?style=flat-square)](https://travis-ci.org/diegohaz/singel) [![Coverage Status](https://img.shields.io/codecov/c/github/diegohaz/singel/master.svg?style=flat-square)](https://codecov.io/gh/diegohaz/singel/branch/master)**Single Element Pattern** (Singel) is a set of rules/best practices to create consistent, reliable and maintainable components in React and other component-based libraries. This is based on the idea that the **building blocks** of an application should resemble as most as possible native HTML elements. [**Read full article**](https://medium.freecodecamp.org/introducing-the-single-element-pattern-dfbd2c295c5d)
This repo is a CLI tool for checking whether React components conform to the Singel pattern.
## Installation
```sh
$ npm i -g singel
```## Usage
```sh
$ singel path/to/**/Component.js --ignore "path/to/**/ignored/Component.js"
```## Projects applying Singel
> Feel free to send a PR adding your open source project
- [Reakit](https://github.com/diegohaz/reakit)
## Rules
### Render only one element
```jsx
// bad - 2 elements
const Element = props => (
);// good
const Element = props => (
);// good - if Element is good
const Element2 = props => (
);
```### Never break the app
```jsx
// good
const Element = props => (
);// bad - will break if getId wasn't provided
const Element = ({ getId, ...props }) => (
);// bad - will break if foo wasn't provided
const Element = ({ foo, ...props }) => (
);
```### Render all HTML attributes passed as props
```jsx
// good
const Element = props => (
);// bad - not rendering id
const Element = ({ id, ...props }) => (
);// good
const Element = ({ id, ...props }) => (
);
```### Always merge the styles passed as props
```jsx
// good
const Element = props => (
);// bad - not rendering className
const Element = ({ className, ...props }) => (
);// bad - not rendering style
const Element = ({ style, ...props }) => (
);// bad - replacing className instead of appending
const Element = props => (
);// bad - replacing style instead of merging
const Element = props => (
);// good
const Element = ({ className, ...props }) => (
);// good
const Element = ({ style, ...props }) => (
);
```### Add all the event handlers passed as props
```jsx
// good
const Element = props => (
);// bad - not passing onClick
const Element = ({ onClick, ...props }) => (
);// bad - replacing onClick prop
const Element = props => (
);// good
const Element = ({ onClick, ...props }) => (
);// good - it's ok to replace internal event handlers
const Element = props => (
);// good - calling internal and prop
const callAll = (...fns) => (...args) =>
fns.forEach(fn => fn && fn(...args));const Element = ({ onClick, ...props }) => (
);
```## FAQ
### How to handle nested elements?
Say you have a `Button` element and you want to display a `Tooltip` when it's hovered. The first rule you'll want to break is rendering only one element. To handle that you have some options:
- Use CSS pseudo-elements (such as `:after` and `:before`);
- Create a non-singel element, which is fine;
- Nest styles instead of components.Here's an example of how you can accomplish tha latter one:
```css
/* could also be CSS-in-JS */
.button {
position: relative;
/* more button css */
}.button:hover .tooltip {
display: block;
}.button .tooltip {
display: none;
position: absolute;
/* more tooltip css */
}
``````jsx
const Button = ({ className, ...props }) => (
);Button.Tooltip = ({ className, ...props }) => (
);
```Usage:
```jsx
😁
Hover me```
Both `Button` and `Button.Tooltip` are single elements. You have all the benefits you would have by nesting them, but now with complete control over `Button.Tooltip` from outside.
## License
MIT © [Diego Haz](https://github.com/diegohaz)