Skip to content

Commit

Permalink
Merge pull request #99 from Typeform/dist512
Browse files Browse the repository at this point in the history
feat(DIST-512): Add "size" option for "popup" embed mode
  • Loading branch information
Matej Lednicky authored Nov 16, 2020
2 parents c90fcc6 + dc8b919 commit 991e6bd
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 44 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ typeformEmbed.makePopup(url, options)
| ❌ drawerWidth | Specify the width of the drawer (only applies if using `mode` `"drawer_left"` or `"drawer_right"`). | `Number` (pixels) | |
| width | Specify the width of the drawer or popup (only applies if using `mode` `"drawer_left"` or `"drawer_right"` or `"popover"` or `"side_panel"`). | `Number` (pixels) | 800 for `"drawer_left"` and `"drawer_right"` <br/> 320 for `"popover"` |
| height | Specify the height of the popup (only applies if using `mode` `"popover"` or `"side_panel"`). | `Number` (pixels) | 500 |
| size | Specify the size of the popup (only applies if using `mode` `"popup"`). | `Number` (percent) | 100 |
| onSubmit | Callback function that will be executed right after the typeform is successfully submitted. | `Function` | - |
| onReady | Callback function that will be executed once the typeform is ready. | `Function` | - |
| onClose | Callback function that will be executed once the typeform is closed. | `Function` | - |
Expand Down
3 changes: 3 additions & 0 deletions demo/form/mock.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
<h1>This is the typeform you are looking for</h1>
<img src="./photo.jpg" alt="photo" />
<button onclick="start()" data-qa="start-button">Start</button>

<!-- hidden input field for closing the form via keyboard in functional tests (cypress requires input element for typing) -->
<input type="hidden" data-qa="form-input" />
</div>
</div>
</div>
Expand Down
14 changes: 14 additions & 0 deletions demo/popup-api.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@

<a id="btn-drawer_right" class="popup">Launch me as a right drawer!</a>

<a id="btn-popup_s" class="popup">Launch me as a small popup!</a>

<a id="btn-popup_xs" class="popup">Launch me as a very small popup!</a>

<div class="popover-hint">Launch a popover here 👉</div>

<a id="btn-popover" class="popover">
Expand Down Expand Up @@ -147,6 +151,16 @@
makeMockPopup({mode: 'drawer_right', width: 300, transferableUrlParameters: ['utm_source']}).open()
}

document.getElementById('btn-popup_s').onclick = function(e) {
e.preventDefault()
makeMockPopup({mode: 'popup', transferableUrlParameters: ['utm_source'], size: 75}).open()
}

document.getElementById('btn-popup_xs').onclick = function(e) {
e.preventDefault()
makeMockPopup({mode: 'popup', transferableUrlParameters: ['utm_source'], size: 40}).open()
}

let popoverPopup
const popoverButton = document.getElementById('btn-popover')
const popoverButtonIcon = popoverButton.innerHTML
Expand Down
26 changes: 26 additions & 0 deletions demo/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,32 @@
Launch me as a right drawer!
</a>

<a
id="btn-popup_s"
class="typeform-share popup"
href="./form/mock.html#foobar=hello"
data-mode="popup"
data-submit-close-delay="4"
data-transferable-url-parameters="utm_source"
data-size="75"
target="_blank"
>
Launch me as a small popup!
</a>

<a
id="btn-popup_xs"
class="typeform-share popup"
href="./form/mock.html#foobar=hello"
data-mode="popup"
data-submit-close-delay="4"
data-transferable-url-parameters="utm_source"
data-size="40"
target="_blank"
>
Launch me as a very small popup!
</a>

<div class="popover-hint">Launch a popover here 👉</div>

<a
Expand Down
47 changes: 14 additions & 33 deletions e2e/cypress-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,11 @@ const getIframeBody = (iframe) => {
.then(cy.wrap) // wrap "body" DOM element to allow chaining more Cypress commands
}

export const getIframe = (iframe, callbackWithIframeBody, callbackWithIframe) => {
if (Cypress.isBrowser('chrome')) {
callbackWithIframeBody(getIframeBody(iframe))
} else if (callbackWithIframe) {
callbackWithIframe(cy.get(iframe))
}
}

export const testEmbeddedForm = (selector = IFRAME_SELECTOR) => {
getIframe(
selector,
iframeBody => iframeBody.find('[data-qa="start-button"]').should('have.text', 'Start').should('be.visible'),
iframe => iframe.should('be.visible')
)
getIframeBody(selector)
.find('[data-qa="start-button"]')
.should('have.text', 'Start')
.should('be.visible')
}

export const openPopup = (selector) => {
Expand All @@ -40,15 +31,11 @@ export const closePopupViaButtonOnMobile = () => {
cy.get(IFRAME_SELECTOR).should('not.exist')
}

export const closePopupViaKeyboard = (selector = '[data-qa="popup-close-button"]') => {
getIframe(
IFRAME_SELECTOR,
iframeBody => {
iframeBody.find('[data-qa="start-button"]').type('{esc}') // send escape key to iframe
cy.get(IFRAME_SELECTOR).should('not.exist')
},
() => closePopupViaButton(selector)
)
export const closePopupViaKeyboard = () => {
getIframeBody(IFRAME_SELECTOR)
.find('[data-qa="form-input"]')
.type('{esc}', { force: true }) // input is hidden, force the "esc" key
cy.get(IFRAME_SELECTOR).should('not.exist')
}

const setViewport = ({ width, height }) => {
Expand All @@ -72,19 +59,13 @@ export const openOnMobile = (url) => {
}

export const testEmbedFormOnMobile = () => {
getIframe(
IFRAME_SELECTOR,
iframeBody => {
iframeBody.find('[data-qa="start-button"]').click()
getIframeBody(IFRAME_SELECTOR).find('[data-qa="start-button"]').click()

// on mobile there are 2 iframes when the form is opened in modal window
cy.get(IFRAME_SELECTOR).should('have.length', 2)
// on mobile there are 2 iframes when the form is opened in modal window
cy.get(IFRAME_SELECTOR).should('have.length', 2)

cy.get('[data-qa="close-button-mobile"]').click()
cy.get(IFRAME_SELECTOR).should('have.length', 1)
},
iframe => iframe.should('be.visible')
)
cy.get('[data-qa="close-button-mobile"]').click()
cy.get(IFRAME_SELECTOR).should('have.length', 1)
}

export const waitForEmbed = () => {
Expand Down
6 changes: 1 addition & 5 deletions e2e/spec/functional/popup.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,7 @@ Object.keys(popupModes).forEach(popupMode => {

it('Closes Embed Popup using Keyboard', () => {
openPopup(`#btn-${popupMode}`)
if (popupMode === 'popover' || popupMode === 'side_panel') {
closePopupViaKeyboard(`#btn-${popupMode}`) // close button is used as fallback in firefox
} else {
closePopupViaKeyboard()
}
closePopupViaKeyboard()
})
})

Expand Down
2 changes: 2 additions & 0 deletions e2e/spec/visual/popup.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { eyesCheckDesktop, eyesCheckMobile } from '../../applitools-utils'
describe('Popup Widget', () => {
const popupModes = {
popup: 'Popup',
popup_s: 'Popup (small)',
popup_xs: 'Popup (very small)',
drawer_left: 'Drawer Left',
drawer_right: 'Drawer Right',
popover: 'Popover',
Expand Down
4 changes: 4 additions & 0 deletions src/core/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ const sanitizePopupAttributes = data => {
obj.transferableUrlParameters = parseTransferableUrlParameters(data.transferableUrlParameters)
}

if (data.size) {
obj.size = parseInt(data.size, 10)
}

return obj
}

Expand Down
4 changes: 3 additions & 1 deletion src/core/attributes.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ describe('Attributes', () => {
popupMockElem.setAttribute('data-hide-headers', '')
popupMockElem.setAttribute('data-hide-footer', false)
popupMockElem.setAttribute('data-invalid-attribute', true)
popupMockElem.setAttribute('data-size', '15')

const popupOptions = {
mode: 'popup',
autoClose: 10,
autoOpen: true,
open: 'scroll',
openValue: '20',
hideHeaders: true
hideHeaders: true,
size: 15
}

expect(sanitizePopupAttributes(getDataset(popupMockElem))).toEqual(popupOptions)
Expand Down
2 changes: 2 additions & 0 deletions src/core/make-popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { handleAutoOpen } from './utils/popup-auto-open'
const DEFAULT_DRAWER_WIDTH = 800
const DEFAULT_POPUP_WIDTH = 320
const DEFAULT_POPUP_HEIGHT = 500
const DEFAULT_POPUP_SIZE_PERCENT = 100

const buildOptions = (embedId, options) => {
const isDrawer = options.mode === DRAWER || options.mode === DRAWER_RIGHT
Expand All @@ -55,6 +56,7 @@ const buildOptions = (embedId, options) => {
width,
height: DEFAULT_POPUP_HEIGHT,
isAutoCloseEnabled: options.autoClose !== undefined,
size: DEFAULT_POPUP_SIZE_PERCENT,
...options
}
}
Expand Down
24 changes: 19 additions & 5 deletions src/core/views/popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,23 @@ const Overlay = styled.div`
`

const popupWrapper = styled(BaseWrapper)`
width: ${p => (p.isContained ? 'calc(100% - 80px)' : 'calc(100vw - 80px)')};
height: ${p => (p.isContained ? 'calc(100% - 80px)' : 'calc(100vh - 80px)')};
top: 40px;
left: 40px;
${p => {
const offset = (100 - p.size) / 2
if (p.isContained) {
return `
width: calc(${p.size}% - 80px);
height: calc(${p.size}% - 80px);
top: calc(${offset}% + 40px);
left: calc(${offset}% + 40px);
`
}
return `
width: calc(${p.size}% - 80px);
height: calc(${p.size}% - 80px);
top: calc(${offset}% + 40px);
left: calc(${offset}% + 40px);
`
}}
transition: all 300ms ease-out;
`

Expand Down Expand Up @@ -315,7 +328,7 @@ class Popup extends Component {
render () {
let iframeStyles = null
const { embedId, options, url } = this.props
const { width, height, hideScrollbars, isContained, mode } = options
const { width, height, hideScrollbars, isContained, mode, size } = options

if (hideScrollbars) {
iframeStyles = {
Expand Down Expand Up @@ -347,6 +360,7 @@ class Popup extends Component {
mode={mode}
onTransitionEnd={this.handleTransitionEnd}
open={this.state.frameAnimate && !this.state.isLoading}
size={size}
width={width}
>
{!showSmallPopup && this.state.iframeLoaded && (
Expand Down

0 comments on commit 991e6bd

Please sign in to comment.