Unverified Commit 87c31b3c authored by Robert Knight's avatar Robert Knight Committed by GitHub

Merge pull request #1038 from hypothesis/react-svg-icon

Convert `<svg-icon>` component to React
parents 5eaea90d e5728d69
'use strict'; 'use strict';
/** const { createElement } = require('preact');
* The <svg-icon> component renders SVG icons using inline <svg> tags, const propTypes = require('prop-types');
* enabling their appearance to be customized via CSS.
*
* This matches the way we do icons on the website, see
* https://github.com/hypothesis/h/pull/3675
*/
// The list of supported icons // The list of supported icons
const icons = { const icons = {
...@@ -14,21 +9,24 @@ const icons = { ...@@ -14,21 +9,24 @@ const icons = {
cursor: require('../../images/icons/cursor.svg'), cursor: require('../../images/icons/cursor.svg'),
}; };
// @ngInject /**
function SvgIconController($element) { * Component that renders icons using inline `<svg>` elements.
this.$onInit = () => { * This enables their appearance to be customized via CSS.
if (!icons[this.name]) { *
throw new Error('Unknown icon: ' + this.name); * This matches the way we do icons on the website, see
* https://github.com/hypothesis/h/pull/3675
*/
function SvgIcon({ name }) {
if (!icons[name]) {
throw new Error(`Unknown icon ${name}`);
} }
$element[0].innerHTML = icons[this.name]; const markup = { __html: icons[name] };
}; return <span dangerouslySetInnerHTML={markup} />;
} }
module.exports = { SvgIcon.propTypes = {
controllerAs: 'vm',
controller: SvgIconController,
bindings: {
/** The name of the icon to load. */ /** The name of the icon to load. */
name: '<', name: propTypes.string,
},
}; };
module.exports = SvgIcon;
'use strict'; 'use strict';
const angular = require('angular'); const { createElement, render } = require('preact');
const util = require('../../directive/test/util'); const SvgIcon = require('../svg-icon');
describe('svgIcon', function() { describe('SvgIcon', () => {
before(function() { // Tests here use DOM APIs rather than Enzyme because SvgIcon uses
angular.module('app', []).component('svgIcon', require('../svg-icon')); // `dangerouslySetInnerHTML` for its content, and that is not visible in the
}); // Enzyme tree.
beforeEach(function() {
angular.mock.module('app');
});
it("sets the element's content to the content of the SVG", function() { it("sets the element's content to the content of the SVG", () => {
const el = util.createDirective(document, 'svgIcon', { name: 'refresh' }); const container = document.createElement('div');
assert.ok(el[0].querySelector('svg')); render(<SvgIcon name="refresh" />, container);
assert.ok(container.querySelector('svg'));
}); });
it('throws an error if the icon is unknown', function() { it('throws an error if the icon is unknown', () => {
assert.throws(function() { assert.throws(() => {
util.createDirective(document, 'svgIcon', { name: 'unknown' }); const container = document.createElement('div');
render(<SvgIcon name="unknown" />, container);
}); });
}); });
}); });
...@@ -185,7 +185,7 @@ function startAngularApp(config) { ...@@ -185,7 +185,7 @@ function startAngularApp(config) {
.component('sortDropdown', require('./components/sort-dropdown')) .component('sortDropdown', require('./components/sort-dropdown'))
.component('spinner', require('./components/spinner')) .component('spinner', require('./components/spinner'))
.component('streamContent', require('./components/stream-content')) .component('streamContent', require('./components/stream-content'))
.component('svgIcon', require('./components/svg-icon')) .component('svgIcon', wrapReactComponent(require('./components/svg-icon')))
.component('tagEditor', require('./components/tag-editor')) .component('tagEditor', require('./components/tag-editor'))
.component('threadList', require('./components/thread-list')) .component('threadList', require('./components/thread-list'))
.component('timestamp', require('./components/timestamp')) .component('timestamp', require('./components/timestamp'))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment