2
0

feat(lib): 💄 Better chat widget icon

This commit is contained in:
Baptiste Arnaud
2022-04-30 06:48:26 -07:00
parent e339cc1672
commit a2cfecc16c
8 changed files with 29 additions and 25 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "typebot-js", "name": "typebot-js",
"version": "2.2.4", "version": "2.2.5",
"main": "dist/index.js", "main": "dist/index.js",
"unpkg": "dist/index.umd.min.js", "unpkg": "dist/index.umd.min.js",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",

View File

@ -12,7 +12,7 @@ export const createButton = (params?: ButtonParams): HTMLButtonElement => {
const createButtonIcon = ( const createButtonIcon = (
src?: string, src?: string,
style?: string style?: string
): SVGElement | HTMLImageElement => { ): SVGElement | HTMLElement => {
if (!src) return createDefaultIcon() if (!src) return createDefaultIcon()
const icon = document.createElement('img') const icon = document.createElement('img')
icon.classList.add('icon') icon.classList.add('icon')
@ -23,8 +23,7 @@ const createButtonIcon = (
const createDefaultIcon = (): SVGElement => { const createDefaultIcon = (): SVGElement => {
const icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg') const icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
icon.setAttribute('viewBox', '0 0 41 19') icon.setAttribute('viewBox', '0 0 24 24')
icon.style.width = '63%'
icon.innerHTML = typebotLogoSvgTextContent() icon.innerHTML = typebotLogoSvgTextContent()
icon.classList.add('icon') icon.classList.add('icon')
return icon return icon
@ -32,13 +31,13 @@ const createDefaultIcon = (): SVGElement => {
const createCloseIcon = (): SVGElement => { const createCloseIcon = (): SVGElement => {
const icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg') const icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
icon.setAttribute('viewBox', '0 0 512 512') icon.setAttribute('viewBox', '0 0 24 24')
icon.innerHTML = closeSvgPath icon.innerHTML = closeSvgPath
icon.classList.add('close-icon') icon.classList.add('close-icon')
return icon return icon
} }
const typebotLogoSvgTextContent = () => const typebotLogoSvgTextContent = () =>
`<rect x="40.29" y="0.967773" width="6.83761" height="30.7692" rx="3.4188" transform="rotate(90 40.29 0.967773)"></rect> <path fill-rule="evenodd" clip-rule="evenodd" d="M3.70884 7.80538C5.597 7.80538 7.12765 6.27473 7.12765 4.38658C7.12765 2.49842 5.597 0.967773 3.70884 0.967773C1.82069 0.967773 0.290039 2.49842 0.290039 4.38658C0.290039 6.27473 1.82069 7.80538 3.70884 7.80538Z" fill="white"></path> <rect x="0.290039" y="18.0615" width="6.83761" height="30.7692" rx="3.4188" transform="rotate(-90 0.290039 18.0615)" fill="white"></rect> <path fill-rule="evenodd" clip-rule="evenodd" d="M36.8712 11.2239C34.9831 11.2239 33.4524 12.7546 33.4524 14.6427C33.4524 16.5309 34.9831 18.0615 36.8712 18.0615C38.7594 18.0615 40.29 16.5309 40.29 14.6427C40.29 12.7546 38.7594 11.2239 36.8712 11.2239Z" fill="white"></path>` `<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path>`
export const closeSvgPath = `<path d="M278.6 256l68.2-68.2c6.2-6.2 6.2-16.4 0-22.6-6.2-6.2-16.4-6.2-22.6 0L256 233.4l-68.2-68.2c-6.2-6.2-16.4-6.2-22.6 0-3.1 3.1-4.7 7.2-4.7 11.3 0 4.1 1.6 8.2 4.7 11.3l68.2 68.2-68.2 68.2c-3.1 3.1-4.7 7.2-4.7 11.3 0 4.1 1.6 8.2 4.7 11.3 6.2 6.2 16.4 6.2 22.6 0l68.2-68.2 68.2 68.2c6.2 6.2 16.4 6.2 22.6 0 6.2-6.2 6.2-16.4 0-22.6L278.6 256z"></path>` export const closeSvgPath = `<line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line>`

View File

@ -1,4 +1,4 @@
import { setRememberCloseInStorage } from '../chat/index' import { setRememberCloseInStorage } from '../chat'
import { ProactiveMessageParams } from '../../types' import { ProactiveMessageParams } from '../../types'
import { closeSvgPath } from './button' import { closeSvgPath } from './button'

View File

@ -31,13 +31,22 @@
} }
#typebot-bubble > button > .icon { #typebot-bubble > button > .icon {
width: 80%;
transition: opacity 500ms ease-out 0s, transform 500ms ease-out 0s; transition: opacity 500ms ease-out 0s, transform 500ms ease-out 0s;
fill: white; }
#typebot-bubble > button > svg.icon {
fill: none;
width: 55%;
stroke-width: 2px;
stroke: white;
} }
#typebot-bubble > button > img.icon { #typebot-bubble > button > img.icon {
width: 80%;
height: 80%;
border-radius: 100%; border-radius: 100%;
object-fit: cover;
object-position: center;
} }
#typebot-bubble.iframe-opened > button > .icon { #typebot-bubble.iframe-opened > button > .icon {
@ -47,12 +56,12 @@
#typebot-bubble > button > .close-icon { #typebot-bubble > button > .close-icon {
position: absolute; position: absolute;
width: 80%;
height: 80%;
transform: rotate(-90deg) scale(0); transform: rotate(-90deg) scale(0);
opacity: 0; opacity: 0;
transition: opacity 500ms ease-out 0s, transform 500ms ease-out 0s; transition: opacity 500ms ease-out 0s, transform 500ms ease-out 0s;
fill: white; width: 55%;
stroke-width: 2px;
stroke: white;
} }
#typebot-bubble.iframe-opened > button > .close-icon { #typebot-bubble.iframe-opened > button > .close-icon {

View File

@ -39,8 +39,8 @@ const parseQueryParams = (starterVariables?: {
const parseStarterVariables = (starterVariables?: { const parseStarterVariables = (starterVariables?: {
[key: string]: string | undefined [key: string]: string | undefined
}) => }) =>
starterVariables starterVariables && Object.keys(starterVariables).length > 0
? `&${Object.keys(starterVariables) ? `?${Object.keys(starterVariables)
.filter((key) => starterVariables[key]) .filter((key) => starterVariables[key])
.map( .map(
(key) => (key) =>

View File

@ -23,9 +23,7 @@ describe('initBubble', () => {
Typebot.initBubble({ url: 'https://typebot.io/typebot-id2' }) Typebot.initBubble({ url: 'https://typebot.io/typebot-id2' })
const frames = document.getElementsByTagName('iframe') const frames = document.getElementsByTagName('iframe')
expect(frames).toHaveLength(1) expect(frames).toHaveLength(1)
expect(frames[0].dataset.src).toBe( expect(frames[0].dataset.src).toBe('https://typebot.io/typebot-id2')
'https://typebot.io/typebot-id2?hn=localhost'
)
}) })
it('show open after the corresponding delay', async () => { it('show open after the corresponding delay', async () => {
@ -36,7 +34,7 @@ describe('initBubble', () => {
}) })
const bubble = document.querySelector('#typebot-bubble') as HTMLDivElement const bubble = document.querySelector('#typebot-bubble') as HTMLDivElement
expect(bubble.classList.contains('iframe-opened')).toBe(false) expect(bubble.classList.contains('iframe-opened')).toBe(false)
await new Promise((r) => setTimeout(r, 1050)) await new Promise((r) => setTimeout(r, 1100))
expect(bubble.classList.contains('iframe-opened')).toBe(true) expect(bubble.classList.contains('iframe-opened')).toBe(true)
const rememberCloseDecisionFromStorage = localStorage.getItem( const rememberCloseDecisionFromStorage = localStorage.getItem(
Typebot.localStorageKeys.rememberClose Typebot.localStorageKeys.rememberClose

View File

@ -11,7 +11,7 @@ describe('createIframe', () => {
'https://typebot.io/typebot-id' 'https://typebot.io/typebot-id'
) )
expect(iframeElement.getAttribute('src')).toBe( expect(iframeElement.getAttribute('src')).toBe(
'https://typebot.io/typebot-id?hn=localhost' 'https://typebot.io/typebot-id'
) )
}) })
@ -24,7 +24,7 @@ describe('createIframe', () => {
}), }),
] ]
expect(iframes[0].getAttribute('src')).toBe( expect(iframes[0].getAttribute('src')).toBe(
'https://typebot.io/typebot-id?hn=localhost&var1=value1&var2=value2' 'https://typebot.io/typebot-id?var1=value1&var2=value2'
) )
}) })
@ -44,7 +44,7 @@ describe('createIframe', () => {
loadWhenVisible: true, loadWhenVisible: true,
}) })
expect(iframeElement.getAttribute('data-src')).toBe( expect(iframeElement.getAttribute('data-src')).toBe(
'https://typebot.io/typebot-id?hn=localhost' 'https://typebot.io/typebot-id'
) )
expect(iframeElement.getAttribute('src')).toBeFalsy() expect(iframeElement.getAttribute('src')).toBeFalsy()
}) })

View File

@ -23,9 +23,7 @@ describe('initPopup', () => {
initPopup({ url: 'https://typebot.io/typebot-id2' }) initPopup({ url: 'https://typebot.io/typebot-id2' })
const elements = document.getElementsByTagName('iframe') const elements = document.getElementsByTagName('iframe')
expect(elements).toHaveLength(1) expect(elements).toHaveLength(1)
expect(elements[0].dataset.src).toBe( expect(elements[0].dataset.src).toBe('https://typebot.io/typebot-id2')
'https://typebot.io/typebot-id2?hn=localhost'
)
}) })
it("shouldn't have opened classname if no delay", () => { it("shouldn't have opened classname if no delay", () => {