diff --git a/cypress/e2e/surveys.cy.ts b/cypress/e2e/surveys.cy.ts index 9445b32c0..1d8e1024f 100644 --- a/cypress/e2e/surveys.cy.ts +++ b/cypress/e2e/surveys.cy.ts @@ -536,6 +536,31 @@ describe('Surveys', () => { cy.phCaptures().should('include', 'survey shown') cy.phCaptures().should('include', 'survey sent') }) + + it('auto contrasts text color for feedback tab', () => { + cy.intercept('GET', '**/surveys/*', { + surveys: [ + { + id: '123', + name: 'Feedback tab survey', + type: 'widget', + start_date: '2021-01-01T00:00:00Z', + questions: [openTextQuestion], + appearance: { + widgetLabel: 'Feedback', + widgetType: 'tab', + widgetColor: 'white', + }, + }, + ], + }).as('surveys') + const black = 'rgb(0, 0, 0)' + const white = 'rgb(255, 255, 255)' + cy.visit('./playground/cypress') + onPageLoad() + cy.get('.PostHogWidget123').shadow().find('.ph-survey-widget-tab').should('have.css', 'background-color', white) + cy.get('.PostHogWidget123').shadow().find('.ph-survey-widget-tab').should('have.css', 'color', black) + }) }) describe('Thank you message', () => { diff --git a/rollup.config.js b/rollup.config.js index b2fbae84e..ea4905a89 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -58,8 +58,14 @@ export default [ preact: 'preact', }, }, + ], + plugins: [...plugins], + }, + { + input: 'src/loader-surveys-preview.ts', + output: [ { - file: 'dist/surveys.esm.js', + file: 'dist/surveys-module-previews.js', format: 'es', sourcemap: true, }, diff --git a/src/__tests__/extensions/surveys.test.ts b/src/__tests__/extensions/surveys.test.ts index eea44014c..350f9c90e 100644 --- a/src/__tests__/extensions/surveys.test.ts +++ b/src/__tests__/extensions/surveys.test.ts @@ -1,5 +1,5 @@ import 'regenerator-runtime/runtime' -import { generateSurveys, renderSurveysPreview } from '../../extensions/surveys' +import { generateSurveys, renderSurveysPreview, renderFeedbackWidgetPreview } from '../../extensions/surveys' import { createShadow } from '../../extensions/surveys/surveys-utils' import { Survey, SurveyQuestionType, SurveyType } from '../../posthog-surveys-types' @@ -57,7 +57,14 @@ describe('survey display logic', () => { }) }) -describe('survey render preview', () => { +describe('preview renders', () => { + beforeEach(() => { + // we have to manually reset the DOM before each test + document.getElementsByTagName('html')[0].innerHTML = '' + localStorage.clear() + jest.clearAllMocks() + }) + test('renderSurveysPreview', () => { const mockSurvey = { id: 'testSurvey1', @@ -89,4 +96,30 @@ describe('survey render preview', () => { expect(surveyDiv.getElementsByClassName('survey-form').length).toBe(1) expect(surveyDiv.getElementsByClassName('survey-question').length).toBe(1) }) + + test('renderFeedbackWidgetPreview', () => { + const mockSurvey = { + id: 'testSurvey1', + name: 'Test survey 1', + type: SurveyType.Widget, + appearance: { widgetLabel: 'preview test', widgetColor: 'black', widgetType: 'tab' }, + start_date: '2021-01-01T00:00:00.000Z', + description: 'This is a survey description', + linked_flag_key: null, + questions: [ + { + question: 'What would you like to see next?', + type: SurveyQuestionType.Open, + }, + ], + end_date: null, + targeting_flag_key: null, + } + const root = document.createElement('div') + expect(root.innerHTML).toBe('') + renderFeedbackWidgetPreview(mockSurvey as Survey, root) + expect(root.getElementsByTagName('style').length).toBe(1) + expect(root.getElementsByClassName('ph-survey-widget-tab').length).toBe(1) + expect(root.getElementsByClassName('ph-survey-widget-tab')[0].innerHTML).toContain('preview test') + }) }) diff --git a/src/extensions/surveys-widget.ts b/src/extensions/surveys-widget.ts index 66b96f22c..71da17b15 100644 --- a/src/extensions/surveys-widget.ts +++ b/src/extensions/surveys-widget.ts @@ -8,12 +8,19 @@ export function createWidgetShadow(survey: Survey) { const div = document.createElement('div') div.className = `PostHogWidget${survey.id}` const shadow = div.attachShadow({ mode: 'open' }) - const widgetStyleSheet = ` + const widgetStyleSheet = createWidgetStyle(survey.appearance?.widgetColor) + shadow.append(Object.assign(document.createElement('style'), { innerText: widgetStyleSheet })) + document.body.appendChild(div) + return shadow +} + +export function createWidgetStyle(widgetColor?: string) { + return ` .ph-survey-widget-tab { position: fixed; top: 50%; right: 0; - background: ${survey.appearance?.widgetColor || '#e0a045'}; + background: ${widgetColor || '#e0a045'}; color: white; transform: rotate(-90deg) translate(0, -100%); transform-origin: right top; @@ -32,7 +39,4 @@ export function createWidgetShadow(survey: Survey) { position: fixed; } ` - shadow.append(Object.assign(document.createElement('style'), { innerText: widgetStyleSheet })) - document.body.appendChild(div) - return shadow } diff --git a/src/extensions/surveys.tsx b/src/extensions/surveys.tsx index 3f029d5db..5b8578234 100644 --- a/src/extensions/surveys.tsx +++ b/src/extensions/surveys.tsx @@ -22,7 +22,7 @@ import { } from './surveys/surveys-utils' import * as Preact from 'preact' import { render } from 'preact-render-to-string' -import { createWidgetShadow } from './surveys-widget' +import { createWidgetShadow, createWidgetStyle } from './surveys-widget' import { useState, useEffect, useRef, useContext } from 'preact/hooks' import { _isNumber } from '../utils/type-utils' import { ConfirmationMessage } from './surveys/components/ConfirmationMessage' @@ -41,7 +41,7 @@ const handleWidget = (posthog: PostHog, survey: Survey) => { const shadow = createWidgetShadow(survey) const surveyStyleSheet = style(survey.appearance) shadow.appendChild(Object.assign(document.createElement('style'), { innerText: surveyStyleSheet })) - Preact.render(, shadow) + Preact.render(, shadow) } export const callSurveys = (posthog: PostHog, forceReload: boolean = false) => { @@ -99,7 +99,7 @@ export const callSurveys = (posthog: PostHog, forceReload: boolean = false) => { if (!localStorage.getItem(`seenSurvey_${survey.id}`)) { const shadow = createShadow(style(survey?.appearance), survey.id) - Preact.render(, shadow) + Preact.render(, shadow) } } }) @@ -120,6 +120,7 @@ export const renderSurveysPreview = ( ) const surveyHtml = render( { + const widgetStyleSheet = createWidgetStyle(survey.appearance?.widgetColor) + const styleElement = Object.assign(document.createElement('style'), { innerText: widgetStyleSheet }) + root.appendChild(styleElement) + const widgetHtml = render() + const widgetDiv = document.createElement('div') + widgetDiv.innerHTML = widgetHtml + root.appendChild(widgetDiv) +} + // This is the main exported function export function generateSurveys(posthog: PostHog) { // NOTE: Important to ensure we never try and run surveys without a window environment @@ -364,12 +375,24 @@ const closeSurveyPopup = (survey: Survey, posthog?: PostHog, readOnly?: boolean) window.dispatchEvent(new Event('PHSurveyClosed')) } -export function FeedbackWidget({ posthog, survey }: { posthog: PostHog; survey: Survey }): JSX.Element { +export function FeedbackWidget({ + survey, + posthog, + readOnly, +}: { + survey: Survey + posthog?: PostHog + readOnly?: boolean +}): JSX.Element { const [showSurvey, setShowSurvey] = useState(false) const [styleOverrides, setStyle] = useState({}) const widgetRef = useRef(null) useEffect(() => { + if (readOnly || !posthog) { + return + } + if (survey.appearance?.widgetType === 'tab') { if (widgetRef.current) { const widgetPos = widgetRef.current.getBoundingClientRect() @@ -395,12 +418,19 @@ export function FeedbackWidget({ posthog, survey }: { posthog: PostHog; survey: return ( <> {survey.appearance?.widgetType === 'tab' && ( -
setShowSurvey(!showSurvey)}> +
!readOnly && setShowSurvey(!showSurvey)} + style={{ color: getContrastingTextColor(survey.appearance.widgetColor) }} + >
{survey.appearance?.widgetLabel || ''}
)} - {showSurvey && } + {showSurvey && ( + + )} ) } diff --git a/src/loader-surveys-preview.ts b/src/loader-surveys-preview.ts new file mode 100644 index 000000000..46315a70f --- /dev/null +++ b/src/loader-surveys-preview.ts @@ -0,0 +1 @@ +export { renderSurveysPreview, renderFeedbackWidgetPreview } from './extensions/surveys' diff --git a/src/loader-surveys.ts b/src/loader-surveys.ts index d8c25e0de..9e7bf8e1f 100644 --- a/src/loader-surveys.ts +++ b/src/loader-surveys.ts @@ -1,7 +1,6 @@ import { generateSurveys } from './extensions/surveys' import { window } from './utils/globals' -export { renderSurveysPreview } from './extensions/surveys' if (window) { ;(window as any).extendPostHogWithSurveys = generateSurveys