Skip to content

Commit

Permalink
Implemented the Icon component (formerly Sprite).
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesDonnelly committed Sep 11, 2018
1 parent c892c1a commit 5210340
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 1 deletion.
35 changes: 35 additions & 0 deletions src/components/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
<dt><a href="#module_[AFComponent]">[AFComponent]</a> : <code>js</code></dt>
<dd><p>The <code>&lt;AFComponent /&gt;</code> utility component wraps other components with themeing and localisation support.</p>
</dd>
<dt><a href="#module_[Icon]">[Icon]</a> : <code>components/common</code></dt>
<dd><p>The <code>&lt;Icon /&gt;</code> component renders an icon (image).
This component assumes the various icon spritesheets from <a href="https://api.apkallufalls.com">https://api.apkallufalls.com</a> have already been stored in localStorage (which happens when the app loads).</p>
</dd>
<dt><a href="#module_[Language]">[Language]</a> : <code>components/common</code></dt>
<dd><p>The <code>&lt;Language /&gt;</code> component displays language selection controls.</p>
</dd>
Expand Down Expand Up @@ -38,6 +42,37 @@ The `<AFComponent />` utility component wraps other components with themeing and
| --- | --- | --- |
| props.style | <code>Object</code> | Style rules to apply on the wrapped component. |

<a name="module_[Icon]"></a>

## [Icon] : <code>components/common</code>
The `<Icon />` component renders an icon (image).
This component assumes the various icon spritesheets from https://api.apkallufalls.com have already been stored in localStorage (which happens when the app loads).

**Properties**

| Name | Type | Description |
| --- | --- | --- |
| props.caption | <code>String</code> | The text to be displayed on hover (used within the rendered component's `title` attribute and `<figcaption>` element). |
| [props.iconId] | <code>number</code> | An icon ID used to generate the image URL. This is used to fetch the X and Y co-ordinates from the resource's spritesheet JSON. Necessary if `props.url` is not specified. |
| [props.resource] | <code>String</code> | The resource the icon belongs to. Used to fetch the spritesheet JSON for the icon. Can be one of the following: achievements, chocoboBardings, emotes, minions, mounts, orchestrionRolls or titles. Necessary if `props.url` is not specified. |
| [props.url] | <code>String</code> | A qualified image URL to use. Necessary if `props.iconId` is not specified. |

**Example**
```js
// This renders an icon with a qualified URL.
<Icon caption="Test" url="example.png" />
```
**Example**
```js
// This renders an icon from a content spritesheet.
<Icon caption="Test" iconId={4501} resource="minions" />
```
**Example**
```js
// This icon ID is invalid and there's no resource specified.
// This will return the Example Self emote as it looks like a generic 'not found' image.
<Icon caption="Test" iconId={9999} />
```
<a name="module_[Language]"></a>

## [Language] : <code>components/common</code>
Expand Down
82 changes: 82 additions & 0 deletions src/components/common/Icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* The `<Icon />` component renders an icon (image).
* This component assumes the various icon spritesheets from https://api.apkallufalls.com have already been stored in localStorage (which happens when the app loads).
* @module [{components/common}Icon]
* @prop {String} props.caption - The text to be displayed on hover (used within the rendered component's `title` attribute and `<figcaption>` element).
* @prop {number} [props.iconId] - An icon ID used to generate the image URL. This is used to fetch the X and Y co-ordinates from the resource's spritesheet JSON. Necessary if `props.url` is not specified.
* @prop {String} [props.resource] - The resource the icon belongs to. Used to fetch the spritesheet JSON for the icon. Can be one of the following: achievements, chocoboBardings, emotes, minions, mounts, orchestrionRolls or titles. Necessary if `props.url` is not specified.
* @prop {String} [props.url] - A qualified image URL to use. Necessary if `props.iconId` is not specified.
* @example
* // This renders an icon with a qualified URL.
* <Icon caption="Test" url="example.png" />
* @example
* // This renders an icon from a content spritesheet.
* <Icon caption="Test" iconId={4501} resource="minions" />
* @example
* // This icon ID is invalid and there's no resource specified.
* // This will return the Example Self emote as it looks like a generic 'not found' image.
* <Icon caption="Test" iconId={9999} />
*/
import React from "react";
import AFComponent from "components/AFComponent";

import style from "styles/common/Icon";

const Icon = ({
classes,
caption,
iconId,
resource,
url,
}) => {
let computedStyle;

if (url)
computedStyle = {
backgroundImage: `url(${url})`
};
else {
computedStyle = (() => {
const spritesheet = localStorage.getItem(`icons/${resource}`);

if (!spritesheet) {
console.warn(`Unable to locate spritesheet for resource "${resource}".`);
return {
backgroundImage: 'url(https://api.apkallufalls.com/icons/emote/64044.png)'
}
}

const iconPosition = spritesheet[iconId];

if (!iconPositions) {
console.warn(`Unable to find icon ID ${iconId} within spritesheet for resource "${resource}".`);
return {
backgroundImage: 'url(https://api.apkallufalls.com/icons/emote/64044.png)'
}
}

return {
backgroundImage: `url(https://api.apkallufalls.com/icons/${resource}.png)`,
backgroundPosition: `${iconPosition[0]}px ${iconPosition[1]}px`
}
})();
}

return (
<figure
className={classes.icon}
style={computedStyle}
title={caption}
>
<figcaption className={classes.caption}>
{caption}
</figcaption>
</figure>
);
}

export default (props) => (
<AFComponent style={style} {...props}>
<Icon />
</AFComponent>
)
10 changes: 9 additions & 1 deletion src/components/pages/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import AFComponent from "components/AFComponent";
import style from "styles/pages/Home";

// Components.
import Icon from "components/common/Icon";
import Panel from "components/common/Panel";
import Progress from "components/common/Progress";
import Popup from "components/common/Popup";

const Home = ({ classes, locale, localeInject }) => (
Expand Down Expand Up @@ -71,7 +73,13 @@ const Home = ({ classes, locale, localeInject }) => (
}
)
}} />
<Panel>Foobar</Panel>
<Panel>
<Progress caption="Example" value={4} total={7} />
<Icon caption="Example" url="https://api.apkallufalls.com/icons/item/10.png" />
<Icon caption="Example" iconId={4501} resource="minions" />
<Icon caption="Example 'no spritesheet found'" />
<Icon caption="Example 'unable to find icon'" resource="minions" />
</Panel>
</section>
);

Expand Down
17 changes: 17 additions & 0 deletions src/styles/common/Icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export default theme => ({
icon: {
background: {
position: 0,
repeat: 'no-repeat',
size: 'contain'
},
display: 'inline-block',
height: 40,
margin: 0,
width: 40
},
caption: {
fontSize: 0,
visibility: 'hidden'
}
});

0 comments on commit 5210340

Please sign in to comment.