{"version":3,"sources":["webpack:///./src/core/api/services/ApiService.ts","webpack:///./src/hooks/useIntersectionObserver.ts","webpack:///./src/hooks/useInView.ts","webpack:///./src/helpers/recaptcha.ts","webpack:///./src/stories/Components/Forms/Recaptcha/Recaptcha.styles.ts","webpack:///./src/stories/Components/Forms/Recaptcha/Recaptcha.tsx","webpack:///./src/hooks/useRecaptcha.ts","webpack:///./src/stories/Components/Forms/Checkbox/Checkbox.styles.ts","webpack:///./src/stories/Components/Forms/Checkbox/Checkbox.tsx"],"names":["ApiService","request","url","this","getUrl","headers","Headers","Accept","isMultipartFormData","delete","requestOptions","method","cache","body","getBody","files","undefined","cors","mode","credentials","fetch","response","status","Error","statusText","json","data","slug","controller","length","isStorybook","isSSR","window","location","host","port","process","API_URL","baseUrl","params","querystring","stringify","formData","FormData","append","JSON","index","file","useIntersectionObserver","callback","options","observerRef","useRef","rootRef","elementRef","useEffect","current","IntersectionObserver","root","observe","disconnect","useInView","reverse","isEditMode","useState","inView","setInView","entries","isIntersecting","load","Promise","resolve","reject","grecaptcha","script","document","createElement","onRecaptchaLoad","src","head","appendChild","error","initialise","element","sitekey","ready","widgetId","render","reset","RecaptchaStyles","Container","styled","div","Recaptcha","shouldLoad","siteKey","onChange","threshold","ref","recaptcha","React","recaptchaState","setRecaptchaState","verifyCallback","doAsync","useRecaptcha","token","S","Input","input","srOnly","Label","label","brand","white","rgba","grey","grey55","primary","base","Checkbox","value","onKeyDown","e","key","toLowerCase","preventDefault","onClick","noop","props","Fragment","type","checked","htmlLabel","htmlFor","id","required","dangerouslySetInnerHTML","__html"],"mappings":"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","file":"20-f20e05e3a707e1fbdaaa.js","sourcesContent":["import { isSSR } from '@helpers/ssr';\r\nimport querystring from 'querystring';\r\nclass ApiService {\r\n async request(request) {\r\n // Get the url\r\n const url = this.getUrl(request);\r\n // Headers\r\n const headers = new Headers({\r\n 'Content-Type': 'application/json; charset=utf-8',\r\n Accept: 'application/json',\r\n });\r\n if (request.isMultipartFormData === true) {\r\n headers.delete('Content-Type');\r\n }\r\n // construct a request\r\n const requestOptions = {\r\n method: request.method,\r\n headers,\r\n cache: 'default',\r\n body: this.getBody(request, request.files),\r\n };\r\n if (request.cors === undefined || request.cors === true) {\r\n requestOptions.mode = 'cors';\r\n requestOptions.credentials = 'include';\r\n }\r\n // await the response\r\n const response = await fetch(url, requestOptions);\r\n if (response.status === 500) {\r\n throw Error(`${response.status}: ${response.statusText}`);\r\n }\r\n const data = (await response.json());\r\n return data;\r\n }\r\n async safeRequest(request) {\r\n try {\r\n const response = await this.request(request);\r\n return response;\r\n }\r\n catch {\r\n return null;\r\n }\r\n }\r\n getUrl(request) {\r\n let url = `/${request.slug}`;\r\n if (request.controller && request.controller.length > 0) {\r\n url = `/api/${request.controller}/${request.slug}`;\r\n }\r\n let isStorybook = false;\r\n if (!isSSR()) {\r\n if ((window.location.host === 'styleguide.groundforce.netcprev.co.uk' ||\r\n window.location.port === '4000' ||\r\n window.location.port === '4001') &&\r\n process.env.API_URL) {\r\n isStorybook = true;\r\n }\r\n }\r\n if (request.baseUrl) {\r\n url = `${request.baseUrl}${url}`;\r\n }\r\n else if (isStorybook) {\r\n url = `${process.env.API_URL}${url}`;\r\n }\r\n if ((request.method === 'GET' || request.method === 'DELETE') && request.params) {\r\n url += '?';\r\n url += querystring.stringify({ ...request.params });\r\n }\r\n return url;\r\n }\r\n getBody(request, files) {\r\n if (request.method === 'GET') {\r\n return null;\r\n }\r\n if (request.isMultipartFormData === true) {\r\n const formData = new FormData();\r\n formData.append('params', JSON.stringify(request.params));\r\n if (files && files.length > 0) {\r\n for (let index = 0; index < files.length; index++) {\r\n const file = files[index];\r\n formData.append(`files-${index}`, file);\r\n }\r\n }\r\n return formData;\r\n }\r\n return JSON.stringify(request.params);\r\n }\r\n}\r\nexport default new ApiService();\r\n","import { useEffect, useRef } from 'react';\r\n/**\r\n * Use the IntersectionObserver to track visibility of an element in the viewport.\r\n * @param {IntersectionObserverCallback} callback\r\n * @param {IntersectionObserverInit} options\r\n * @returns {UseIntersectionObserverReturn}\r\n */\r\nfunction useIntersectionObserver(callback, options = {}) {\r\n const observerRef = useRef(null);\r\n const rootRef = useRef(null);\r\n const elementRef = useRef(null);\r\n useEffect(() => {\r\n if (!elementRef.current) {\r\n return undefined;\r\n }\r\n observerRef.current = new IntersectionObserver(callback, {\r\n root: rootRef.current,\r\n ...options,\r\n });\r\n observerRef.current.observe(elementRef.current);\r\n return () => {\r\n if (observerRef.current === null) {\r\n return;\r\n }\r\n observerRef.current.disconnect();\r\n };\r\n }, [callback, options]);\r\n return { elementRef, observerRef, rootRef };\r\n}\r\nexport default useIntersectionObserver;\r\n","import { useState } from 'react';\r\nimport useIntersectionObserver from './useIntersectionObserver';\r\nexport function useInView(options, reverse = false, isEditMode = false) {\r\n const [inView, setInView] = useState(false);\r\n const { elementRef } = useIntersectionObserver((entries) => {\r\n if (entries[0].isIntersecting) {\r\n setInView(true);\r\n }\r\n else if (reverse === true) {\r\n setInView(false);\r\n }\r\n }, options);\r\n return [elementRef, isEditMode ? true : inView];\r\n}\r\n","import { isSSR } from '@helpers/ssr';\r\nfunction load() {\r\n const promise = new Promise((resolve, reject) => {\r\n if (isSSR() || typeof window.grecaptcha !== 'undefined') {\r\n return resolve();\r\n }\r\n try {\r\n const script = document.createElement('script');\r\n window.onRecaptchaLoad = function onRecaptchaLoad() {\r\n resolve();\r\n };\r\n script.src = 'https://www.google.com/recaptcha/api.js?onload=onRecaptchaLoad&render=explicit';\r\n document.head.appendChild(script);\r\n }\r\n catch (error) {\r\n reject(error);\r\n }\r\n });\r\n return promise;\r\n}\r\nfunction initialise(element, sitekey, callback) {\r\n const promise = new Promise((resolve, reject) => {\r\n if (typeof window.grecaptcha === 'undefined') {\r\n return reject(`\"window.grecaptcha\" is undefined, ensure the recaptcha script has been loaded.`);\r\n }\r\n window.grecaptcha.ready(() => {\r\n const widgetId = window.grecaptcha.render(element, {\r\n sitekey: sitekey,\r\n callback: callback,\r\n 'expired-callback': () => {\r\n window.grecaptcha.reset('recaptcha-container');\r\n },\r\n 'error-callback': reject,\r\n });\r\n resolve(widgetId);\r\n });\r\n });\r\n return promise;\r\n}\r\nfunction reset(widgetId) {\r\n const promise = new Promise((resolve, reject) => {\r\n if (typeof window.grecaptcha === 'undefined') {\r\n return reject(`\"window.grecaptcha\" is undefined, ensure the recaptcha script has been loaded.`);\r\n }\r\n window.grecaptcha.ready(() => {\r\n window.grecaptcha.reset(widgetId);\r\n resolve();\r\n });\r\n });\r\n return promise;\r\n}\r\nexport { initialise, load, reset };\r\n","import styled from 'styled-components';\r\nconst Container = styled.div ``;\r\nconst Recaptcha = styled.div ``;\r\nconst RecaptchaStyles = {\r\n Container,\r\n Recaptcha,\r\n};\r\nexport default RecaptchaStyles;\r\n","import { useInView } from '@hooks/useInView';\r\nimport { useRecaptcha } from '@hooks/useRecaptcha';\r\nimport * as React from 'react';\r\nimport S from './Recaptcha.styles';\r\nconst Recaptcha = ({ shouldLoad, siteKey, onChange }) => {\r\n const [ref, inView] = useInView({ threshold: 1 });\r\n const recaptcha = useRecaptcha({\r\n shouldLoad: inView ? shouldLoad : false,\r\n siteKey: siteKey,\r\n verifyCallback: (token) => {\r\n onChange(token);\r\n },\r\n });\r\n return React.createElement(S.Container, { ref: ref }, inView && React.createElement(S.Recaptcha, { ref: recaptcha.ref }));\r\n};\r\nexport default React.memo(Recaptcha);\r\n","import * as recaptcha from '@helpers/recaptcha';\r\nimport * as React from 'react';\r\nexport function useRecaptcha(params) {\r\n const ref = React.useRef(null);\r\n const [recaptchaState, setRecaptchaState] = React.useState({ widgetId: '' });\r\n // Handle initialisation of recaptcha.\r\n React.useEffect(() => {\r\n doAsync();\r\n async function doAsync() {\r\n // Defer until we should load, and ref is set.\r\n if (!ref.current || !params.shouldLoad) {\r\n return;\r\n }\r\n // Load recaptcha script.\r\n await recaptcha.load();\r\n // Initialise the recaptcha widget and store widget id in state.\r\n const widgetId = await recaptcha.initialise(ref.current, params.siteKey, params.verifyCallback);\r\n setRecaptchaState({ widgetId });\r\n }\r\n }, [params.shouldLoad]);\r\n // Create callback function based on current widget id.\r\n const reset = React.useCallback(async () => {\r\n await recaptcha.reset(recaptchaState.widgetId);\r\n }, [recaptchaState.widgetId]);\r\n return { ...recaptchaState, ref, reset };\r\n}\r\n","import brand from '@helpers/brand';\r\nimport srOnly from '@helpers/srOnly';\r\nimport { rgba } from 'polished';\r\nimport styled from 'styled-components';\r\nconst Input = styled.input `\r\n ${srOnly}\r\n`;\r\nconst Label = styled.label `\r\n position: relative;\r\n padding-left: 28px;\r\n user-select: none;\r\n\r\n &::before,\r\n &::after {\r\n content: '';\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n border-radius: 3px;\r\n height: 20px;\r\n width: 20px;\r\n transition: all 0.1s;\r\n }\r\n\r\n &::before {\r\n display: inline-flex;\r\n background: ${brand.white};\r\n border: 1px solid ${rgba(brand.grey.grey55, 0.75)};\r\n place-content: center;\r\n place-items: center;\r\n text-align: center;\r\n }\r\n\r\n &::after {\r\n display: inline-flex;\r\n background: ${brand.primary.base};\r\n background-clip: content-box;\r\n border: 1px solid ${rgba(brand.grey.grey55, 0.75)};\r\n border-radius: 3px;\r\n padding: 3px;\r\n place-content: center;\r\n place-items: center;\r\n text-align: center;\r\n opacity: 0;\r\n width: 14px;\r\n height: 14px;\r\n }\r\n\r\n ${Input}:checked + &::after {\r\n opacity: 1;\r\n }\r\n`;\r\nexport default {\r\n Input,\r\n Label,\r\n};\r\n","import React from 'react';\r\nimport S from './Checkbox.styles';\r\nimport noop from 'lodash/noop';\r\nconst Checkbox = ({ value, onKeyDown = (e) => {\r\n if (e.key.toLowerCase() === 'enter') {\r\n e.preventDefault(); // Stops weird behaviour\r\n }\r\n}, onClick = () => noop(), ...props }) => {\r\n const onChange = (e) => {\r\n if (props.onChange) {\r\n props.onChange(e);\r\n }\r\n };\r\n return (React.createElement(React.Fragment, null,\r\n React.createElement(S.Input, { ...props, type: \"checkbox\", checked: value, onChange: (e) => onChange(e), onKeyDown: onKeyDown }),\r\n !props.htmlLabel && (React.createElement(S.Label, { onClick: () => onClick && onClick(!value), htmlFor: props.id },\r\n props.label,\r\n \" \",\r\n props.required ? React.createElement(\"span\", null, \"*\") : null)),\r\n !!props.htmlLabel && (React.createElement(S.Label, { onClick: () => onClick && onClick(!value), htmlFor: props.id, dangerouslySetInnerHTML: { __html: props.label } }, props.required ? React.createElement(\"span\", null, \"*\") : null))));\r\n};\r\nexport default Checkbox;\r\n"],"sourceRoot":""}