From b82bfab56d8f99264afc54025c3286c1be85bc98 Mon Sep 17 00:00:00 2001 From: Li Yi Date: Mon, 19 Feb 2024 13:16:05 -0500 Subject: [PATCH 1/5] fix text color contrast for feedback tab --- cypress/e2e/surveys.cy.ts | 25 +++++++++++++++++++++++++ src/extensions/surveys-widget.ts | 14 +++++++++----- src/extensions/surveys.tsx | 4 ++-- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/cypress/e2e/surveys.cy.ts b/cypress/e2e/surveys.cy.ts index 7544dfb14..6e4c79c98 100644 --- a/cypress/e2e/surveys.cy.ts +++ b/cypress/e2e/surveys.cy.ts @@ -514,6 +514,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/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..0118ca8ee 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' @@ -395,7 +395,7 @@ 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 || ''}
From 733e53eaf1bc0d9ab049ba7424a15f9822b5501b Mon Sep 17 00:00:00 2001 From: Li Yi Date: Mon, 19 Feb 2024 13:16:28 -0500 Subject: [PATCH 2/5] render feedback widget preview --- src/__tests__/extensions/surveys.test.ts | 30 ++++++++++++++++++++++-- src/extensions/surveys.tsx | 29 +++++++++++++++++++++-- src/loader-surveys.ts | 2 +- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/__tests__/extensions/surveys.test.ts b/src/__tests__/extensions/surveys.test.ts index eea44014c..0bec9f2fc 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,7 @@ describe('survey display logic', () => { }) }) -describe('survey render preview', () => { +describe('preview renders', () => { test('renderSurveysPreview', () => { const mockSurvey = { id: 'testSurvey1', @@ -89,4 +89,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: {}, + 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, + }, + ], + conditions: { widgetLabel: 'preview test', widgetColor: 'black' }, + end_date: null, + targeting_flag_key: null, + } + const surveyDiv = document.createElement('div') + expect(surveyDiv.innerHTML).toBe('') + renderFeedbackWidgetPreview(mockSurvey as Survey, surveyDiv) + expect(surveyDiv.getElementsByTagName('style').length).toBe(1) + expect(surveyDiv.getElementsByClassName('ph-survey-widget-tab').length).toBe(1) + }) }) diff --git a/src/extensions/surveys.tsx b/src/extensions/surveys.tsx index 0118ca8ee..77bd47ef5 100644 --- a/src/extensions/surveys.tsx +++ b/src/extensions/surveys.tsx @@ -138,6 +138,14 @@ export const renderSurveysPreview = ( root.appendChild(surveyDiv) } +export const renderFeedbackWidgetPreview = (survey: Survey, root: HTMLElement) => { + const shadow = createWidgetShadow(survey) + const surveyStyleSheet = createWidgetStyle(survey.appearance?.widgetColor) + shadow.appendChild(Object.assign(document.createElement('style'), { innerText: surveyStyleSheet })) + Preact.render(, shadow) + root.appendChild(shadow) +} + // 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 +372,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({ + posthog, + survey, + readOnly, +}: { + posthog: PostHog + survey: Survey + readOnly?: boolean +}): JSX.Element { const [showSurvey, setShowSurvey] = useState(false) const [styleOverrides, setStyle] = useState({}) const widgetRef = useRef(null) useEffect(() => { + if (readOnly) { + return + } + if (survey.appearance?.widgetType === 'tab') { if (widgetRef.current) { const widgetPos = widgetRef.current.getBoundingClientRect() @@ -395,7 +415,12 @@ export function FeedbackWidget({ posthog, survey }: { posthog: PostHog; survey: return ( <> {survey.appearance?.widgetType === 'tab' && ( -
!readOnly && setShowSurvey(!showSurvey)} style={{color: getContrastingTextColor(survey.appearance.widgetColor)}}> +
!readOnly && setShowSurvey(!showSurvey)} + style={{ color: getContrastingTextColor(survey.appearance.widgetColor) }} + >
{survey.appearance?.widgetLabel || ''}
diff --git a/src/loader-surveys.ts b/src/loader-surveys.ts index d8c25e0de..5fbed6f32 100644 --- a/src/loader-surveys.ts +++ b/src/loader-surveys.ts @@ -1,7 +1,7 @@ import { generateSurveys } from './extensions/surveys' import { window } from './utils/globals' -export { renderSurveysPreview } from './extensions/surveys' +export { renderSurveysPreview, renderFeedbackWidgetPreview } from './extensions/surveys' if (window) { ;(window as any).extendPostHogWithSurveys = generateSurveys From 738f8335db173d52aa7f66f375091510f6aa1f02 Mon Sep 17 00:00:00 2001 From: Li Yi Date: Mon, 19 Feb 2024 14:27:21 -0500 Subject: [PATCH 3/5] fix tests and render method --- src/__tests__/extensions/surveys.test.ts | 21 ++++++++++++++------- src/extensions/surveys.tsx | 18 ++++++++++-------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/__tests__/extensions/surveys.test.ts b/src/__tests__/extensions/surveys.test.ts index 0bec9f2fc..350f9c90e 100644 --- a/src/__tests__/extensions/surveys.test.ts +++ b/src/__tests__/extensions/surveys.test.ts @@ -58,6 +58,13 @@ describe('survey display logic', () => { }) 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', @@ -95,7 +102,7 @@ describe('preview renders', () => { id: 'testSurvey1', name: 'Test survey 1', type: SurveyType.Widget, - appearance: {}, + 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, @@ -105,14 +112,14 @@ describe('preview renders', () => { type: SurveyQuestionType.Open, }, ], - conditions: { widgetLabel: 'preview test', widgetColor: 'black' }, end_date: null, targeting_flag_key: null, } - const surveyDiv = document.createElement('div') - expect(surveyDiv.innerHTML).toBe('') - renderFeedbackWidgetPreview(mockSurvey as Survey, surveyDiv) - expect(surveyDiv.getElementsByTagName('style').length).toBe(1) - expect(surveyDiv.getElementsByClassName('ph-survey-widget-tab').length).toBe(1) + 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.tsx b/src/extensions/surveys.tsx index 77bd47ef5..6e64713bd 100644 --- a/src/extensions/surveys.tsx +++ b/src/extensions/surveys.tsx @@ -139,11 +139,13 @@ export const renderSurveysPreview = ( } export const renderFeedbackWidgetPreview = (survey: Survey, root: HTMLElement) => { - const shadow = createWidgetShadow(survey) - const surveyStyleSheet = createWidgetStyle(survey.appearance?.widgetColor) - shadow.appendChild(Object.assign(document.createElement('style'), { innerText: surveyStyleSheet })) - Preact.render(, shadow) - root.appendChild(shadow) + 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 @@ -373,12 +375,12 @@ const closeSurveyPopup = (survey: Survey, posthog?: PostHog, readOnly?: boolean) } export function FeedbackWidget({ - posthog, survey, + posthog, readOnly, }: { - posthog: PostHog survey: Survey + posthog?: PostHog readOnly?: boolean }): JSX.Element { const [showSurvey, setShowSurvey] = useState(false) @@ -386,7 +388,7 @@ export function FeedbackWidget({ const widgetRef = useRef(null) useEffect(() => { - if (readOnly) { + if (readOnly || !posthog) { return } From 1a6a47d903d499ddd5d5e3bf3ebea5d7957e2f41 Mon Sep 17 00:00:00 2001 From: Li Yi Date: Mon, 19 Feb 2024 21:48:52 -0500 Subject: [PATCH 4/5] load survey previews module separately otherwise it overrides generateSurveys --- rollup.config.js | 8 +++++++- src/extensions/surveys.tsx | 11 +++++++---- src/loader-surveys.ts | 1 - 3 files changed, 14 insertions(+), 6 deletions(-) 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/extensions/surveys.tsx b/src/extensions/surveys.tsx index 6e64713bd..5b8578234 100644 --- a/src/extensions/surveys.tsx +++ b/src/extensions/surveys.tsx @@ -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 widgetHtml = render() const widgetDiv = document.createElement('div') widgetDiv.innerHTML = widgetHtml root.appendChild(widgetDiv) @@ -427,7 +428,9 @@ export function FeedbackWidget({ {survey.appearance?.widgetLabel || ''}
)} - {showSurvey && } + {showSurvey && ( + + )} ) } diff --git a/src/loader-surveys.ts b/src/loader-surveys.ts index 5fbed6f32..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, renderFeedbackWidgetPreview } from './extensions/surveys' if (window) { ;(window as any).extendPostHogWithSurveys = generateSurveys From 1da5b549db6f41d1339ce3320f9530df026f53a7 Mon Sep 17 00:00:00 2001 From: Li Yi Date: Mon, 19 Feb 2024 21:49:45 -0500 Subject: [PATCH 5/5] add file --- src/loader-surveys-preview.ts | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/loader-surveys-preview.ts 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'