diff --git a/docs/app/Examples/elements/Image/Usage/ImageExampleImageProps.js b/docs/app/Examples/elements/Image/Usage/ImageExampleImageProps.js
new file mode 100644
index 0000000000..7da3c4b3ba
--- /dev/null
+++ b/docs/app/Examples/elements/Image/Usage/ImageExampleImageProps.js
@@ -0,0 +1,13 @@
+import React from 'react'
+import { Image } from 'semantic-ui-react'
+
+const ImageExampleImageProps = () => (
+
+)
+
+export default ImageExampleImageProps
diff --git a/docs/app/Examples/elements/Image/Usage/ImageExampleWrappedImageProps.js b/docs/app/Examples/elements/Image/Usage/ImageExampleWrappedImageProps.js
new file mode 100644
index 0000000000..ef6d07a93a
--- /dev/null
+++ b/docs/app/Examples/elements/Image/Usage/ImageExampleWrappedImageProps.js
@@ -0,0 +1,14 @@
+import React from 'react'
+import { Image } from 'semantic-ui-react'
+
+const ImageExampleWrappedImageProps = () => (
+
+)
+
+export default ImageExampleWrappedImageProps
diff --git a/docs/app/Examples/elements/Image/Usage/index.js b/docs/app/Examples/elements/Image/Usage/index.js
index a328b48891..94f0e448ab 100644
--- a/docs/app/Examples/elements/Image/Usage/index.js
+++ b/docs/app/Examples/elements/Image/Usage/index.js
@@ -1,4 +1,5 @@
import React from 'react'
+
import ComponentExample from 'docs/app/Components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/app/Components/ComponentDoc/ExampleSection'
@@ -9,6 +10,15 @@ const ImageUsageExamples = () => (
description='An image can render children.'
examplePath='elements/Image/Usage/ImageExampleChildren'
/>
+ An image correctly handles props of an HTML img
.}
+ examplePath='elements/Image/Usage/ImageExampleImageProps'
+ />
+
)
diff --git a/src/elements/Image/Image.d.ts b/src/elements/Image/Image.d.ts
index 85af9ced07..c88046891f 100644
--- a/src/elements/Image/Image.d.ts
+++ b/src/elements/Image/Image.d.ts
@@ -18,9 +18,6 @@ export interface ImageProps {
/** An element type to render as (string or function). */
as?: any;
- /** Alternate text for the image specified. */
- alt?: string;
-
/** An image may be formatted to appear inline with text as an avatar. */
avatar?: boolean;
@@ -54,9 +51,6 @@ export interface ImageProps {
/** An image can take up the width of its container. */
fluid?: boolean;
- /** The img element height attribute. */
- height?: string | number;
-
/** An image can be hidden. */
hidden?: boolean;
@@ -76,10 +70,7 @@ export interface ImageProps {
size?: SemanticSIZES;
/** An image can specify that it needs an additional spacing to separate it from nearby content. */
- spaced?: boolean|'left'|'right';
-
- /** Specifies the URL of the image. */
- src?: string;
+ spaced?: boolean | 'left' | 'right';
/** Whether or not to add the ui className. */
ui?: boolean;
@@ -87,9 +78,6 @@ export interface ImageProps {
/** An image can specify its vertical alignment. */
verticalAlign?: SemanticVERTICALALIGNMENTS;
- /** The img element width attribute. */
- width?: string | number;
-
/** An image can render wrapped in a `div.ui.image` as alternative HTML markup. */
wrapped?: boolean;
}
diff --git a/src/elements/Image/Image.js b/src/elements/Image/Image.js
index 686a093e20..8611cd25c6 100644
--- a/src/elements/Image/Image.js
+++ b/src/elements/Image/Image.js
@@ -10,6 +10,7 @@ import {
getElementType,
getUnhandledProps,
META,
+ partitionHTMLProps,
SUI,
useKeyOnly,
useKeyOrValueAndKey,
@@ -18,16 +19,16 @@ import {
} from '../../lib'
import Dimmer from '../../modules/Dimmer'
import Label from '../Label/Label'
-
import ImageGroup from './ImageGroup'
+const imageProps = ['alt', 'height', 'src', 'srcSet', 'width']
+
/**
* An image is a graphic representation of something.
* @see Icon
*/
function Image(props) {
const {
- alt,
avatar,
bordered,
centered,
@@ -39,7 +40,6 @@ function Image(props) {
disabled,
floated,
fluid,
- height,
hidden,
href,
inline,
@@ -47,9 +47,7 @@ function Image(props) {
rounded,
size,
spaced,
- src,
verticalAlign,
- width,
wrapped,
ui,
} = props
@@ -73,6 +71,7 @@ function Image(props) {
className,
)
const rest = getUnhandledProps(Image, props)
+ const [imgTagProps, rootProps] = partitionHTMLProps(rest, { htmlProps: imageProps })
const ElementType = getElementType(Image, props, () => {
if (!_.isNil(dimmer) || !_.isNil(label) || !_.isNil(wrapped) || !childrenUtils.isNil(children)) return 'div'
})
@@ -84,13 +83,9 @@ function Image(props) {
return {content}
}
- const rootProps = { ...rest, className: classes }
- const imgTagProps = { alt, src, height, width }
-
- if (ElementType === 'img') return
-
+ if (ElementType === 'img') return
return (
-
+
{Dimmer.create(dimmer)}
{Label.create(label)}
@@ -109,9 +104,6 @@ Image.propTypes = {
/** An element type to render as (string or function). */
as: customPropTypes.as,
- /** Alternate text for the image specified. */
- alt: PropTypes.string,
-
/** An image may be formatted to appear inline with text as an avatar. */
avatar: PropTypes.bool,
@@ -148,12 +140,6 @@ Image.propTypes = {
customPropTypes.disallow(['size']),
]),
- /** The img element height attribute. */
- height: PropTypes.oneOfType([
- PropTypes.number,
- PropTypes.string,
- ]),
-
/** An image can be hidden. */
hidden: PropTypes.bool,
@@ -178,21 +164,12 @@ Image.propTypes = {
PropTypes.oneOf(['left', 'right']),
]),
- /** Specifies the URL of the image. */
- src: PropTypes.string,
-
/** Whether or not to add the ui className. */
ui: PropTypes.bool,
/** An image can specify its vertical alignment. */
verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS),
- /** The img element width attribute. */
- width: PropTypes.oneOfType([
- PropTypes.string,
- PropTypes.number,
- ]),
-
/** An image can render wrapped in a `div.ui.image` as alternative HTML markup. */
wrapped: PropTypes.bool,
}
diff --git a/src/elements/Input/Input.js b/src/elements/Input/Input.js
index b71b71dbaf..e4c5a4cb1c 100644
--- a/src/elements/Input/Input.js
+++ b/src/elements/Input/Input.js
@@ -11,7 +11,7 @@ import {
getElementType,
getUnhandledProps,
META,
- partitionHTMLInputProps,
+ partitionHTMLProps,
SUI,
useKeyOnly,
useValueAndKey,
@@ -154,7 +154,7 @@ class Input extends Component {
const tabIndex = this.computeTabIndex()
const unhandled = getUnhandledProps(Input, this.props)
- const [htmlInputProps, rest] = partitionHTMLInputProps(unhandled)
+ const [htmlInputProps, rest] = partitionHTMLProps(unhandled)
return [{
...htmlInputProps,
diff --git a/src/lib/htmlInputPropsUtils.js b/src/lib/htmlPropsUtils.js
similarity index 96%
rename from src/lib/htmlInputPropsUtils.js
rename to src/lib/htmlPropsUtils.js
index c5f07ce06a..ad86c86ab4 100644
--- a/src/lib/htmlInputPropsUtils.js
+++ b/src/lib/htmlPropsUtils.js
@@ -43,7 +43,7 @@ export const htmlInputProps = [...htmlInputAttrs, ...htmlInputEvents]
* @param {boolean} [options.includeAria] Includes all input props that starts with "aria-"
* @returns {[{}, {}]} An array of objects
*/
-export const partitionHTMLInputProps = (props, options = {}) => {
+export const partitionHTMLProps = (props, options = {}) => {
const {
htmlProps = htmlInputProps,
includeAria = true,
diff --git a/src/lib/index.js b/src/lib/index.js
index 5601f842e3..f6f506a619 100644
--- a/src/lib/index.js
+++ b/src/lib/index.js
@@ -29,8 +29,8 @@ export {
htmlInputAttrs,
htmlInputEvents,
htmlInputProps,
- partitionHTMLInputProps,
-} from './htmlInputPropsUtils'
+ partitionHTMLProps,
+} from './htmlPropsUtils'
export { default as isBrowser } from './isBrowser'
export { default as leven } from './leven'
diff --git a/src/modules/Checkbox/Checkbox.js b/src/modules/Checkbox/Checkbox.js
index a303960e7c..2d37e214b2 100644
--- a/src/modules/Checkbox/Checkbox.js
+++ b/src/modules/Checkbox/Checkbox.js
@@ -12,7 +12,7 @@ import {
htmlInputAttrs,
makeDebugger,
META,
- partitionHTMLInputProps,
+ partitionHTMLProps,
useKeyOnly,
} from '../../lib'
@@ -217,7 +217,7 @@ export default class Checkbox extends Component {
)
const unhandled = getUnhandledProps(Checkbox, this.props)
const ElementType = getElementType(Checkbox, this.props)
- const [htmlInputProps, rest] = partitionHTMLInputProps(unhandled, { htmlProps: htmlInputAttrs })
+ const [htmlInputProps, rest] = partitionHTMLProps(unhandled, { htmlProps: htmlInputAttrs })
const id = _.get(htmlInputProps, 'id')
return (
diff --git a/src/modules/Search/Search.js b/src/modules/Search/Search.js
index 5c2f3de66e..d7f5fc1420 100644
--- a/src/modules/Search/Search.js
+++ b/src/modules/Search/Search.js
@@ -15,7 +15,7 @@ import {
makeDebugger,
META,
objectDiff,
- partitionHTMLInputProps,
+ partitionHTMLProps,
shallowEqual,
SUI,
useKeyOnly,
@@ -643,7 +643,7 @@ export default class Search extends Component {
)
const unhandled = getUnhandledProps(Search, this.props)
const ElementType = getElementType(Search, this.props)
- const [htmlInputProps, rest] = partitionHTMLInputProps(unhandled, {
+ const [htmlInputProps, rest] = partitionHTMLProps(unhandled, {
htmlProps: htmlInputAttrs,
})
diff --git a/test/specs/elements/Image/Image-test.js b/test/specs/elements/Image/Image-test.js
index 14c2cfc200..163bb76ce9 100644
--- a/test/specs/elements/Image/Image-test.js
+++ b/test/specs/elements/Image/Image-test.js
@@ -38,10 +38,12 @@ describe('Image', () => {
common.propValueOnlyToClassName(Image, 'size', SUI.SIZES)
- it('renders an img tag', () => {
- shallow()
- .type()
- .should.equal('img')
+ describe('as', () => {
+ it('renders an img tag', () => {
+ shallow()
+ .type()
+ .should.equal('img')
+ })
})
describe('href', () => {
@@ -52,6 +54,23 @@ describe('Image', () => {
})
})
+ describe('image props', () => {
+ _.forEach(['alt', 'height', 'src', 'srcSet', 'width'], (propName) => {
+ it(`keeps "${propName}" on root element by default`, () => {
+ const wrapper = shallow()
+
+ wrapper.should.have.tagName('img')
+ wrapper.should.have.prop(propName, 'foo')
+ })
+
+ it(`passes "${propName}" to the img tag when wrapped`, () => {
+ shallow()
+ .find('img')
+ .should.have.prop(propName, 'foo')
+ })
+ })
+ })
+
describe('ui', () => {
it('is true by default', () => {
Image.defaultProps.should.have.any.keys('ui')
@@ -68,14 +87,10 @@ describe('Image', () => {
})
describe('wrapped', () => {
- it('applies all img attribute props to the img tag', () => {
- const props = { src: 'http://g.co', alt: 'alt text', width: 10, height: '10' }
- const img = shallow()
- .find('img')
-
- _.each(props, (val, key) => {
- img.should.have.prop(key, val)
- })
+ it('renders an div tag when true', () => {
+ shallow()
+ .type()
+ .should.equal('div')
})
})
})
diff --git a/test/specs/lib/htmlInputPropsUtils-test.js b/test/specs/lib/htmlInputPropsUtils-test.js
index 82e93b9826..f60d11e2fe 100644
--- a/test/specs/lib/htmlInputPropsUtils-test.js
+++ b/test/specs/lib/htmlInputPropsUtils-test.js
@@ -1,4 +1,4 @@
-import { partitionHTMLInputProps } from 'src/lib/htmlInputPropsUtils'
+import { partitionHTMLProps } from 'src/lib/htmlPropsUtils'
const props = {
autoFocus: false,
@@ -7,15 +7,15 @@ const props = {
required: true,
}
-describe('partitionHTMLInputProps', () => {
+describe('partitionHTMLProps', () => {
it('should return two arrays with objects', () => {
- partitionHTMLInputProps(props).should.have.lengthOf(2)
+ partitionHTMLProps(props).should.have.lengthOf(2)
})
it('should split props by definition', () => {
- const [htmlInputProps, rest] = partitionHTMLInputProps(props)
+ const [htmlProps, rest] = partitionHTMLProps(props)
- htmlInputProps.should.deep.equal({
+ htmlProps.should.deep.equal({
autoFocus: false,
placeholder: 'baz',
required: true,
@@ -24,24 +24,24 @@ describe('partitionHTMLInputProps', () => {
})
it('should split props by own definition', () => {
- const [htmlInputProps, rest] = partitionHTMLInputProps(props, {
+ const [htmlProps, rest] = partitionHTMLProps(props, {
htmlProps: ['placeholder', 'required'],
})
- htmlInputProps.should.deep.equal({ placeholder: 'baz', required: true })
+ htmlProps.should.deep.equal({ placeholder: 'baz', required: true })
rest.should.deep.equal({ autoFocus: false, className: 'foo' })
})
describe('aria', () => {
it('split aria props by default to htmlProps', () => {
- const [htmlInputProps, rest] = partitionHTMLInputProps({
+ const [htmlProps, rest] = partitionHTMLProps({
'aria-atomic': false,
'aria-busy': true,
className: 'foo',
role: 'bar',
})
- htmlInputProps.should.deep.equal({
+ htmlProps.should.deep.equal({
'aria-atomic': false,
'aria-busy': true,
role: 'bar',
@@ -50,14 +50,14 @@ describe('partitionHTMLInputProps', () => {
})
it('split aria props by default to rest when disabled', () => {
- const [htmlInputProps, rest] = partitionHTMLInputProps({
+ const [htmlProps, rest] = partitionHTMLProps({
'aria-atomic': false,
'aria-busy': true,
className: 'foo',
role: 'bar',
}, { includeAria: false })
- htmlInputProps.should.deep.equal({})
+ htmlProps.should.deep.equal({})
rest.should.deep.equal({
'aria-atomic': false,
'aria-busy': true,