From 74a6409b76c33125f706a412c2fc3b4a1b3104d4 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Wed, 15 Oct 2025 10:55:53 -0700 Subject: [PATCH 1/8] feat: add back icon assets for multiple resolutions and platforms --- src/inbox/assets/back-icon.png | Bin 0 -> 207 bytes src/inbox/assets/back-icon@1x.android.png | Bin 0 -> 100 bytes src/inbox/assets/back-icon@1x.ios.png | Bin 0 -> 290 bytes src/inbox/assets/back-icon@2x.android.png | Bin 0 -> 134 bytes src/inbox/assets/back-icon@2x.ios.png | Bin 0 -> 405 bytes src/inbox/assets/back-icon@3x.android.png | Bin 0 -> 167 bytes src/inbox/assets/back-icon@3x.ios.png | Bin 0 -> 761 bytes src/inbox/assets/back-icon@4x.android.png | Bin 0 -> 207 bytes src/inbox/assets/back-icon@4x.ios.png | Bin 0 -> 809 bytes 9 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/inbox/assets/back-icon.png create mode 100644 src/inbox/assets/back-icon@1x.android.png create mode 100644 src/inbox/assets/back-icon@1x.ios.png create mode 100644 src/inbox/assets/back-icon@2x.android.png create mode 100644 src/inbox/assets/back-icon@2x.ios.png create mode 100644 src/inbox/assets/back-icon@3x.android.png create mode 100644 src/inbox/assets/back-icon@3x.ios.png create mode 100644 src/inbox/assets/back-icon@4x.android.png create mode 100644 src/inbox/assets/back-icon@4x.ios.png diff --git a/src/inbox/assets/back-icon.png b/src/inbox/assets/back-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..17e52e8550e5668f7117bcb755beb70c3a21c9e9 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%xcgrg^$JhEy=Vy>(TP*-+rv1Kz7M z%I*XNJ!(VLzdH4Ge@o8ai4)e^3vK%P+bZq#{MQci z?P`C0d3kxcKa^1~`zt>B;jiLd|K_aKfAEz>edFmDy)D6SUw`+o@R*?B*u=sqq~bB* zgRIJrKN^lr3+tD}bFTI}~XjubmVU5CWQ(LZ;AgeuH{an^LB{Ts5E|^v% literal 0 HcmV?d00001 diff --git a/src/inbox/assets/back-icon@1x.android.png b/src/inbox/assets/back-icon@1x.android.png new file mode 100644 index 0000000000000000000000000000000000000000..083db295f474b9903408258c71818c2c49151d35 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1ZBG}+kP60RiDL^GIXr{@&3`D~ x%$9kI*}bEvW6`UVO)xQz+sFfYmle_k4J{c^Y-u@of;y~NbrRr@}xDqOoe#7(!ujI zW)IKPtpOg9x^ZGiV^G!WUnY384Jwg^1?qzoV?Vqi%~F-r131d0cdTWi1E3pVgr)a^ zbA?Lk#0WF#3+Yvg4uEz<4l(HmchxGX6;goJ^ovoWl9~bgne?yCQ=RAlXaeYC>D}3~ oOlpASO$!ea%F`=`*pIb34xO&@x>?fx0{{R307*qoM6N<$f~pOBr2qf` literal 0 HcmV?d00001 diff --git a/src/inbox/assets/back-icon@2x.android.png b/src/inbox/assets/back-icon@2x.android.png new file mode 100644 index 0000000000000000000000000000000000000000..6de0a1cbb365dfd5d9274890d243ca2321f32235 GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}tUr!gukP61P(+)Bo5D;KluXOkB z|6f;`Uoa>nrTyP5;4+Jm;dJDxe#>oP@r$y*#>rHDd13s5eN)8##R;WH*ZD4M;?i1i i;i&z7`QNqd4J-@3aX4v+{p181%;4$j=d#Wzp$P!F!7nZV literal 0 HcmV?d00001 diff --git a/src/inbox/assets/back-icon@2x.ios.png b/src/inbox/assets/back-icon@2x.ios.png new file mode 100644 index 0000000000000000000000000000000000000000..63de0e303aae4f3f09bbf5834290131501232f64 GIT binary patch literal 405 zcmV;G0c!q$3ng)KwR%cav2NeVj#yi|twB8nJ$ zhJ9XSgC81to-du2Xkr{|@HcXhBf~opLkgz`JWJYh7b%=;afNgn{8BUDujC*_hPNS> z7&ls+kwoI8u%elk7pg@(StZ8P4^;l-*^fZJ1`5~OHBd;D;qqM+{Bs~b$&5^qEx(K8 zx9Nf9ZEAjO1n+^rUo`oHziD{zE6kAXuYyr+hHU>u3T%dKe|C&IvG2#fso;0*pv4!B zOc_R!8Jq}55TlLyCq{c8swLA2SGn}>CsPgp4HtE6hRq5700000NkvXXu0mjfokp-j literal 0 HcmV?d00001 diff --git a/src/inbox/assets/back-icon@3x.android.png b/src/inbox/assets/back-icon@3x.android.png new file mode 100644 index 0000000000000000000000000000000000000000..15a983a67d97c9a6c39d91550a528c37c53a9e3e GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhaw@;qG}Ln;{G-aN{9*nr0&aBl6p z15q2fw>DO<$f$_t-m`#N(R0!@qfL6}is!BA-aP5mqcux*S)AYDzOuXc@WF!zU-mWw z!RNIrdq3B7GJgpV3USMNx+#Bt3lxOZSlm}!I$z&?|8f=2ODy@*gQAaCs?P@6%;4$j K=d#Wzp$P!X&_+4{ literal 0 HcmV?d00001 diff --git a/src/inbox/assets/back-icon@3x.ios.png b/src/inbox/assets/back-icon@3x.ios.png new file mode 100644 index 0000000000000000000000000000000000000000..2320fd74d1781dc8a74cc131d8c3bb17fc52bae4 GIT binary patch literal 761 zcmVAUlM5g1Q_DYVitMm-$7Tx z*ro&sTZ*z6>QNY&<*{MBLwj|YS(XqXD^V764Y9I1Okis$Okg8b+mr|wUq@l0HcEq; zVTpm+Kw?IyI+FyL&Ez%>QDU|-7*wFaOtGZEY$rQ2K-HNzTzn^q>8HU=v}CyWZt?*4 zR&^#h0``%e>7l`lw-g9CKz639sxv7OaEQQsKxaB>Fyky00*;WF4yw+iM!+!&6ScM) z%veiJ{LO>gk?HFakuuxmtTUZbi;r*1=ySHXQyoauVV}3fsCFdksL$Qv?Q2bBWbLdnCsmVuHOp65Sf{(`X7f(3UB_ENM%STv@ zvIOdikIG_Hb<}I(pkKw$XH%o9lBnz0zU=BVRS7|_2-Hp7L=H8o0zzIAXX+Lzml{=$ zMBTymK^Jb-%uZCPG}qfJds0JQ2XB$6bg6-+U-Ef=(TP*-+rv1Kz7M z%I*XNJ!(VLzdH4Ge@o8ai4)e^3vK%P+bZq#{MQci z?P`C0d3kxcKa^1~`zt>B;jiLd|K_aKfAEz>edFmDy)D6SUw`+o@R*?B*u=sqq~bB* zgRIJrKN^lr3+tD}bFTI}~XjubmVU5CWQ(LZ;AgeuH{an^LB{Ts5E|^v% literal 0 HcmV?d00001 diff --git a/src/inbox/assets/back-icon@4x.ios.png b/src/inbox/assets/back-icon@4x.ios.png new file mode 100644 index 0000000000000000000000000000000000000000..b26634e594135d181375c3316b2ce059a31c6665 GIT binary patch literal 809 zcmV+^1J?YBP)YD1miR7mE{DV$Qg{||{bo~dA%(lFKsoPR23s4@v0mrvvjQGomaY7ADLDuqH1 zvGK4`4{>#jmgPlOeM+>Mf_`%D1%nu+I@RZN_76>V5WO1tOIiKYhsr9>jYgGKs=`*N zv}jyyRB5p)?goPB+{p5Jb-|H(#biuZo$8V=bj@m<&Aw*Mzvy;mD@cB;LBZVYApQ(D zdpPq|r)sw;OT$xM%b9U3xD%GW6CGq63GPHqLE>$f#-ZTp)T|)+jjzs91<7wcE?A); z`OV+XYNgUb`*8ccu~0$s2Ow%Rm0<*BXJiDW8UkwI7}mD<7*>7|TUr^wfilifZVG;4 n@$E^mUzjZzWv9I6RnQJ~H00000NkvXXu0mjf?i-Uu literal 0 HcmV?d00001 From 4308017aeb447334ccaac64e356b64b7a09cf4d9 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Wed, 15 Oct 2025 10:56:22 -0700 Subject: [PATCH 2/8] refactor: add HeaderBackButton component and integrate it into IterableInboxMessageDisplay --- src/inbox/components/HeaderBackButton.tsx | 39 +++++++++++++++++++ .../IterableInboxMessageDisplay.tsx | 12 +++++- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/inbox/components/HeaderBackButton.tsx diff --git a/src/inbox/components/HeaderBackButton.tsx b/src/inbox/components/HeaderBackButton.tsx new file mode 100644 index 000000000..e46948050 --- /dev/null +++ b/src/inbox/components/HeaderBackButton.tsx @@ -0,0 +1,39 @@ +import { + StyleSheet, + Text, + TouchableWithoutFeedback, + View, + type TouchableWithoutFeedbackProps, +} from 'react-native'; +import { Icon } from 'react-native-vector-icons/Icon'; +import { ITERABLE_INBOX_COLORS } from '../constants/colors'; + +const styles = StyleSheet.create({ + + returnButton: { + alignItems: 'center', + flexDirection: 'row', + }, + + returnButtonIcon: { + color: ITERABLE_INBOX_COLORS.BUTTON_PRIMARY_TEXT, + fontSize: 40, + paddingLeft: 0, + }, + + returnButtonText: { + color: ITERABLE_INBOX_COLORS.BUTTON_PRIMARY_TEXT, + fontSize: 20, + }, +}); + +export const HeaderBackButton = (props: TouchableWithoutFeedbackProps) => { + return ( + + + + Inbox + + + ); +}; diff --git a/src/inbox/components/IterableInboxMessageDisplay.tsx b/src/inbox/components/IterableInboxMessageDisplay.tsx index 7e6798c73..6799dafea 100644 --- a/src/inbox/components/IterableInboxMessageDisplay.tsx +++ b/src/inbox/components/IterableInboxMessageDisplay.tsx @@ -23,9 +23,9 @@ import { IterableInAppCloseSource, IterableInAppLocation, } from '../../inApp'; - import { ITERABLE_INBOX_COLORS } from '../constants'; import { type IterableInboxRowViewModel } from '../types'; +import { HeaderBackButton } from './HeaderBackButton'; /** * Props for the IterableInboxMessageDisplay component. @@ -222,6 +222,16 @@ export const IterableInboxMessageDisplay = ({ + { + returnToInbox(); + Iterable.trackInAppClose( + rowViewModel.inAppMessage, + IterableInAppLocation.inbox, + IterableInAppCloseSource.back + ); + }} + /> { returnToInbox(); From 2c9a954bf9f0656540f5f3bb3b2268cc5dcb46b3 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Wed, 15 Oct 2025 13:24:19 -0700 Subject: [PATCH 3/8] refactor: create HeaderBackButton and replace back-arrow --- src/inbox/components/HeaderBackButton.tsx | 75 ++++++++++++++++--- .../IterableInboxMessageDisplay.tsx | 39 +--------- 2 files changed, 68 insertions(+), 46 deletions(-) diff --git a/src/inbox/components/HeaderBackButton.tsx b/src/inbox/components/HeaderBackButton.tsx index e46948050..15687ac4e 100644 --- a/src/inbox/components/HeaderBackButton.tsx +++ b/src/inbox/components/HeaderBackButton.tsx @@ -1,38 +1,93 @@ import { + Image, + PixelRatio, + Platform, StyleSheet, Text, TouchableWithoutFeedback, View, + type ImageSourcePropType, type TouchableWithoutFeedbackProps, } from 'react-native'; -import { Icon } from 'react-native-vector-icons/Icon'; import { ITERABLE_INBOX_COLORS } from '../constants/colors'; +// Base64 encoded back arrow icons +// [Original image](https://github.com/react-navigation/react-navigation/blob/main/packages/elements/src/assets/back-icon%404x.ios.png) +const backArrowLarge = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAABUCAYAAADEZ7TLAAAC8ElEQVR42u2bWchOaxTH/xfnHMcZnHkwRobwJfdIkkSSkpKSEikREcla+81X5tR34c61O8kQIknmKUnGyCzzjczzz817Kfm+9dbasn/13P/X/1n72XuvZy2VGmeQnA1yrsh4LGe/DNda2qnUNPOdjBY572XwiXVeNZpUStbxvZyNMvjsci7Ud6Jk4o3NMvjCVStT2vwgY2srxCPnYHnEO9tl0Mr1WOmspZ2cHTJow7qY7fyPcnbJoI1rvdJoob2M3QHxr9RM/yznf5KxJyAeOQsyxe8NiS9YpRTW8LOMfUHnl2c5/4uMA0HnlymF1fwq53BIvLEky/kOco4G06ZQCqv4Tc7xoPOLs5z/XcaJoPhFSmElf8g5+XWe8yv4S86p4GkzLytt/pZzOuj8nCzn/5FzJuj8rCzn/5VzLiD+gwpmKoXl/CfjfEi8M0MpGB1lXAw6Py0rbTrJuBR4WN+rYGqW+C5yLofEG1OUgtNVzpVA2rxTjclZzneTcy0k3pmUJb67jOuBtHkrZ6JSKOgh42ZIfMGELPE95dwKpM0bFYzPEt9bxu2QeGdcVs73kXEnkDav5YzNEt9Xzt1Q0ckYkyW+v4z7QfGjlUKNJjkPAmnzUgUjs8QPkPEw4PwLFYzIEj9QzqOA889VMDwr5/8PiTeeqWCY0jDWB5x/KmeoMgkcl0/kDFGA/ABqDFadKoVCD7HxsFEPcXWMluVFVn1KtJmCfnLuBYMYpTrV53T2D012EL0a+UtZ/dSHyirOjUaVVarCVqi0aFxtVGmxKu4GgujcyPJ6dcGResVkTFed6pIvdM1qnM2+Zs2/6HZmK0h+q0HB3Owg/gw3ezjzVadqtylLw1Ney5lxLLgTlr0THWQcCe5ETUHibZfGoeDp1Kwg+Y2vzlIFyW89LlihIPnN385qpdJC+3D7vbFQQfIHIGo0lWEEZWdkBKUaAmrgGNa2+BhWfhBbWhnAgTLOUW4KfmLkT7K2Zhi0GsetBqK/dT4Csa/f2ZlrPiMAAAAASUVORK5CYII='; + +export const ICON_SIZE = Platform.OS === 'ios' ? 21 : 24; +export const ICON_MARGIN = Platform.OS === 'ios' ? 8 : 3; +const ICON_COLOR = ITERABLE_INBOX_COLORS.BUTTON_PRIMARY_TEXT; + const styles = StyleSheet.create({ + icon: { + height: ICON_SIZE, + margin: ICON_MARGIN, + width: ICON_SIZE, + }, returnButton: { alignItems: 'center', + display: 'flex', flexDirection: 'row', }, - returnButtonIcon: { - color: ITERABLE_INBOX_COLORS.BUTTON_PRIMARY_TEXT, - fontSize: 40, - paddingLeft: 0, - }, - returnButtonText: { color: ITERABLE_INBOX_COLORS.BUTTON_PRIMARY_TEXT, fontSize: 20, }, }); -export const HeaderBackButton = (props: TouchableWithoutFeedbackProps) => { +/** + * Props for the HeaderBackButton component. + */ +export interface HeaderBackButtonProps extends TouchableWithoutFeedbackProps { + /** + * The text to display next to the back arrow. + */ + label?: string; + /** + * The URI of the image to display. + * + * This defaults to a base64 encoded version of [the back arrow used in react-navigation/elements](https://github.com/react-navigation/react-navigation/blob/main/packages/elements/src/assets/back-icon%404x.ios.png) + */ + imageUri?: string; + /** + * The source of the image to display. + */ + imageSource?: ImageSourcePropType; +} + +/** + * A back arrow button used in a header + * + * @returns A button with a back arrow + */ +export const HeaderBackButton = ({ + label, + imageUri = backArrowLarge, + imageSource = { + uri: imageUri, + width: PixelRatio.getPixelSizeForLayoutSize(ICON_SIZE), + height: PixelRatio.getPixelSizeForLayoutSize(ICON_SIZE), + }, + ...props +}: HeaderBackButtonProps) => { return ( - - Inbox + + {label && {label}} ); diff --git a/src/inbox/components/IterableInboxMessageDisplay.tsx b/src/inbox/components/IterableInboxMessageDisplay.tsx index 6799dafea..d42306a04 100644 --- a/src/inbox/components/IterableInboxMessageDisplay.tsx +++ b/src/inbox/components/IterableInboxMessageDisplay.tsx @@ -1,13 +1,12 @@ import { useEffect, useState } from 'react'; import { Linking, + Platform, ScrollView, StyleSheet, Text, - TouchableWithoutFeedback, View, } from 'react-native'; -import Icon from 'react-native-vector-icons/Ionicons'; import { WebView, type WebViewMessageEvent } from 'react-native-webview'; import { @@ -86,6 +85,7 @@ export const IterableInboxMessageDisplay = ({ header: { flexDirection: 'row', + height: Platform.OS === 'ios' ? 44 : 56, justifyContent: 'center', width: '100%', }, @@ -119,11 +119,6 @@ export const IterableInboxMessageDisplay = ({ fontWeight: 'bold', }, - returnButton: { - alignItems: 'center', - flexDirection: 'row', - }, - returnButtonContainer: { alignItems: 'center', flexDirection: 'row', @@ -133,17 +128,6 @@ export const IterableInboxMessageDisplay = ({ width: '25%', ...(isPortrait ? {} : { marginLeft: 80 }), }, - - returnButtonIcon: { - color: ITERABLE_INBOX_COLORS.BUTTON_PRIMARY_TEXT, - fontSize: 40, - paddingLeft: 0, - }, - - returnButtonText: { - color: ITERABLE_INBOX_COLORS.BUTTON_PRIMARY_TEXT, - fontSize: 20, - }, }); const JS = ` @@ -223,6 +207,7 @@ export const IterableInboxMessageDisplay = ({ { returnToInbox(); Iterable.trackInAppClose( @@ -232,24 +217,6 @@ export const IterableInboxMessageDisplay = ({ ); }} /> - { - returnToInbox(); - Iterable.trackInAppClose( - rowViewModel.inAppMessage, - IterableInAppLocation.inbox, - IterableInAppCloseSource.back - ); - }} - > - - - Inbox - - From 9bf11789bc9c7fc0eeaa8750964a9dba4bea2a87 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Wed, 15 Oct 2025 13:24:39 -0700 Subject: [PATCH 4/8] chore: add prettier-eslint and update dependencies in package.json and yarn.lock --- package.json | 1 + yarn.lock | 253 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 249 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ef832a4ad..c3e1dfc52 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "eslint-plugin-tsdoc": "^0.3.0", "jest": "^29.7.0", "prettier": "^3.0.3", + "prettier-eslint": "^16.4.2", "react": "19.0.0", "react-native": "0.79.3", "react-native-builder-bob": "^0.40.4", diff --git a/yarn.lock b/yarn.lock index d9961ac53..ea98be24c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3142,6 +3142,7 @@ __metadata: eslint-plugin-tsdoc: ^0.3.0 jest: ^29.7.0 prettier: ^3.0.3 + prettier-eslint: ^16.4.2 react: 19.0.0 react-native: 0.79.3 react-native-builder-bob: ^0.40.4 @@ -4750,6 +4751,24 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/parser@npm:^6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/parser@npm:6.21.0" + dependencies: + "@typescript-eslint/scope-manager": 6.21.0 + "@typescript-eslint/types": 6.21.0 + "@typescript-eslint/typescript-estree": 6.21.0 + "@typescript-eslint/visitor-keys": 6.21.0 + debug: ^4.3.4 + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 162fe3a867eeeffda7328bce32dae45b52283c68c8cb23258fb9f44971f761991af61f71b8c9fe1aa389e93dfe6386f8509c1273d870736c507d76dd40647b68 + languageName: node + linkType: hard + "@typescript-eslint/parser@npm:^7.1.1": version: 7.18.0 resolution: "@typescript-eslint/parser@npm:7.18.0" @@ -4796,6 +4815,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/scope-manager@npm:6.21.0" + dependencies: + "@typescript-eslint/types": 6.21.0 + "@typescript-eslint/visitor-keys": 6.21.0 + checksum: 71028b757da9694528c4c3294a96cc80bc7d396e383a405eab3bc224cda7341b88e0fc292120b35d3f31f47beac69f7083196c70616434072fbcd3d3e62d3376 + languageName: node + linkType: hard + "@typescript-eslint/scope-manager@npm:7.18.0": version: 7.18.0 resolution: "@typescript-eslint/scope-manager@npm:7.18.0" @@ -4855,6 +4884,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/types@npm:6.21.0" + checksum: 9501b47d7403417af95fc1fb72b2038c5ac46feac0e1598a46bcb43e56a606c387e9dcd8a2a0abe174c91b509f2d2a8078b093786219eb9a01ab2fbf9ee7b684 + languageName: node + linkType: hard + "@typescript-eslint/types@npm:7.18.0": version: 7.18.0 resolution: "@typescript-eslint/types@npm:7.18.0" @@ -4887,6 +4923,25 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.21.0" + dependencies: + "@typescript-eslint/types": 6.21.0 + "@typescript-eslint/visitor-keys": 6.21.0 + debug: ^4.3.4 + globby: ^11.1.0 + is-glob: ^4.0.3 + minimatch: 9.0.3 + semver: ^7.5.4 + ts-api-utils: ^1.0.1 + peerDependenciesMeta: + typescript: + optional: true + checksum: dec02dc107c4a541e14fb0c96148f3764b92117c3b635db3a577b5a56fc48df7a556fa853fb82b07c0663b4bf2c484c9f245c28ba3e17e5cb0918ea4cab2ea21 + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:7.18.0": version: 7.18.0 resolution: "@typescript-eslint/typescript-estree@npm:7.18.0" @@ -4981,6 +5036,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.21.0" + dependencies: + "@typescript-eslint/types": 6.21.0 + eslint-visitor-keys: ^3.4.1 + checksum: 67c7e6003d5af042d8703d11538fca9d76899f0119130b373402819ae43f0bc90d18656aa7add25a24427ccf1a0efd0804157ba83b0d4e145f06107d7d1b7433 + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:7.18.0": version: 7.18.0 resolution: "@typescript-eslint/visitor-keys@npm:7.18.0" @@ -5186,6 +5251,13 @@ __metadata: languageName: node linkType: hard +"ansi-regex@npm:^2.0.0": + version: 2.1.1 + resolution: "ansi-regex@npm:2.1.1" + checksum: 190abd03e4ff86794f338a31795d262c1dfe8c91f7e01d04f13f646f1dcb16c5800818f886047876f1272f065570ab86b24b99089f8b68a0e11ff19aed4ca8f1 + languageName: node + linkType: hard + "ansi-regex@npm:^4.1.0": version: 4.1.1 resolution: "ansi-regex@npm:4.1.1" @@ -5207,6 +5279,13 @@ __metadata: languageName: node linkType: hard +"ansi-styles@npm:^2.2.1": + version: 2.2.1 + resolution: "ansi-styles@npm:2.2.1" + checksum: ebc0e00381f2a29000d1dac8466a640ce11943cef3bda3cd0020dc042e31e1058ab59bf6169cd794a54c3a7338a61ebc404b7c91e004092dd20e028c432c9c2c + languageName: node + linkType: hard + "ansi-styles@npm:^3.2.0, ansi-styles@npm:^3.2.1": version: 3.2.1 resolution: "ansi-styles@npm:3.2.1" @@ -5916,6 +5995,19 @@ __metadata: languageName: node linkType: hard +"chalk@npm:^1.1.3": + version: 1.1.3 + resolution: "chalk@npm:1.1.3" + dependencies: + ansi-styles: ^2.2.1 + escape-string-regexp: ^1.0.2 + has-ansi: ^2.0.0 + strip-ansi: ^3.0.0 + supports-color: ^2.0.0 + checksum: 9d2ea6b98fc2b7878829eec223abcf404622db6c48396a9b9257f6d0ead2acf18231ae368d6a664a83f272b0679158da12e97b5229f794939e555cc574478acd + languageName: node + linkType: hard + "chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -6222,6 +6314,13 @@ __metadata: languageName: node linkType: hard +"common-tags@npm:^1.8.2": + version: 1.8.2 + resolution: "common-tags@npm:1.8.2" + checksum: 767a6255a84bbc47df49a60ab583053bb29a7d9687066a18500a516188a062c4e4cd52de341f22de0b07062e699b1b8fe3cfa1cb55b241cb9301aeb4f45b4dff + languageName: node + linkType: hard + "compare-func@npm:^2.0.0": version: 2.0.0 resolution: "compare-func@npm:2.0.0" @@ -6937,6 +7036,13 @@ __metadata: languageName: node linkType: hard +"dlv@npm:^1.1.3": + version: 1.1.3 + resolution: "dlv@npm:1.1.3" + checksum: d7381bca22ed11933a1ccf376db7a94bee2c57aa61e490f680124fa2d1cd27e94eba641d9f45be57caab4f9a6579de0983466f620a2cd6230d7ec93312105ae7 + languageName: node + linkType: hard + "doctrine@npm:^2.1.0": version: 2.1.0 resolution: "doctrine@npm:2.1.0" @@ -7293,7 +7399,7 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:^1.0.5": +"escape-string-regexp@npm:^1.0.2, escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" checksum: 6092fda75c63b110c706b6a9bfde8a612ad595b628f0bd2147eea1d3406723020810e591effc7db1da91d80a71a737a313567c5abb3813e8d9c71f4aa595b410 @@ -7510,7 +7616,7 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^7.2.2": +"eslint-scope@npm:^7.1.1, eslint-scope@npm:^7.2.2": version: 7.2.2 resolution: "eslint-scope@npm:7.2.2" dependencies: @@ -7534,7 +7640,7 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8.51.0": +"eslint@npm:^8.51.0, eslint@npm:^8.57.1": version: 8.57.1 resolution: "eslint@npm:8.57.1" dependencies: @@ -7582,7 +7688,7 @@ __metadata: languageName: node linkType: hard -"espree@npm:^9.6.0, espree@npm:^9.6.1": +"espree@npm:^9.3.1, espree@npm:^9.6.0, espree@npm:^9.6.1": version: 9.6.1 resolution: "espree@npm:9.6.1" dependencies: @@ -7603,7 +7709,7 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.4.2": +"esquery@npm:^1.4.0, esquery@npm:^1.4.2": version: 1.6.0 resolution: "esquery@npm:1.6.0" dependencies: @@ -8419,6 +8525,15 @@ __metadata: languageName: node linkType: hard +"has-ansi@npm:^2.0.0": + version: 2.0.0 + resolution: "has-ansi@npm:2.0.0" + dependencies: + ansi-regex: ^2.0.0 + checksum: 1b51daa0214440db171ff359d0a2d17bc20061164c57e76234f614c91dbd2a79ddd68dfc8ee73629366f7be45a6df5f2ea9de83f52e1ca24433f2cc78c35d8ec + languageName: node + linkType: hard + "has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": version: 1.0.2 resolution: "has-bigints@npm:1.0.2" @@ -10427,6 +10542,23 @@ __metadata: languageName: node linkType: hard +"loglevel-colored-level-prefix@npm:^1.0.0": + version: 1.0.0 + resolution: "loglevel-colored-level-prefix@npm:1.0.0" + dependencies: + chalk: ^1.1.3 + loglevel: ^1.4.1 + checksum: 146aa7d0ea900d6d8523e945b2265be240e4c7c4752dae678983764dd756c44194684af1ee8ea721feff4c4f8c5771544a02a6cd8b269a663cffe9b4fcf955f1 + languageName: node + linkType: hard + +"loglevel@npm:^1.4.1": + version: 1.9.2 + resolution: "loglevel@npm:1.9.2" + checksum: 896c67b90a507bfcfc1e9a4daa7bf789a441dd70d95cd13b998d6dd46233a3bfadfb8fadb07250432bbfb53bf61e95f2520f9b11f9d3175cc460e5c251eca0af + languageName: node + linkType: hard + "loose-envify@npm:^1.0.0, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" @@ -11164,6 +11296,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:9.0.3": + version: 9.0.3 + resolution: "minimatch@npm:9.0.3" + dependencies: + brace-expansion: ^2.0.1 + checksum: 253487976bf485b612f16bf57463520a14f512662e592e95c571afdab1442a6a6864b6c88f248ce6fc4ff0b6de04ac7aa6c8bb51e868e99d1d65eb0658a708b5 + languageName: node + linkType: hard + "minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -12097,6 +12238,34 @@ __metadata: languageName: node linkType: hard +"prettier-eslint@npm:^16.4.2": + version: 16.4.2 + resolution: "prettier-eslint@npm:16.4.2" + dependencies: + "@typescript-eslint/parser": ^6.21.0 + common-tags: ^1.8.2 + dlv: ^1.1.3 + eslint: ^8.57.1 + indent-string: ^4.0.0 + lodash.merge: ^4.6.2 + loglevel-colored-level-prefix: ^1.0.0 + prettier: ^3.5.3 + pretty-format: ^29.7.0 + require-relative: ^0.8.7 + tslib: ^2.8.1 + vue-eslint-parser: ^9.4.3 + peerDependencies: + prettier-plugin-svelte: ^3.0.0 + svelte-eslint-parser: "*" + peerDependenciesMeta: + prettier-plugin-svelte: + optional: true + svelte-eslint-parser: + optional: true + checksum: ad420f2d3b6f0c055e0eefed2f32876e4ac29d5c0202778ae531438224c7d07b67dcfb64054bc61a0cc88f231988198f229395361a9b2112ad048d08b6d5bc80 + languageName: node + linkType: hard + "prettier-linter-helpers@npm:^1.0.0": version: 1.0.0 resolution: "prettier-linter-helpers@npm:1.0.0" @@ -12115,6 +12284,15 @@ __metadata: languageName: node linkType: hard +"prettier@npm:^3.5.3": + version: 3.6.2 + resolution: "prettier@npm:3.6.2" + bin: + prettier: bin/prettier.cjs + checksum: 0206f5f437892e8858f298af8850bf9d0ef1c22e21107a213ba56bfb9c2387a2020bfda244a20161d8e3dad40c6b04101609a55d370dece53d0a31893b64f861 + languageName: node + linkType: hard + "pretty-format@npm:30.2.0, pretty-format@npm:^30.0.5": version: 30.2.0 resolution: "pretty-format@npm:30.2.0" @@ -12999,6 +13177,13 @@ __metadata: languageName: node linkType: hard +"require-relative@npm:^0.8.7": + version: 0.8.7 + resolution: "require-relative@npm:0.8.7" + checksum: f1c3be06977823bba43600344d9ea6fbf8a55bdb81ec76533126849ab4024e6c31c6666f37fa4b5cfeda9c41dee89b8e19597cac02bdefaab42255c6708661ab + languageName: node + linkType: hard + "reselect@npm:^4.1.7": version: 4.1.8 resolution: "reselect@npm:4.1.8" @@ -13274,6 +13459,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.3.6": + version: 7.7.3 + resolution: "semver@npm:7.7.3" + bin: + semver: bin/semver.js + checksum: f013a3ee4607857bcd3503b6ac1d80165f7f8ea94f5d55e2d3e33df82fce487aa3313b987abf9b39e0793c83c9fc67b76c36c067625141a9f6f704ae0ea18db2 + languageName: node + linkType: hard + "semver@npm:^7.6.3": version: 7.7.2 resolution: "semver@npm:7.7.2" @@ -13818,6 +14012,15 @@ __metadata: languageName: node linkType: hard +"strip-ansi@npm:^3.0.0": + version: 3.0.1 + resolution: "strip-ansi@npm:3.0.1" + dependencies: + ansi-regex: ^2.0.0 + checksum: 9b974de611ce5075c70629c00fa98c46144043db92ae17748fb780f706f7a789e9989fd10597b7c2053ae8d1513fd707816a91f1879b2f71e6ac0b6a863db465 + languageName: node + linkType: hard + "strip-ansi@npm:^5.0.0": version: 5.2.0 resolution: "strip-ansi@npm:5.2.0" @@ -13903,6 +14106,13 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:^2.0.0": + version: 2.0.0 + resolution: "supports-color@npm:2.0.0" + checksum: 602538c5812b9006404370b5a4b885d3e2a1f6567d314f8b4a41974ffe7d08e525bf92ae0f9c7030e3b4c78e4e34ace55d6a67a74f1571bc205959f5972f88f0 + languageName: node + linkType: hard + "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -14077,6 +14287,15 @@ __metadata: languageName: node linkType: hard +"ts-api-utils@npm:^1.0.1": + version: 1.4.3 + resolution: "ts-api-utils@npm:1.4.3" + peerDependencies: + typescript: ">=4.2.0" + checksum: ea00dee382d19066b2a3d8929f1089888b05fec797e32e7a7004938eda1dccf2e77274ee2afcd4166f53fab9b8d7ee90ebb225a3183f9ba8817d636f688a148d + languageName: node + linkType: hard + "ts-api-utils@npm:^1.3.0": version: 1.4.0 resolution: "ts-api-utils@npm:1.4.0" @@ -14100,6 +14319,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:^2.8.1": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a + languageName: node + linkType: hard + "tsutils@npm:^3.21.0": version: 3.21.0 resolution: "tsutils@npm:3.21.0" @@ -14630,6 +14856,23 @@ __metadata: languageName: node linkType: hard +"vue-eslint-parser@npm:^9.4.3": + version: 9.4.3 + resolution: "vue-eslint-parser@npm:9.4.3" + dependencies: + debug: ^4.3.4 + eslint-scope: ^7.1.1 + eslint-visitor-keys: ^3.3.0 + espree: ^9.3.1 + esquery: ^1.4.0 + lodash: ^4.17.21 + semver: ^7.3.6 + peerDependencies: + eslint: ">=6.0.0" + checksum: 8d5b7ef7c5ee264ca2ba78da4b95ac7a66175a458d153a35e92cd7c55b794db0f2c31a8fdd40021bab4496f2f64ab80d7dbb6dccff4103beb4564c439a88fa42 + languageName: node + linkType: hard + "walker@npm:^1.0.7, walker@npm:^1.0.8": version: 1.0.8 resolution: "walker@npm:1.0.8" From 0e1bb0411c0a97ba335b80ad0699645ecbebfbb6 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Wed, 15 Oct 2025 13:25:17 -0700 Subject: [PATCH 5/8] chore: remove unused back icon assets for various resolutions and platforms --- src/inbox/assets/back-icon.png | Bin 207 -> 0 bytes src/inbox/assets/back-icon@1x.android.png | Bin 100 -> 0 bytes src/inbox/assets/back-icon@1x.ios.png | Bin 290 -> 0 bytes src/inbox/assets/back-icon@2x.android.png | Bin 134 -> 0 bytes src/inbox/assets/back-icon@2x.ios.png | Bin 405 -> 0 bytes src/inbox/assets/back-icon@3x.android.png | Bin 167 -> 0 bytes src/inbox/assets/back-icon@3x.ios.png | Bin 761 -> 0 bytes src/inbox/assets/back-icon@4x.android.png | Bin 207 -> 0 bytes src/inbox/assets/back-icon@4x.ios.png | Bin 809 -> 0 bytes 9 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/inbox/assets/back-icon.png delete mode 100644 src/inbox/assets/back-icon@1x.android.png delete mode 100644 src/inbox/assets/back-icon@1x.ios.png delete mode 100644 src/inbox/assets/back-icon@2x.android.png delete mode 100644 src/inbox/assets/back-icon@2x.ios.png delete mode 100644 src/inbox/assets/back-icon@3x.android.png delete mode 100644 src/inbox/assets/back-icon@3x.ios.png delete mode 100644 src/inbox/assets/back-icon@4x.android.png delete mode 100644 src/inbox/assets/back-icon@4x.ios.png diff --git a/src/inbox/assets/back-icon.png b/src/inbox/assets/back-icon.png deleted file mode 100644 index 17e52e8550e5668f7117bcb755beb70c3a21c9e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%xcgrg^$JhEy=Vy>(TP*-+rv1Kz7M z%I*XNJ!(VLzdH4Ge@o8ai4)e^3vK%P+bZq#{MQci z?P`C0d3kxcKa^1~`zt>B;jiLd|K_aKfAEz>edFmDy)D6SUw`+o@R*?B*u=sqq~bB* zgRIJrKN^lr3+tD}bFTI}~XjubmVU5CWQ(LZ;AgeuH{an^LB{Ts5E|^v% diff --git a/src/inbox/assets/back-icon@1x.android.png b/src/inbox/assets/back-icon@1x.android.png deleted file mode 100644 index 083db295f474b9903408258c71818c2c49151d35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1ZBG}+kP60RiDL^GIXr{@&3`D~ x%$9kI*}bEvW6`UVO)xQz+sFfYmle_k4J{c^Y-u@of;y~NbrRr@}xDqOoe#7(!ujI zW)IKPtpOg9x^ZGiV^G!WUnY384Jwg^1?qzoV?Vqi%~F-r131d0cdTWi1E3pVgr)a^ zbA?Lk#0WF#3+Yvg4uEz<4l(HmchxGX6;goJ^ovoWl9~bgne?yCQ=RAlXaeYC>D}3~ oOlpASO$!ea%F`=`*pIb34xO&@x>?fx0{{R307*qoM6N<$f~pOBr2qf` diff --git a/src/inbox/assets/back-icon@2x.android.png b/src/inbox/assets/back-icon@2x.android.png deleted file mode 100644 index 6de0a1cbb365dfd5d9274890d243ca2321f32235..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}tUr!gukP61P(+)Bo5D;KluXOkB z|6f;`Uoa>nrTyP5;4+Jm;dJDxe#>oP@r$y*#>rHDd13s5eN)8##R;WH*ZD4M;?i1i i;i&z7`QNqd4J-@3aX4v+{p181%;4$j=d#Wzp$P!F!7nZV diff --git a/src/inbox/assets/back-icon@2x.ios.png b/src/inbox/assets/back-icon@2x.ios.png deleted file mode 100644 index 63de0e303aae4f3f09bbf5834290131501232f64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 405 zcmV;G0c!q$3ng)KwR%cav2NeVj#yi|twB8nJ$ zhJ9XSgC81to-du2Xkr{|@HcXhBf~opLkgz`JWJYh7b%=;afNgn{8BUDujC*_hPNS> z7&ls+kwoI8u%elk7pg@(StZ8P4^;l-*^fZJ1`5~OHBd;D;qqM+{Bs~b$&5^qEx(K8 zx9Nf9ZEAjO1n+^rUo`oHziD{zE6kAXuYyr+hHU>u3T%dKe|C&IvG2#fso;0*pv4!B zOc_R!8Jq}55TlLyCq{c8swLA2SGn}>CsPgp4HtE6hRq5700000NkvXXu0mjfokp-j diff --git a/src/inbox/assets/back-icon@3x.android.png b/src/inbox/assets/back-icon@3x.android.png deleted file mode 100644 index 15a983a67d97c9a6c39d91550a528c37c53a9e3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhaw@;qG}Ln;{G-aN{9*nr0&aBl6p z15q2fw>DO<$f$_t-m`#N(R0!@qfL6}is!BA-aP5mqcux*S)AYDzOuXc@WF!zU-mWw z!RNIrdq3B7GJgpV3USMNx+#Bt3lxOZSlm}!I$z&?|8f=2ODy@*gQAaCs?P@6%;4$j K=d#Wzp$P!X&_+4{ diff --git a/src/inbox/assets/back-icon@3x.ios.png b/src/inbox/assets/back-icon@3x.ios.png deleted file mode 100644 index 2320fd74d1781dc8a74cc131d8c3bb17fc52bae4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 761 zcmVAUlM5g1Q_DYVitMm-$7Tx z*ro&sTZ*z6>QNY&<*{MBLwj|YS(XqXD^V764Y9I1Okis$Okg8b+mr|wUq@l0HcEq; zVTpm+Kw?IyI+FyL&Ez%>QDU|-7*wFaOtGZEY$rQ2K-HNzTzn^q>8HU=v}CyWZt?*4 zR&^#h0``%e>7l`lw-g9CKz639sxv7OaEQQsKxaB>Fyky00*;WF4yw+iM!+!&6ScM) z%veiJ{LO>gk?HFakuuxmtTUZbi;r*1=ySHXQyoauVV}3fsCFdksL$Qv?Q2bBWbLdnCsmVuHOp65Sf{(`X7f(3UB_ENM%STv@ zvIOdikIG_Hb<}I(pkKw$XH%o9lBnz0zU=BVRS7|_2-Hp7L=H8o0zzIAXX+Lzml{=$ zMBTymK^Jb-%uZCPG}qfJds0JQ2XB$6bg6-+U-Ef=(TP*-+rv1Kz7M z%I*XNJ!(VLzdH4Ge@o8ai4)e^3vK%P+bZq#{MQci z?P`C0d3kxcKa^1~`zt>B;jiLd|K_aKfAEz>edFmDy)D6SUw`+o@R*?B*u=sqq~bB* zgRIJrKN^lr3+tD}bFTI}~XjubmVU5CWQ(LZ;AgeuH{an^LB{Ts5E|^v% diff --git a/src/inbox/assets/back-icon@4x.ios.png b/src/inbox/assets/back-icon@4x.ios.png deleted file mode 100644 index b26634e594135d181375c3316b2ce059a31c6665..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 809 zcmV+^1J?YBP)YD1miR7mE{DV$Qg{||{bo~dA%(lFKsoPR23s4@v0mrvvjQGomaY7ADLDuqH1 zvGK4`4{>#jmgPlOeM+>Mf_`%D1%nu+I@RZN_76>V5WO1tOIiKYhsr9>jYgGKs=`*N zv}jyyRB5p)?goPB+{p5Jb-|H(#biuZo$8V=bj@m<&Aw*Mzvy;mD@cB;LBZVYApQ(D zdpPq|r)sw;OT$xM%b9U3xD%GW6CGq63GPHqLE>$f#-ZTp)T|)+jjzs91<7wcE?A); z`OV+XYNgUb`*8ccu~0$s2Ow%Rm0<*BXJiDW8UkwI7}mD<7*>7|TUr^wfilifZVG;4 n@$E^mUzjZzWv9I6RnQJ~H00000NkvXXu0mjf?i-Uu From 4fe7c80dc9ee1a3dc43f1f89bcfbc3b77b0620cb Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Wed, 15 Oct 2025 14:14:35 -0700 Subject: [PATCH 6/8] feat: replace icon references with base64 encoded images --- example/src/components/App/App.constants.ts | 18 +++++++++++--- example/src/components/App/App.utils.tsx | 27 ++++++++++++++++++--- example/src/components/App/Main.tsx | 2 +- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/example/src/components/App/App.constants.ts b/example/src/components/App/App.constants.ts index f84c390cb..65bf314e6 100644 --- a/example/src/components/App/App.constants.ts +++ b/example/src/components/App/App.constants.ts @@ -1,7 +1,19 @@ import { Route } from '../../constants'; +// Taken from https://github.com/ionic-team/ionicons/blob/main/src/svg/cash-outline.svg +export const cashIcon = + 'data:image/png;base64,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'; + +// Taken from https://github.com/ionic-team/ionicons/blob/main/src/svg/person-outline.svg +export const personIcon = + 'data:image/png;base64,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'; + +// Taken from https://github.com/ionic-team/ionicons/blob/main/src/svg/mail-outline.svg +export const mailIcon = + 'data:image/png;base64,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'; + export const routeIcon = { - [Route.Commerce]: 'cash-outline', - [Route.Inbox]: 'mail-outline', - [Route.User]: 'person-outline', + [Route.Commerce]: cashIcon, + [Route.Inbox]: mailIcon, + [Route.User]: personIcon, }; diff --git a/example/src/components/App/App.utils.tsx b/example/src/components/App/App.utils.tsx index 2dcde5374..6a3990472 100644 --- a/example/src/components/App/App.utils.tsx +++ b/example/src/components/App/App.utils.tsx @@ -1,5 +1,24 @@ -import Icon from 'react-native-vector-icons/Ionicons'; +import { Image, View } from 'react-native'; +import type { Route } from '../../constants/routes'; -export const getIcon = (name: string, props: Record) => ( - -); +export const getIcon = (name: Route, props: Record) => { + const { color, size = 25 } = props; + + return ( + + + + ); +}; diff --git a/example/src/components/App/Main.tsx b/example/src/components/App/Main.tsx index 55b0d74e2..b944801fe 100644 --- a/example/src/components/App/Main.tsx +++ b/example/src/components/App/Main.tsx @@ -25,7 +25,7 @@ export const Main = () => { screenOptions={({ route }) => { const iconName = routeIcon[route.name]; return { - tabBarIcon: (props) => getIcon(iconName, props), + tabBarIcon: (props) => getIcon(iconName as Route, props), tabBarActiveTintColor: colors.brandPurple, tabBarInactiveTintColor: colors.textSecondary, headerShown: false, From 6ece6e031147935ecd50f46e65be519d306f00ab Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Wed, 15 Oct 2025 14:15:19 -0700 Subject: [PATCH 7/8] chore: remove react-native-vector-icons dependency and related configurations --- README.md | 1 - example/android/app/build.gradle | 2 - example/package.json | 1 - jest.config.js | 2 +- package.json | 3 -- yarn.lock | 68 +------------------------------- 6 files changed, 3 insertions(+), 74 deletions(-) diff --git a/README.md b/README.md index fb5a88a63..9f8ead8e9 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,6 @@ Iterable's React Native SDK relies on: _UI Components require additional peer dependencies_ - [React Navigation 6+](https://github.com/react-navigation/react-navigation) - [React Native Safe Area Context 4+](https://github.com/th3rdwave/react-native-safe-area-context) - - [React Native Vector Icons 10+](https://github.com/oblador/react-native-vector-icons) - [React Native WebView 13+](https://github.com/react-native-webview/react-native-webview) - **iOS** diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 060f74075..a060fdcce 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -117,5 +117,3 @@ dependencies { implementation jscFlavor } } - -apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle") diff --git a/example/package.json b/example/package.json index 40ca703a4..20dddd07b 100644 --- a/example/package.json +++ b/example/package.json @@ -19,7 +19,6 @@ "react-native-gesture-handler": "^2.24.0", "react-native-safe-area-context": "^5.1.0", "react-native-screens": "^4.9.1", - "react-native-vector-icons": "^10.2.0", "react-native-webview": "^13.13.1" }, "devDependencies": { diff --git a/jest.config.js b/jest.config.js index 482f53a77..c5b75e86c 100644 --- a/jest.config.js +++ b/jest.config.js @@ -6,7 +6,7 @@ module.exports = { ], testMatch: ['/src/**/*.(test|spec).[jt]s?(x)'], transformIgnorePatterns: [ - 'node_modules/(?!(react-native|@react-native|@react-navigation|react-native-screens|react-native-safe-area-context|react-native-gesture-handler|react-native-webview|react-native-vector-icons)/)', + 'node_modules/(?!(react-native|@react-native|@react-navigation|react-native-screens|react-native-safe-area-context|react-native-gesture-handler|react-native-webview)/)', ], collectCoverageFrom: [ 'src/**/*.{cjs,js,jsx,mjs,ts,tsx}', diff --git a/package.json b/package.json index c3e1dfc52..bb356a6f5 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,6 @@ "@testing-library/react-native": "^13.3.3", "@types/jest": "^29.5.5", "@types/react": "^19.0.0", - "@types/react-native-vector-icons": "^6.4.18", "@typescript-eslint/eslint-plugin": "^8.13.0", "@typescript-eslint/parser": "^8.13.0", "commitlint": "^19.6.1", @@ -96,7 +95,6 @@ "react-native-gesture-handler": "^2.26.0", "react-native-safe-area-context": "^5.4.0", "react-native-screens": "^4.10.0", - "react-native-vector-icons": "^10.2.0", "react-native-webview": "^13.14.1", "react-test-renderer": "19.0.0", "release-it": "^17.10.0", @@ -114,7 +112,6 @@ "react": "*", "react-native": "*", "react-native-safe-area-context": "*", - "react-native-vector-icons": "*", "react-native-webview": "*" }, "peerDependenciesMeta": { diff --git a/yarn.lock b/yarn.lock index ea98be24c..ec4f21c4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3108,7 +3108,6 @@ __metadata: react-native-gesture-handler: ^2.24.0 react-native-safe-area-context: ^5.1.0 react-native-screens: ^4.9.1 - react-native-vector-icons: ^10.2.0 react-native-webview: ^13.13.1 react-test-renderer: 19.0.0 languageName: unknown @@ -3130,7 +3129,6 @@ __metadata: "@testing-library/react-native": ^13.3.3 "@types/jest": ^29.5.5 "@types/react": ^19.0.0 - "@types/react-native-vector-icons": ^6.4.18 "@typescript-eslint/eslint-plugin": ^8.13.0 "@typescript-eslint/parser": ^8.13.0 commitlint: ^19.6.1 @@ -3149,7 +3147,6 @@ __metadata: react-native-gesture-handler: ^2.26.0 react-native-safe-area-context: ^5.4.0 react-native-screens: ^4.10.0 - react-native-vector-icons: ^10.2.0 react-native-webview: ^13.14.1 react-test-renderer: 19.0.0 release-it: ^17.10.0 @@ -3163,7 +3160,6 @@ __metadata: react: "*" react-native: "*" react-native-safe-area-context: "*" - react-native-vector-icons: "*" react-native-webview: "*" peerDependenciesMeta: expo: @@ -4615,25 +4611,6 @@ __metadata: languageName: node linkType: hard -"@types/react-native-vector-icons@npm:^6.4.18": - version: 6.4.18 - resolution: "@types/react-native-vector-icons@npm:6.4.18" - dependencies: - "@types/react": "*" - "@types/react-native": ^0.70 - checksum: 1ef458cb5e7a37f41eb400e3153940b1b152e4df76a7c06c7a47c712dbfe46e14b9999f04dde1bd074f338f850e161c6c925174ddea33386b74f8112c940065b - languageName: node - linkType: hard - -"@types/react-native@npm:^0.70": - version: 0.70.19 - resolution: "@types/react-native@npm:0.70.19" - dependencies: - "@types/react": "*" - checksum: 79b504fa56340631079e7c20ea0d9412ec14147b76d0ce189f4403936f529ef1e6fd031383afab117846c5ae039123bcf3afc948bae4432269c6780282726f71 - languageName: node - linkType: hard - "@types/react-test-renderer@npm:^19.0.0": version: 19.1.0 resolution: "@types/react-test-renderer@npm:19.1.0" @@ -6172,17 +6149,6 @@ __metadata: languageName: node linkType: hard -"cliui@npm:^7.0.2": - version: 7.0.4 - resolution: "cliui@npm:7.0.4" - dependencies: - string-width: ^4.2.0 - strip-ansi: ^6.0.0 - wrap-ansi: ^7.0.0 - checksum: ce2e8f578a4813806788ac399b9e866297740eecd4ad1823c27fd344d78b22c5f8597d548adbcc46f0573e43e21e751f39446c5a5e804a12aace402b7a315d7f - languageName: node - linkType: hard - "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -12370,7 +12336,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": +"prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -12760,21 +12726,6 @@ __metadata: languageName: node linkType: hard -"react-native-vector-icons@npm:^10.2.0": - version: 10.2.0 - resolution: "react-native-vector-icons@npm:10.2.0" - dependencies: - prop-types: ^15.7.2 - yargs: ^16.1.1 - bin: - fa-upgrade.sh: bin/fa-upgrade.sh - fa5-upgrade: bin/fa5-upgrade.sh - fa6-upgrade: bin/fa6-upgrade.sh - generate-icon: bin/generate-icon.js - checksum: fda930df4e63f12533268f5b339ebe4c77c691eae43503328466b3087ed868a06a4593fd246e75ac6b5ec955543eec35608c7922191bdcc3b3a94ed7f3575ef0 - languageName: node - linkType: hard - "react-native-webview@npm:^13.13.1": version: 13.14.1 resolution: "react-native-webview@npm:13.14.1" @@ -15200,7 +15151,7 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:^20.2.2, yargs-parser@npm:^20.2.9": +"yargs-parser@npm:^20.2.9": version: 20.2.9 resolution: "yargs-parser@npm:20.2.9" checksum: 8bb69015f2b0ff9e17b2c8e6bfe224ab463dd00ca211eece72a4cd8a906224d2703fb8a326d36fdd0e68701e201b2a60ed7cf81ce0fd9b3799f9fe7745977ae3 @@ -15226,21 +15177,6 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^16.1.1": - version: 16.2.0 - resolution: "yargs@npm:16.2.0" - dependencies: - cliui: ^7.0.2 - escalade: ^3.1.1 - get-caller-file: ^2.0.5 - require-directory: ^2.1.1 - string-width: ^4.2.0 - y18n: ^5.0.5 - yargs-parser: ^20.2.2 - checksum: b14afbb51e3251a204d81937c86a7e9d4bdbf9a2bcee38226c900d00f522969ab675703bee2a6f99f8e20103f608382936034e64d921b74df82b63c07c5e8f59 - languageName: node - linkType: hard - "yargs@npm:^17.0.0, yargs@npm:^17.3.1, yargs@npm:^17.5.1, yargs@npm:^17.6.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" From c1f3dec93b6ececc78e2d566b8d7e7d44131ad7d Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Wed, 15 Oct 2025 14:29:20 -0700 Subject: [PATCH 8/8] test: add comprehensive tests for HeaderBackButton component --- .eslintrc.js | 1 + .../components/HeaderBackButton.test.tsx | 243 ++++++++++++++++++ 2 files changed, 244 insertions(+) create mode 100644 src/inbox/components/HeaderBackButton.test.tsx diff --git a/.eslintrc.js b/.eslintrc.js index e0f808c23..bad66d857 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -48,4 +48,5 @@ module.exports = { }, }, ], + ignorePatterns: ['coverage/**/*', 'lib/**/*', 'docs/**/*'], }; diff --git a/src/inbox/components/HeaderBackButton.test.tsx b/src/inbox/components/HeaderBackButton.test.tsx new file mode 100644 index 000000000..76917e0c0 --- /dev/null +++ b/src/inbox/components/HeaderBackButton.test.tsx @@ -0,0 +1,243 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { fireEvent, render } from '@testing-library/react-native'; +import { PixelRatio } from 'react-native'; +import { HeaderBackButton, ICON_MARGIN, ICON_SIZE } from './HeaderBackButton'; + +describe('HeaderBackButton', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Rendering', () => { + it('should render without crashing', () => { + const { getByTestId } = render(); + expect(getByTestId('back-button')).toBeTruthy(); + }); + + it('should render with default back arrow image', () => { + const { UNSAFE_getByType } = render(); + const image = UNSAFE_getByType('Image' as any); + expect(image).toBeTruthy(); + expect(image.props.source).toMatchObject({ + uri: expect.stringContaining('data:image/png;base64'), + width: PixelRatio.getPixelSizeForLayoutSize(ICON_SIZE), + height: PixelRatio.getPixelSizeForLayoutSize(ICON_SIZE), + }); + }); + + it('should render without label by default', () => { + const { queryByText } = render(); + expect(queryByText(/./)).toBeNull(); + }); + + it('should render with label when provided', () => { + const label = 'Back'; + const { getByText } = render(); + expect(getByText(label)).toBeTruthy(); + }); + + it('should render with custom label text', () => { + const customLabel = 'Go Back to Home'; + const { getByText } = render(); + expect(getByText(customLabel)).toBeTruthy(); + }); + }); + + describe('Custom Image Props', () => { + it('should render with custom imageUri', () => { + const customUri = 'https://example.com/custom-back-icon.png'; + const { UNSAFE_getByType } = render( + + ); + const image = UNSAFE_getByType('Image' as any); + expect(image.props.source).toMatchObject({ + uri: customUri, + }); + }); + + it('should render with custom imageSource', () => { + const customSource = { uri: 'https://example.com/icon.png' }; + const { UNSAFE_getByType } = render( + + ); + const image = UNSAFE_getByType('Image' as any); + expect(image.props.source).toEqual(customSource); + }); + + it('should prioritize imageSource over imageUri when both are provided', () => { + const customUri = 'https://example.com/custom-back-icon.png'; + const customSource = { uri: 'https://example.com/icon.png' }; + const { UNSAFE_getByType } = render( + + ); + const image = UNSAFE_getByType('Image' as any); + expect(image.props.source).toEqual(customSource); + }); + }); + + describe('Image Properties', () => { + it('should render image with correct properties', () => { + const { UNSAFE_getByType } = render(); + const image = UNSAFE_getByType('Image' as any); + + expect(image.props.resizeMode).toBe('contain'); + expect(image.props.fadeDuration).toBe(0); + expect(image.props.height).toBe(ICON_SIZE); + expect(image.props.width).toBe(ICON_SIZE); + expect(image.props.resizeMethod).toBe('scale'); + expect(image.props.tintColor).toBeTruthy(); + }); + + it('should apply correct style to image', () => { + const { UNSAFE_getByType } = render(); + const image = UNSAFE_getByType('Image' as any); + + expect(image.props.style).toMatchObject({ + height: ICON_SIZE, + margin: ICON_MARGIN, + width: ICON_SIZE, + }); + }); + }); + + describe('Touch Interaction', () => { + it('should call onPress when button is pressed', () => { + const onPressMock = jest.fn(); + const { getByTestId } = render( + + ); + + fireEvent.press(getByTestId('back-button')); + expect(onPressMock).toHaveBeenCalledTimes(1); + }); + + it('should call onPressIn when touch starts', () => { + const onPressInMock = jest.fn(); + const { getByTestId } = render( + + ); + + fireEvent(getByTestId('back-button'), 'pressIn'); + expect(onPressInMock).toHaveBeenCalledTimes(1); + }); + + it('should call onPressOut when touch ends', () => { + const onPressOutMock = jest.fn(); + const { getByTestId } = render( + + ); + + fireEvent(getByTestId('back-button'), 'pressOut'); + expect(onPressOutMock).toHaveBeenCalledTimes(1); + }); + + it('should not trigger onPress when disabled', () => { + const onPressMock = jest.fn(); + const { getByTestId } = render( + + ); + + fireEvent.press(getByTestId('back-button')); + expect(onPressMock).not.toHaveBeenCalled(); + }); + }); + + describe('Platform-specific behavior', () => { + it('should export correct icon size constant', () => { + // ICON_SIZE is evaluated at module load time based on Platform.OS + expect(ICON_SIZE).toBeDefined(); + expect([21, 24]).toContain(ICON_SIZE); + }); + + it('should export correct icon margin constant', () => { + // ICON_MARGIN is evaluated at module load time based on Platform.OS + expect(ICON_MARGIN).toBeDefined(); + expect([3, 8]).toContain(ICON_MARGIN); + }); + + it('should use consistent icon size in image props', () => { + const { UNSAFE_getByType } = render(); + const image = UNSAFE_getByType('Image' as any); + + expect(image.props.height).toBe(ICON_SIZE); + expect(image.props.width).toBe(ICON_SIZE); + }); + }); + + describe('Accessibility', () => { + it('should accept accessibility props', () => { + const { getByTestId } = render( + + ); + + const button = getByTestId('back-button'); + expect(button.props.accessible).toBe(true); + expect(button.props.accessibilityLabel).toBe('Navigate back'); + expect(button.props.accessibilityHint).toBe('Returns to previous screen'); + }); + }); + + describe('Component Structure', () => { + it('should render View with correct flex direction', () => { + const { UNSAFE_getAllByType } = render(); + const views = UNSAFE_getAllByType('View' as any); + + // Find the view with returnButton style + const returnButtonView = views.find( + (view) => + view.props.style?.flexDirection === 'row' && + view.props.style?.alignItems === 'center' + ); + expect(returnButtonView).toBeTruthy(); + }); + + it('should render label text with correct style when provided', () => { + const { getByText } = render(); + const labelElement = getByText('Back'); + + expect(labelElement.props.style).toMatchObject({ + fontSize: 20, + }); + }); + }); + + describe('Edge Cases', () => { + it('should handle empty string label', () => { + const { queryByText } = render(); + // Empty string should not render text + expect(queryByText('')).toBeNull(); + }); + + it('should handle multiple props correctly', () => { + const onPressMock = jest.fn(); + const label = 'Custom Back'; + const customUri = 'https://example.com/icon.png'; + + const { getByText, getByTestId } = render( + + ); + + expect(getByText(label)).toBeTruthy(); + expect(getByTestId('back-button').props.accessible).toBe(true); + + fireEvent.press(getByTestId('back-button')); + expect(onPressMock).toHaveBeenCalledTimes(1); + }); + }); +});