Skip to content

Commit

Permalink
feat(image): allow component to render svg string
Browse files Browse the repository at this point in the history
  • Loading branch information
unix committed Jan 30, 2022
1 parent a32f585 commit 2ece822
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 17 deletions.
12 changes: 6 additions & 6 deletions components/image/__tests__/__snapshots__/browser.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3042,7 +3042,7 @@ LoadedCheerio {
width: auto;
height: auto;
object-fit: scale-down;
display: block;
display: inline-block;
}
",
"next": null,
Expand Down Expand Up @@ -3091,7 +3091,7 @@ LoadedCheerio {
width: auto;
height: auto;
object-fit: scale-down;
display: block;
display: inline-block;
}
",
"next": null,
Expand Down Expand Up @@ -3265,7 +3265,7 @@ LoadedCheerio {
width: auto;
height: auto;
object-fit: scale-down;
display: block;
display: inline-block;
}
",
"next": null,
Expand Down Expand Up @@ -3314,7 +3314,7 @@ LoadedCheerio {
width: auto;
height: auto;
object-fit: scale-down;
display: block;
display: inline-block;
}
",
"next": null,
Expand Down Expand Up @@ -6572,7 +6572,7 @@ LoadedCheerio {
width: auto;
height: auto;
object-fit: scale-down;
display: block;
display: inline-block;
}
",
"next": null,
Expand Down Expand Up @@ -6621,7 +6621,7 @@ LoadedCheerio {
width: auto;
height: auto;
object-fit: scale-down;
display: block;
display: inline-block;
}
",
"next": null,
Expand Down
6 changes: 6 additions & 0 deletions components/image/__tests__/__snapshots__/index.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ exports[`Image should render correctly 1`] = `ReactWrapper {}`;
exports[`Image should render correctly 2`] = `ReactWrapper {}`;

exports[`Image should render correctly 3`] = `ReactWrapper {}`;

exports[`Image should render correctly with svg string 1`] = `ReactWrapper {}`;

exports[`Image should render correctly with svg string 2`] = `ReactWrapper {}`;

exports[`Image should render correctly with svg string 3`] = `ReactWrapper {}`;
19 changes: 19 additions & 0 deletions components/image/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const url =
'AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO' +
'9TXL0Y4OHwAAAABJRU5ErkJggg=='

const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="15px" height="15px" viewBox="0 0 15 15" fill="none">
<path d="M12.5 8V7.83333C12.5 7.09695 11.903 6.5 11.1667 6.5H10C9.17157 6.5 8.5 7.17157 8.5 8C8.5 8.82843 9.17157 9.5 10 9.5H11C11.8284 9.5 12.5 10.1716 12.5 11C12.5 11.8284 11.8284 12.5 11 12.5H10C9.17157 12.5 8.5 11.8284 8.5 11M8 6.5H3M5.5 6.5V13M0.5 0.5H14.5V14.5H0.5V0.5Z" stroke="black"/></svg>`

describe('Image', () => {
it('should render correctly', async () => {
let wrapper = mount(<Image src={url} />)
Expand All @@ -25,6 +28,22 @@ describe('Image', () => {
expect(() => wrapper.unmount()).not.toThrow()
})

it('should render correctly with svg string', () => {
let wrapper = mount(<Image src={svg} />)
expect(wrapper).toMatchSnapshot()
expect(() => wrapper.unmount()).not.toThrow()

wrapper = mount(<Image src={svg} width={20} height={20} />)
wrapper.find('img').at(0).simulate('load')
expect(wrapper).toMatchSnapshot()
expect(() => wrapper.unmount()).not.toThrow()

wrapper = mount(<Image src={svg} width={20} height={20} disableSkeleton />)
wrapper.find('img').at(0).simulate('load')
expect(wrapper).toMatchSnapshot()
expect(() => wrapper.unmount()).not.toThrow()
})

it('should work correctly with skeleton', async () => {
let wrapper = mount(<Image src={url} width={20} height={20} />)
expect(wrapper.find('.skeleton').length).not.toBe(0)
Expand Down
15 changes: 15 additions & 0 deletions components/image/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const transformDataSource = (src: string) => {
const left = `${src}`.slice(0, 4)
if (encodeURIComponent(left) === '%3Csvg') {
return `data:image/svg+xml;utf8,${src}`
}
return src
}

export const getHostFromUrl = (url: string) => {
try {
return new URL(url).host
} catch (e) {
return url
}
}
9 changes: 1 addition & 8 deletions components/image/image-browser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Props as LinkProps } from '../link/link'
import useTheme from '../use-theme'
import ImageBrowserHttpsIcon from './image-browser-https-icon'
import { getBrowserColors, BrowserColors } from './styles'
import { getHostFromUrl } from './helpers'
import useScaleable, { withPureProps, withScaleable } from '../use-scaleable'

export type ImageAnchorProps = Omit<React.AnchorHTMLAttributes<any>, keyof LinkProps>
Expand All @@ -27,14 +28,6 @@ const defaultProps = {
type NativeAttrs = Omit<React.HTMLAttributes<any>, keyof Props>
export type ImageBrowserProps = Props & NativeAttrs

const getHostFromUrl = (url: string) => {
try {
return new URL(url).host
} catch (e) {
return url
}
}

const getTitle = (title: string, colors: BrowserColors) => (
<div className="title">
{title}
Expand Down
8 changes: 5 additions & 3 deletions components/image/image.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useRef, useState } from 'react'
import React, { useEffect, useMemo, useRef, useState } from 'react'
import useTheme from '../use-theme'
import ImageSkeleton from './image.skeleton'
import { transformDataSource } from './helpers'
import useScaleable, { withPureProps, withScaleable } from '../use-scaleable'

interface Props {
Expand Down Expand Up @@ -35,6 +36,7 @@ const ImageComponent: React.FC<ImageProps> = ({
const [loading, setLoading] = useState<boolean>(true)
const [showSkeleton, setShowSkeleton] = useState<boolean>(true)
const imageRef = useRef<HTMLImageElement>(null)
const url = useMemo(() => transformDataSource(src), [src])

const imageLoaded = () => {
if (!showAnimation) return
Expand Down Expand Up @@ -63,7 +65,7 @@ const ImageComponent: React.FC<ImageProps> = ({
return (
<div className={`image ${className}`}>
{showSkeleton && showAnimation && <ImageSkeleton opacity={loading ? 0.5 : 0} />}
<img ref={imageRef} onLoad={imageLoaded} src={src} {...withPureProps(props)} />
<img ref={imageRef} onLoad={imageLoaded} src={url} {...withPureProps(props)} />
<style jsx>{`
.image {
position: relative;
Expand All @@ -81,7 +83,7 @@ const ImageComponent: React.FC<ImageProps> = ({
width: ${SCALES.width(1, 'auto')};
height: ${SCALES.height(1, 'auto')};
object-fit: scale-down;
display: block;
display: inline-block;
}
`}</style>
</div>
Expand Down

0 comments on commit 2ece822

Please sign in to comment.