From c0e886fdea299575991f8b604bde88c1bdb820bb Mon Sep 17 00:00:00 2001 From: Tobias Date: Thu, 24 Jan 2019 09:49:02 +0100 Subject: [PATCH] feat: make it possible to send in a "data:image" instead of a SVG - sizes are handles for dynamic usage as well --- .../__snapshots__/Button.test.js.snap | 3 +- .../components/icon-primary/IconPrimary.js | 8 ++-- .../dnb-ui-lib/src/components/icon/Icon.js | 48 +++++++++++++------ .../__tests__/__snapshots__/Icon.test.js.snap | 3 +- .../src/components/icon/style/_icon.scss | 3 +- .../__snapshots__/InputMasked.test.js.snap | 3 +- .../__snapshots__/Input.test.js.snap | 3 +- .../__snapshots__/Modal.test.js.snap | 3 +- 8 files changed, 50 insertions(+), 24 deletions(-) diff --git a/packages/dnb-ui-lib/src/components/button/__tests__/__snapshots__/Button.test.js.snap b/packages/dnb-ui-lib/src/components/button/__tests__/__snapshots__/Button.test.js.snap index f4e7d5a6a34..c528029ca72 100644 --- a/packages/dnb-ui-lib/src/components/button/__tests__/__snapshots__/Button.test.js.snap +++ b/packages/dnb-ui-lib/src/components/button/__tests__/__snapshots__/Button.test.js.snap @@ -575,7 +575,8 @@ exports[`Button scss have to match snapshot 1`] = ` .dnb-icon--custom-size { width: auto; height: auto; } - .dnb-icon svg:not([width]):not([height]) { + .dnb-icon svg:not([width]):not([height]), + .dnb-icon img:not([width]):not([height]) { width: inherit; height: inherit; } diff --git a/packages/dnb-ui-lib/src/components/icon-primary/IconPrimary.js b/packages/dnb-ui-lib/src/components/icon-primary/IconPrimary.js index 10f98d8912c..cab53712ef4 100644 --- a/packages/dnb-ui-lib/src/components/icon-primary/IconPrimary.js +++ b/packages/dnb-ui-lib/src/components/icon-primary/IconPrimary.js @@ -5,7 +5,7 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' -import DefaultIcon, { DefaultIconSize, loadSVG } from '../icon/Icon' +import DefaultIcon, { DefaultIconSize, prepareIcon } from '../icon/Icon' import * as primary_icons from '../../icons/primary_icons' import * as primary_icons_medium from '../../icons/primary_icons_medium' @@ -43,13 +43,13 @@ export default class IconPrimary extends PureComponent { this.props ) - const Svg = loadSVG(icon, size, icons) + const IconContainer = prepareIcon({ icon, size, listOfIcons: icons }) - if (!Svg) return <> + if (!IconContainer) return <> return ( - + ) } diff --git a/packages/dnb-ui-lib/src/components/icon/Icon.js b/packages/dnb-ui-lib/src/components/icon/Icon.js index 48cfd52c258..4472dd49f7c 100644 --- a/packages/dnb-ui-lib/src/components/icon/Icon.js +++ b/packages/dnb-ui-lib/src/components/icon/Icon.js @@ -92,11 +92,16 @@ export default class Icon extends PureComponent { } static getIconNameFromComponent(props) { - return typeof props.icon === 'string' - ? props.icon - : props.icon && + const name = + typeof props.icon === 'string' + ? props.icon + : props.icon && typeof props.icon === 'object' && (props.icon.displayName || props.icon.name) + if (/^data:image\//.test(name)) { + return null + } + return name } static calcSize(props) { @@ -224,7 +229,7 @@ export default class Icon extends PureComponent { const { color, modifier, - alt, + alt: _alt, title, class: _className, className, @@ -237,18 +242,23 @@ export default class Icon extends PureComponent { svgParams.color = color } + // get the alt + let alt = _alt || title + + if (!(alt && alt.length > 0)) { + alt = String(Icon.getIconNameFromComponent(props)).replace(/_/g, ' ') + } + // some wrapper params // also used for code markup simulation const wrapperParams = validateDOMAttributes(props, { role: 'img', + // as we use aria-label, we do not provide an alt as well + // alt, + ['aria-label']: alt, title }) - // get the alt - wrapperParams['aria-label'] = String( - alt || title || Icon.getIconNameFromComponent(props) - ).replace(/_/g, ' ') - if (area_hidden) { // wrapperParams['role'] = 'presentation' // almost the same as aria-hidden wrapperParams['aria-hidden'] = area_hidden @@ -264,30 +274,40 @@ export default class Icon extends PureComponent { return { ...props, icon, + alt, svgParams, wrapperParams } } render() { - const { icon, size, wrapperParams, svgParams } = Icon.prerender( + const { icon, size, wrapperParams, svgParams, alt } = Icon.prerender( this.props ) - const Svg = loadSVG(icon, size) + const IconContainer = prepareIcon({ icon, size, alt }) // make sure we return an empty span if we dont could get the icon - if (!Svg) return + if (!IconContainer) return <> return ( - + ) } } -export const loadSVG = (icon, size = null, listOfIcons = null) => { +export const prepareIcon = ({ + icon, + size = null, + listOfIcons = null, + alt = null +} = {}) => { + if (typeof icon === 'string' && /^data:image\//.test(icon)) { + return () => {alt + } + if (typeof icon === 'function') { const elem = icon() if (React.isValidElement(elem)) { diff --git a/packages/dnb-ui-lib/src/components/icon/__tests__/__snapshots__/Icon.test.js.snap b/packages/dnb-ui-lib/src/components/icon/__tests__/__snapshots__/Icon.test.js.snap index f4d73a7a319..613bb183c9a 100644 --- a/packages/dnb-ui-lib/src/components/icon/__tests__/__snapshots__/Icon.test.js.snap +++ b/packages/dnb-ui-lib/src/components/icon/__tests__/__snapshots__/Icon.test.js.snap @@ -208,7 +208,8 @@ exports[`Icon scss have to match snapshot 1`] = ` .dnb-icon--custom-size { width: auto; height: auto; } - .dnb-icon svg:not([width]):not([height]) { + .dnb-icon svg:not([width]):not([height]), + .dnb-icon img:not([width]):not([height]) { width: inherit; height: inherit; } " diff --git a/packages/dnb-ui-lib/src/components/icon/style/_icon.scss b/packages/dnb-ui-lib/src/components/icon/style/_icon.scss index 19ed94db9b0..e6048a2191e 100644 --- a/packages/dnb-ui-lib/src/components/icon/style/_icon.scss +++ b/packages/dnb-ui-lib/src/components/icon/style/_icon.scss @@ -37,7 +37,8 @@ height: auto; // only to feed the svg } - svg:not([width]):not([height]) { + svg:not([width]):not([height]), + img:not([width]):not([height]) { width: inherit; height: inherit; } diff --git a/packages/dnb-ui-lib/src/components/input-masked/__tests__/__snapshots__/InputMasked.test.js.snap b/packages/dnb-ui-lib/src/components/input-masked/__tests__/__snapshots__/InputMasked.test.js.snap index caf1c2291d8..71d343e5e3a 100644 --- a/packages/dnb-ui-lib/src/components/input-masked/__tests__/__snapshots__/InputMasked.test.js.snap +++ b/packages/dnb-ui-lib/src/components/input-masked/__tests__/__snapshots__/InputMasked.test.js.snap @@ -201,7 +201,8 @@ exports[`InputMasked scss have to match snapshot 1`] = ` .dnb-icon--custom-size { width: auto; height: auto; } - .dnb-icon svg:not([width]):not([height]) { + .dnb-icon svg:not([width]):not([height]), + .dnb-icon img:not([width]):not([height]) { width: inherit; height: inherit; } diff --git a/packages/dnb-ui-lib/src/components/input/__tests__/__snapshots__/Input.test.js.snap b/packages/dnb-ui-lib/src/components/input/__tests__/__snapshots__/Input.test.js.snap index 19595284e2a..3c4074a5286 100644 --- a/packages/dnb-ui-lib/src/components/input/__tests__/__snapshots__/Input.test.js.snap +++ b/packages/dnb-ui-lib/src/components/input/__tests__/__snapshots__/Input.test.js.snap @@ -387,7 +387,8 @@ exports[`Input scss have to match snapshot 1`] = ` .dnb-icon--custom-size { width: auto; height: auto; } - .dnb-icon svg:not([width]):not([height]) { + .dnb-icon svg:not([width]):not([height]), + .dnb-icon img:not([width]):not([height]) { width: inherit; height: inherit; } diff --git a/packages/dnb-ui-lib/src/components/modal/__tests__/__snapshots__/Modal.test.js.snap b/packages/dnb-ui-lib/src/components/modal/__tests__/__snapshots__/Modal.test.js.snap index 95a97934a03..c28db7af43d 100644 --- a/packages/dnb-ui-lib/src/components/modal/__tests__/__snapshots__/Modal.test.js.snap +++ b/packages/dnb-ui-lib/src/components/modal/__tests__/__snapshots__/Modal.test.js.snap @@ -584,7 +584,8 @@ exports[`Modal scss have to match snapshot 1`] = ` .dnb-icon--custom-size { width: auto; height: auto; } - .dnb-icon svg:not([width]):not([height]) { + .dnb-icon svg:not([width]):not([height]), + .dnb-icon img:not([width]):not([height]) { width: inherit; height: inherit; }