From 0ea575ad3851aeac20e8d361507f65e01e3317d6 Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Tue, 19 Mar 2024 20:06:16 +0000 Subject: [PATCH 1/3] feat: support padding for mobile replay styling --- .../__snapshots__/transform.test.ts.snap | 149 +++++++++++++++++- ee/frontend/mobile-replay/mobile.types.ts | 16 ++ ee/frontend/mobile-replay/transform.test.ts | 29 ++++ .../transformer/wireframeStyle.ts | 15 ++ 4 files changed, 206 insertions(+), 3 deletions(-) diff --git a/ee/frontend/mobile-replay/__snapshots__/transform.test.ts.snap b/ee/frontend/mobile-replay/__snapshots__/transform.test.ts.snap index 45a3fe627f7fa..e1ad7bc7a2ae2 100644 --- a/ee/frontend/mobile-replay/__snapshots__/transform.test.ts.snap +++ b/ee/frontend/mobile-replay/__snapshots__/transform.test.ts.snap @@ -1381,7 +1381,7 @@ exports[`replay/transform transform incremental mutations de-duplicate the tree "node": { "attributes": { "data-rrweb-id": 99571736, - "style": "color: #000000;width: 150px;height: 19px;position: fixed;left: 10px;top: 584px;align-items: flex-start;justify-content: flex-start;display: flex;font-size: 14px;font-family: sans-serif;overflow:hidden;white-space:normal;", + "style": "color: #000000;width: 150px;height: 19px;position: fixed;left: 10px;top: 584px;align-items: flex-start;justify-content: flex-start;display: flex;padding-left: 0px;padding-right: 0px;padding-top: 0px;padding-bottom: 0px;font-size: 14px;font-family: sans-serif;overflow:hidden;white-space:normal;", }, "childNodes": [], "id": 99571736, @@ -1404,7 +1404,7 @@ exports[`replay/transform transform incremental mutations de-duplicate the tree "node": { "attributes": { "data-rrweb-id": 240124529, - "style": "color: #000000;width: 48px;height: 32px;position: fixed;left: 10px;top: 548px;align-items: center;justify-content: center;display: flex;font-size: 14px;font-family: sans-serif;overflow:hidden;white-space:normal;", + "style": "color: #000000;width: 48px;height: 32px;position: fixed;left: 10px;top: 548px;align-items: center;justify-content: center;display: flex;padding-left: 32px;padding-right: 0px;padding-top: 6px;padding-bottom: 6px;font-size: 14px;font-family: sans-serif;overflow:hidden;white-space:normal;", }, "childNodes": [], "id": 240124529, @@ -1427,7 +1427,7 @@ exports[`replay/transform transform incremental mutations de-duplicate the tree "node": { "attributes": { "data-rrweb-id": 52129787, - "style": "color: #000000;width: 368px;height: 19px;position: fixed;left: 66px;top: 556px;align-items: flex-start;justify-content: flex-start;display: flex;font-size: 14px;font-family: sans-serif;overflow:hidden;white-space:normal;", + "style": "color: #000000;width: 368px;height: 19px;position: fixed;left: 66px;top: 556px;align-items: flex-start;justify-content: flex-start;display: flex;padding-left: 0px;padding-right: 0px;padding-top: 0px;padding-bottom: 0px;font-size: 14px;font-family: sans-serif;overflow:hidden;white-space:normal;", }, "childNodes": [], "id": 52129787, @@ -5421,6 +5421,149 @@ exports[`replay/transform transform inputs input - url - https://example.io 1`] } `; +exports[`replay/transform transform inputs input gets 0 padding by default but can be overridden 1`] = ` +{ + "data": { + "initialOffset": { + "left": 0, + "top": 0, + }, + "node": { + "childNodes": [ + { + "id": 2, + "name": "html", + "publicId": "", + "systemId": "", + "type": 1, + }, + { + "attributes": { + "data-rrweb-id": 3, + "style": "height: 100vh; width: 100vw;", + }, + "childNodes": [ + { + "attributes": { + "data-rrweb-id": 4, + }, + "childNodes": [ + { + "attributes": { + "type": "text/css", + }, + "childNodes": [ + { + "id": 101, + "textContent": " + body { + margin: unset; + } + input, button, select, textarea { + font: inherit; + margin: 0; + padding: 0; + border: 0; + outline: 0; + background: transparent; + } + .input:focus { + outline: none; + } + img { + border-style: none; + } + ", + "type": 3, + }, + ], + "id": 100, + "tagName": "style", + "type": 2, + }, + ], + "id": 4, + "tagName": "head", + "type": 2, + }, + { + "attributes": { + "data-rrweb-id": 5, + "style": "height: 100vh; width: 100vw;", + }, + "childNodes": [ + { + "attributes": { + "data-rrweb-id": 12359, + "style": "width: 100px;height: 30px;position: fixed;left: 0px;top: 0px;", + "type": "text", + "value": "", + }, + "childNodes": [], + "id": 12359, + "tagName": "input", + "type": 2, + }, + { + "attributes": { + "data-rrweb-id": 12361, + "style": "width: 100px;height: 30px;position: fixed;left: 0px;top: 0px;", + "type": "text", + "value": "", + }, + "childNodes": [], + "id": 12361, + "tagName": "input", + "type": 2, + }, + { + "attributes": { + "data-render-reason": "a fixed placeholder to contain the keyboard in the correct stacking position", + "data-rrweb-id": 9, + }, + "childNodes": [], + "id": 9, + "tagName": "div", + "type": 2, + }, + { + "attributes": { + "data-rrweb-id": 7, + }, + "childNodes": [], + "id": 7, + "tagName": "div", + "type": 2, + }, + { + "attributes": { + "data-rrweb-id": 11, + }, + "childNodes": [], + "id": 11, + "tagName": "div", + "type": 2, + }, + ], + "id": 5, + "tagName": "body", + "type": 2, + }, + ], + "id": 3, + "tagName": "html", + "type": 2, + }, + ], + "id": 1, + "type": 0, + }, + }, + "timestamp": 1, + "type": 2, +} +`; + exports[`replay/transform transform inputs isolated add mutation 1`] = ` { "data": { diff --git a/ee/frontend/mobile-replay/mobile.types.ts b/ee/frontend/mobile-replay/mobile.types.ts index f994dae58e076..a4b447d75235c 100644 --- a/ee/frontend/mobile-replay/mobile.types.ts +++ b/ee/frontend/mobile-replay/mobile.types.ts @@ -121,6 +121,22 @@ export type MobileStyles = { * @description maps to CSS font-family. Accepts any valid CSS font-family value. */ fontFamily?: string + /** + * @description maps to CSS padding-left. Expects a number (treated as pixels) or a string that is a number followed by px e.g. 16px + */ + paddingLeft?: string | number + /** + * @description maps to CSS padding-right. Expects a number (treated as pixels) or a string that is a number followed by px e.g. 16px + */ + paddingRight?: string | number + /** + * @description maps to CSS padding-top. Expects a number (treated as pixels) or a string that is a number followed by px e.g. 16px + */ + paddingTop?: string | number + /** + * @description maps to CSS padding-bottom. Expects a number (treated as pixels) or a string that is a number followed by px e.g. 16px + */ + paddingBottom?: string | number } type wireframeBase = { diff --git a/ee/frontend/mobile-replay/transform.test.ts b/ee/frontend/mobile-replay/transform.test.ts index 9e0ddf6b0e05e..98a8ffda3c756 100644 --- a/ee/frontend/mobile-replay/transform.test.ts +++ b/ee/frontend/mobile-replay/transform.test.ts @@ -535,6 +535,35 @@ describe('replay/transform', () => { }) describe('inputs', () => { + test('input gets 0 padding by default but can be overridden', () => { + expect( + posthogEEModule.mobileReplay?.transformEventToWeb({ + type: 2, + data: { + wireframes: [ + { + id: 12359, + width: 100, + height: 30, + type: 'input', + inputType: 'text', + }, + { + id: 12361, + width: 100, + height: 30, + type: 'input', + inputType: 'text', + paddingLeft: '16px', + paddingRight: 16, + }, + ], + }, + timestamp: 1, + }) + ).toMatchSnapshot() + }) + test('buttons with nested elements', () => { expect( posthogEEModule.mobileReplay?.transformEventToWeb({ diff --git a/ee/frontend/mobile-replay/transformer/wireframeStyle.ts b/ee/frontend/mobile-replay/transformer/wireframeStyle.ts index 4160070cbcfcd..ccd06bfcc662c 100644 --- a/ee/frontend/mobile-replay/transformer/wireframeStyle.ts +++ b/ee/frontend/mobile-replay/transformer/wireframeStyle.ts @@ -130,9 +130,24 @@ function makeLayoutStyles(wireframe: wireframe, styleOverride?: StyleOverride): }` ) } + if (styleParts.length) { styleParts.push(`display: flex`) } + + if (isUnitLike(combinedStyles.paddingLeft)) { + styleParts.push(`padding-left: ${ensureUnit(combinedStyles.paddingLeft)}`) + } + if (isUnitLike(combinedStyles.paddingRight)) { + styleParts.push(`padding-right: ${ensureUnit(combinedStyles.paddingRight)}`) + } + if (isUnitLike(combinedStyles.paddingTop)) { + styleParts.push(`padding-top: ${ensureUnit(combinedStyles.paddingTop)}`) + } + if (isUnitLike(combinedStyles.paddingBottom)) { + styleParts.push(`padding-bottom: ${ensureUnit(combinedStyles.paddingBottom)}`) + } + return asStyleString(styleParts) } From c1d91077e79890c254bad560a8a447839bb89340 Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Tue, 19 Mar 2024 20:26:51 +0000 Subject: [PATCH 2/3] fix --- .../mobile-replay/__snapshots__/transform.test.ts.snap | 2 +- ee/frontend/mobile-replay/transform.test.ts | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ee/frontend/mobile-replay/__snapshots__/transform.test.ts.snap b/ee/frontend/mobile-replay/__snapshots__/transform.test.ts.snap index e1ad7bc7a2ae2..889de23db5174 100644 --- a/ee/frontend/mobile-replay/__snapshots__/transform.test.ts.snap +++ b/ee/frontend/mobile-replay/__snapshots__/transform.test.ts.snap @@ -5507,7 +5507,7 @@ exports[`replay/transform transform inputs input gets 0 padding by default but c { "attributes": { "data-rrweb-id": 12361, - "style": "width: 100px;height: 30px;position: fixed;left: 0px;top: 0px;", + "style": "width: 100px;height: 30px;position: fixed;left: 0px;top: 0px;padding-left: 16px;padding-right: 16px;", "type": "text", "value": "", }, diff --git a/ee/frontend/mobile-replay/transform.test.ts b/ee/frontend/mobile-replay/transform.test.ts index 98a8ffda3c756..788bb65655d3d 100644 --- a/ee/frontend/mobile-replay/transform.test.ts +++ b/ee/frontend/mobile-replay/transform.test.ts @@ -58,6 +58,7 @@ describe('replay/transform', () => { beforeEach(async () => { posthogEEModule = await posthogEE() }) + test('can process unknown types without error', () => { expect( posthogEEModule.mobileReplay?.transformToWeb([ @@ -554,8 +555,10 @@ describe('replay/transform', () => { height: 30, type: 'input', inputType: 'text', - paddingLeft: '16px', - paddingRight: 16, + style: { + paddingLeft: '16px', + paddingRight: 16, + }, }, ], }, From f57298c0bde56f5a4c71560ea905372392521633 Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Tue, 19 Mar 2024 23:46:03 +0000 Subject: [PATCH 3/3] schema --- .../schema/mobile/rr-mobile-schema.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ee/frontend/mobile-replay/schema/mobile/rr-mobile-schema.json b/ee/frontend/mobile-replay/schema/mobile/rr-mobile-schema.json index 4dc7ea0dda0e2..49a0a0e613b48 100644 --- a/ee/frontend/mobile-replay/schema/mobile/rr-mobile-schema.json +++ b/ee/frontend/mobile-replay/schema/mobile/rr-mobile-schema.json @@ -334,6 +334,22 @@ "enum": ["left", "right", "center"], "type": "string" }, + "paddingBottom": { + "description": "maps to CSS padding-bottom. Expects a number (treated as pixels) or a string that is a number followed by px e.g. 16px", + "type": ["string", "number"] + }, + "paddingLeft": { + "description": "maps to CSS padding-left. Expects a number (treated as pixels) or a string that is a number followed by px e.g. 16px", + "type": ["string", "number"] + }, + "paddingRight": { + "description": "maps to CSS padding-right. Expects a number (treated as pixels) or a string that is a number followed by px e.g. 16px", + "type": ["string", "number"] + }, + "paddingTop": { + "description": "maps to CSS padding-top. Expects a number (treated as pixels) or a string that is a number followed by px e.g. 16px", + "type": ["string", "number"] + }, "verticalAlign": { "description": "vertical alignment with respect to its parent", "enum": ["top", "bottom", "center"],