Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating an official octicons-react component #196

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/react/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build/
*.json
3 changes: 3 additions & 0 deletions lib/react/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": ["plugin:github/es6", "plugin:github/react"]
}
21 changes: 21 additions & 0 deletions lib/react/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2018 GitHub Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
94 changes: 94 additions & 0 deletions lib/react/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# GitHub Octicons React Component

[![npm version](https://img.shields.io/npm/v/%40github%2Focticons-react.svg)](https://www.npmjs.org/package/%40github%2Focticons-react)
[![Build Status](https://travis-ci.org/primer/octicons.svg?branch=master)](https://travis-ci.org/primer/octicons)

> A react component for installing octicons

## Install

```
$ npm install @github/octicons-react --save
```

## Usage

The entire library will be available when importing `@github/octicons-react`. Specifying the [icon you want to use][octicons], by supplying the `name=""` to the component.

```js
// Example usage
import Octicon from "@github/octicons-react"

return (
<Octicon name="beaker" />
)
```

### Alignment

By default the octicons have `vertical-align: text-bottom;` applied to them. But there are cases where you'll want to change the alignment. The props available are `top`, `middle`.

```js
// Example usage
import Octicon from "@github/octicons-react"

return (
<h1>
<Octicon name="repo" large middle /> github/github
</h1>
)
```


### ariaLabel

You have the option to add accessibility information to the icon using `aria-label`.

```js
// Example usage
import Octicon from "@github/octicons-react"

return (
<button>
<Octicon name="plus" ariaLabel="Add new item" /> New
</button>
)
```


### Sizes

The properties `large`, `medium`, `small` are available for setting the size of the icon.

| Prop | Rendered Size |
| :- | :- |
| Small | 16px height by `computed` width |
| Medium | 32px height by `computed` width |
| Large | 64px height by `computed` width |

```js
// Example usage
import Octicon from "@github/octicons-react"

return (
<h1>
<a href="https://github.com">
<Octicon name="logo-github" large ariaLabel="GitHub"/>
</a>
</h1>
)
```

## License

(c) GitHub, Inc.

When using the GitHub logos, be sure to follow the [GitHub logo guidelines](https://github.com/logos).

[MIT](./LICENSE)

[octicons]: https://octicons.github.com/
[primer]: https://github.com/primer/primer
[docs]: http://primercss.io/
[npm]: https://www.npmjs.com/
[install-npm]: https://docs.npmjs.com/getting-started/installing-node
72 changes: 72 additions & 0 deletions lib/react/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from "react";
import octicons from "octicons";

export default class Octicon extends React.Component {
prepareAttributes(octicon) {
const { ariaLabel, medium, large } = this.props;
const attr = Object.assign({}, octicon.options);
// Default octicon sizes to small
attr["height"] = 16;

// Delete class set by octicons library
delete attr["class"];

// Read in small, medium, large props
if (medium) {
attr["height"] = 32;
} else if (large) {
attr["height"] = 64;
}

// Calculate the width based on height
attr["width"] =
attr["height"] * octicon.options["width"] / octicon.options["height"];

// If the user passed in aria-label
if (ariaLabel) {
attr["aria-label"] = ariaLabel;
attr["role"] = "img";

// Un-hide the icon
delete attr["aria-hidden"];
}

return attr;
}

render() {
const { name } = this.props;
const octicon = octicons[name];

const alignment = props => {
const { top, middle } = props;

if (top) {
return "text-top";
} else if (middle) {
return "middle";
}
return "text-bottom";
};

if (octicon) {
const svgStyle = {
display: "inline-block",
fill: "currentColor",
verticalAlign: alignment(this.props),
userSelect: "none"
};

return (
<svg
{...this.prepareAttributes(octicon)}
style={svgStyle}
/* eslint-disable-next-line react/no-danger */
dangerouslySetInnerHTML={{ __html: octicon.path }}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be ideal to avoid dangerouslySetInnerHTML for performance reasons. When this component is marked as dirty, react will have to update the DOM using innerHTML rather than changing just the attribute that has changed.

https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3#3732

Since all the SVGs are static, we should be able to head of time generate the React.createElement tree builder calls.

/>
);
} else {
throw new Error(`No such octicon: "${name}"!`);
}
}
}
50 changes: 50 additions & 0 deletions lib/react/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"name": "@github/octicons-react",
"version": "1.1.0",
"description": "A scalable set of icons handcrafted with <3 by GitHub.",
"homepage": "https://octicons.github.com",
"author": "GitHub Inc.",
"license": "MIT",
"main": "build/index.js",
"repository": "https://github.com/primer/octicons.git",
"files": [
"index.js",
"build"
],
"scripts": {
"lint": "$(npm bin)/github-lint",
"build": "$(npm bin)/babel index.js -d build",
"prepare": "npm run build"
},
"bugs": {
"url": "https://github.com/primer/octicons/issues"
},
"keywords": [
"GitHub",
"icons",
"svg",
"octicons",
"react",
"primer"
],
"babel": {
"presets": [
"env",
"react"
]
},
"peerDependencies": {
"react": ">=16.2.0"
},
"dependencies": {
"octicons": "7.1.0",
"react": "^16.2.0"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"eslint": "^4.18.1",
"eslint-plugin-github": "^0.23.0"
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"private": true,
"scripts": {
"bootstrap": "lerna bootstrap",
"test": "ava tests/*.js && lerna run test",
"lint": "$(npm bin)/lerna exec npm run lint",
"test": "npm run lint && ava tests/*.js && lerna run test",
"precommit": "lint-staged",
"alpha-release": "script/clean && $(npm bin)/lerna publish --npm-tag=alpha --canary --exact --skip-git",
"release": "script/clean && $(npm bin)/lerna publish --exact --since \"v$(npm info octicons version)\""
Expand Down