Skip to content

Commit 46f0f13

Browse files
committed
feat: Add config props to element
1 parent a1a222d commit 46f0f13

File tree

4 files changed

+77
-17
lines changed

4 files changed

+77
-17
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"test": "jest"
2424
},
2525
"dependencies": {
26+
"prop-types": "^15.6.1",
2627
"react": "^16.4.0",
2728
"react-dom": "^16.4.0"
2829
}

src/ReactCui.js

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,56 @@
1-
import React, { Component } from 'react'
1+
import React, { Component, Fragment } from 'react'
2+
import PropTypes from 'prop-types'
23

3-
const embedUrl = 'https://typeform-labs.s3.amazonaws.com/cui/cui-embed.js'
4+
export const EMBED_URL = 'https://typeform-labs.s3.amazonaws.com/cui/cui-embed.js'
45

56
class Cui extends Component {
67
componentDidMount() {
7-
if (document) {
8+
if (document && !scriptTagExists({document})) {
89
const embedJs = document.createElement('script')
910
embedJs.type = 'text/javascript'
10-
embedJs.src = embedUrl
11+
embedJs.src = EMBED_URL
1112
embedJs.async = true
1213
document.getElementsByTagName('head')[0].appendChild(embedJs)
1314
}
1415
}
1516

1617
render() {
1718
const {
18-
uid
19+
uid,
20+
height,
21+
avatar,
22+
theme
1923
} = this.props
2024
return (
21-
<div key={`cui-${uid}`} className='cui-embed' data-cui-uid={uid}></div>
25+
<Fragment>
26+
{uid ? (
27+
<div
28+
key={`cui-${uid}`}
29+
className='cui-embed'
30+
data-cui-uid={uid}
31+
data-cui-height={height}
32+
data-cui-avatar={avatar}
33+
data-cui-theme={theme}
34+
/>
35+
) : null}
36+
</Fragment>
2237
)
2338
}
2439
}
2540

41+
Cui.propTypes = {
42+
uid: PropTypes.string.isRequired,
43+
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
44+
avatar: PropTypes.string,
45+
theme: PropTypes.string
46+
}
47+
2648
export default Cui
49+
50+
const scriptTagExists = ({document}) => {
51+
const scriptTags = document.getElementsByTagName('head')[0].childNodes
52+
const cuiEmbedScriptTags = [].filter.call(scriptTags, (script) => {
53+
return script.src === EMBED_URL
54+
})
55+
return !!cuiEmbedScriptTags.length
56+
}

src/ReactCui.test.js

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,48 @@
11
import React from 'react'
22
import { shallow, mount, configure } from 'enzyme'
33
import Adapter from 'enzyme-adapter-react-16'
4-
import Cui from './ReactCui'
4+
import Cui, { EMBED_URL } from './ReactCui'
55

66
configure({ adapter: new Adapter() })
7+
describe('<Cui />', () => {
78

8-
test('Component have required UID parameter', () => {
9-
const uid = 'abc123'
10-
const Component = mount(<Cui uid={uid} />)
11-
expect(Component.props().uid).toBe(uid)
12-
})
9+
test('Component have required UID parameter passed to render', () => {
10+
const uid = 'abc123'
11+
const Component = mount(<Cui uid={uid} />)
12+
expect(Component.render().attr('data-cui-uid')).toBe(uid)
13+
})
14+
15+
test('Component have optional parameters being passed to the DOM element', () => {
16+
const uid = 'abc123'
17+
const height = 500
18+
const avatar = 'https://avatar.com/profile.jpg'
19+
const theme = '#333'
20+
const Component = mount(<Cui uid={uid} height={height} avatar={avatar} theme={theme} />)
21+
const ComponentDOM = Component.render()
22+
23+
expect(ComponentDOM.attr('data-cui-height')).toBe(height.toString())
24+
expect(ComponentDOM.attr('data-cui-avatar')).toBe(avatar)
25+
expect(ComponentDOM.attr('data-cui-theme')).toBe(theme)
26+
})
27+
28+
test('Component should have the className `cui-embed` so the scripts loads the CUI inside', () => {
29+
const uid = 'abc123'
30+
const Component = shallow(<Cui uid={uid} />)
31+
32+
expect(Component.find('.cui-embed').length).toBe(1)
33+
})
34+
35+
test('Component should inject ONLY ONE script tag with the embed url', () => {
36+
37+
const Component = mount(<Cui uid={'123'} />)
38+
const scriptTags = document.getElementsByTagName('head')[0].childNodes
39+
let embedScriptTags = 0
40+
scriptTags.forEach(script => {
41+
if (script.src === EMBED_URL) embedScriptTags++
42+
})
43+
44+
expect(embedScriptTags).toBe(1)
1345

14-
test('Component should have the className `cui-embed`', () => {
15-
const uid = 'abc123'
16-
const Component = shallow(<Cui uid={uid} />)
46+
})
1747

18-
expect(Component.is('.cui-embed')).toBe(true)
1948
})

yarn.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3066,7 +3066,7 @@ promise@^7.1.1:
30663066
dependencies:
30673067
asap "~2.0.3"
30683068

3069-
prop-types@^15.6.0:
3069+
prop-types@^15.6.0, prop-types@^15.6.1:
30703070
version "15.6.1"
30713071
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
30723072
dependencies:

0 commit comments

Comments
 (0)