Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
da62c11
fix: fix market insights and security page buttons cp-7.80.0 (#30871)
sahar-fehri Jun 1, 2026
ee42c73
fix(rewards): VIP splash screen title (#30882)
sophieqgu Jun 1, 2026
e1fa793
refactor(NatigationUnitTest): migrate NavigationUnitTest to native st…
weitingsun Jun 1, 2026
e6c4b6c
revert: "ci: Add temporary fallback to Patroll token in `check-templa…
Mrtenz Jun 1, 2026
1bdcec5
feat: track Token Details secondary action buttons (ASSETS-3212) cp-7…
Prithpal-Sooriya Jun 1, 2026
1d5bdb2
refactor(send): migrate send routes to native stack (#30822)
weitingsun Jun 1, 2026
a6d3459
refactor(onboarding): replace Pressable with TouchableOpacity in inte…
Copilot Jun 1, 2026
23581ce
fix(rewards): hypertracker logo color (#30891)
sophieqgu Jun 1, 2026
ad68ca5
chore: nightly build external distributed (#30887)
tommasini Jun 1, 2026
48aaee7
fix(pure black): elevate ListItemSelect and Input surfaces under MM_P…
vinnyhoward Jun 1, 2026
0a88c0e
feat: batch sell submit tx (#30710)
infiniteflower Jun 1, 2026
6d67f21
feat: MUSD-830 expand earn on your crypto to include all mm pay suppo…
Matt561 Jun 1, 2026
9c28805
feat(quick-buy): add direction-aware screen transitions (#30896)
xavier-brochard Jun 1, 2026
d6a3c1e
chore: add new token details closed event (#30792)
sahar-fehri Jun 1, 2026
e1eab35
refactor(confirmations): use MMDS HeaderStandard (#29701)
brianacnguyen Jun 1, 2026
501d6ee
refactor(ui): use MMDS HeaderStandard in misc UI surfaces (#29708)
brianacnguyen Jun 1, 2026
6d2c33b
fix: require money hub enabled flag for mUSD cash section filtering (…
Matt561 Jun 1, 2026
8815b5b
feat(component-library): add variant prop to Pressable (#30831)
vinnyhoward Jun 1, 2026
c47e86a
fix: downgrade Rive fallback log and shorten splash timeout (#30901)
vinnyhoward Jun 1, 2026
cae6c60
feat: app icons backgrounds are now pure black (#30895)
vinnyhoward Jun 1, 2026
044726b
feat: delegate AuthenticationController:getBearerToken in RampsServic…
meltingice1337 Jun 1, 2026
a33a1ed
feat(analytics): add ASSET_VIEWED for Predict, Perps, and Swaps funne…
adrigug Jun 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/check-template-and-add-labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ jobs:
- name: Get access token
id: get-token
uses: MetaMask/github-tools/.github/actions/get-token@v1
continue-on-error: true
with:
token-exchange-url: ${{ vars.TOKEN_EXCHANGE_URL }}
permissions: |
Expand All @@ -63,6 +62,6 @@ jobs:
- name: Check template and add labels
id: check-template-and-add-labels
env:
LABEL_TOKEN: ${{ steps.get-token.outputs.token || secrets.LABEL_TOKEN }}
LABEL_TOKEN: ${{ steps.get-token.outputs.token }}
run: npm run check-template-and-add-labels
working-directory: '.github/scripts'
2 changes: 2 additions & 0 deletions .github/workflows/nightly-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
source_branch: main
environment: exp
testflight_group: 'MetaMask BETA & Release Candidates'
distribute_external: true
secrets: inherit

ios-rc:
Expand All @@ -34,6 +35,7 @@ jobs:
source_branch: main
environment: rc
testflight_group: 'MetaMask BETA & Release Candidates'
distribute_external: true
secrets: inherit

android-exp-generate:
Expand Down
3 changes: 3 additions & 0 deletions .js.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ export MM_MUSD_CONVERSION_MIN_ASSET_BALANCE_REQUIRED="0.01"

# Money Hub
export MM_MONEY_HUB_ENABLED="false"
export MM_MONEY_PAYMENT_TOKENS_BLOCKLIST=""
export MM_MONEY_DEPOSIT_NO_FEE_TOKENS=""
export MM_MONEY_DEPOSIT_MIN_ASSET_BALANCE="0.01"

# Activates remote feature flag override mode.
# Remote feature flag values won't be updated,
Expand Down
Binary file modified android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { View } from 'react-native';

// External dependencies.
import { useStyles } from '../../hooks';
import Pressable from '../Pressable';
import Pressable, { PressableVariant } from '../Pressable';
import ListItem from '../../../component-library/components/List/ListItem/ListItem';

// Internal dependencies.
Expand Down Expand Up @@ -49,6 +49,7 @@ const ListItemMultiSelectButton: React.FC<ListItemMultiSelectButtonProps> = ({

return (
<Pressable
variant={PressableVariant.Highlight}
testID={ROW_TEST_ID}
style={styles.container}
disabled={isDisabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { View } from 'react-native';

// External dependencies.
import { useStyles } from '../../hooks';
import Pressable from '../Pressable';
import Pressable, { PressableVariant } from '../Pressable';
import ListItem from '../../../component-library/components/List/ListItem/ListItem';
import Checkbox from '../../components/Checkbox';

Expand Down Expand Up @@ -46,6 +46,7 @@ const ListItemMultiSelectWithMenuButton: React.FC<

return (
<Pressable
variant={PressableVariant.Highlight}
testID={ROW_TEST_ID}
style={styles.container}
disabled={isDisabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { ThemeContext, useTheme } from '../../../util/theme';
import { AppThemeKey } from '../../../util/theme/models';

import Pressable from './Pressable';
import { PressableVariant } from './Pressable.types';

const layout = StyleSheet.create({
page: { flex: 1, padding: 16, gap: 20 },
Expand Down Expand Up @@ -90,10 +91,17 @@ const PressMe = () => (
</Text>
);

const PressableCard = ({ surfaceColor }: { surfaceColor: string }) => {
const PressableCard = ({
surfaceColor,
variant,
}: {
surfaceColor: string;
variant: PressableVariant;
}) => {
const { colors } = useTheme();
return (
<Pressable
variant={variant}
onPress={() => undefined}
style={[
layout.card,
Expand All @@ -108,7 +116,7 @@ const PressableCard = ({ surfaceColor }: { surfaceColor: string }) => {
);
};

const SurfaceCatalog = () => {
const SurfaceCatalog = ({ variant }: { variant: PressableVariant }) => {
const { colors } = useTheme();
const surfaces = [
{ key: 'default', color: colors.background.default },
Expand All @@ -121,7 +129,7 @@ const SurfaceCatalog = () => {
{surfaces.map((s) => (
<Box key={s.key} twClassName="gap-1">
<SurfaceLabel>background.{s.key}</SurfaceLabel>
<PressableCard surfaceColor={s.color} />
<PressableCard surfaceColor={s.color} variant={variant} />
</Box>
))}
</Box>
Expand All @@ -131,7 +139,15 @@ const SurfaceCatalog = () => {
export const Default = {
render: () => (
<OSThemePane>
<SurfaceCatalog />
<SurfaceCatalog variant={PressableVariant.Default} />
</OSThemePane>
),
};

export const Highlight = {
render: () => (
<OSThemePane>
<SurfaceCatalog variant={PressableVariant.Highlight} />
</OSThemePane>
),
};
66 changes: 33 additions & 33 deletions app/component-library/components-temp/Pressable/Pressable.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,11 @@ import { fireEvent, render } from '@testing-library/react-native';

import { mockTheme } from '../../../util/theme';

import Pressable from './Pressable';

interface AnyStyle {
[key: string]: unknown;
}

const flatten = (style: unknown): AnyStyle => {
if (Array.isArray(style)) {
return style.reduce<AnyStyle>(
(acc, item) => ({ ...acc, ...flatten(item) }),
{},
);
}
if (style && typeof style === 'object') {
return style as AnyStyle;
}
return {};
};
import Pressable, { PRESSED_OPACITY, pressedStyleFor } from './Pressable';
import { PressableVariant } from './Pressable.types';

const RESTING = mockTheme.colors.background.section;
const PRESSED = mockTheme.colors.background.pressed;
const PRESSED_BG = mockTheme.colors.background.pressed;

const styles = StyleSheet.create({
padded: { padding: 16, backgroundColor: RESTING },
Expand Down Expand Up @@ -91,9 +75,12 @@ describe('Pressable', () => {
</Pressable>,
);

const resting = flatten(getByTestId('p').props.style);
expect(resting.backgroundColor).toBe(RESTING);
expect(resting.padding).toBe(16);
const resting = getByTestId('p').props.style;
const flat = Array.isArray(resting)
? Object.assign({}, ...resting.filter(Boolean))
: resting;
expect(flat.backgroundColor).toBe(RESTING);
expect(flat.padding).toBe(16);
});

it('forwards a ref to the underlying view', () => {
Expand All @@ -108,16 +95,29 @@ describe('Pressable', () => {
expect(typeof ref.current?.measure).toBe('function');
});

it('resolves a function-form caller style on render', () => {
const styleFn = jest.fn(() => ({ borderWidth: 1 }));
render(
<Pressable testID="p" style={styleFn} onPress={jest.fn()}>
<Text>x</Text>
</Pressable>,
);

expect(styleFn).toHaveBeenCalledWith(
expect.objectContaining({ pressed: expect.any(Boolean) }),
);
describe('pressedStyleFor', () => {
it('default variant returns subtree opacity dim', () => {
expect(pressedStyleFor(PressableVariant.Default, PRESSED_BG)).toEqual({
opacity: PRESSED_OPACITY,
});
});

it('highlight variant returns background.pressed overlay', () => {
expect(pressedStyleFor(PressableVariant.Highlight, PRESSED_BG)).toEqual({
backgroundColor: PRESSED_BG,
});
});

it('does not include both opacity and backgroundColor for either variant', () => {
const def = pressedStyleFor(PressableVariant.Default, PRESSED_BG);
const hi = pressedStyleFor(PressableVariant.Highlight, PRESSED_BG);
expect('backgroundColor' in def).toBe(false);
expect('opacity' in hi).toBe(false);
});

it('none variant returns an empty overlay (no opacity, no background)', () => {
const overlay = pressedStyleFor(PressableVariant.None, PRESSED_BG);
expect(overlay).toEqual({});
});
});
});
52 changes: 44 additions & 8 deletions app/component-library/components-temp/Pressable/Pressable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,62 @@ import {

import { useTheme } from '../../../util/theme';

import type { PressableProps } from './Pressable.types';
import { PressableVariant, type PressableProps } from './Pressable.types';

export const PRESSED_OPACITY = 0.7;

/**
* Returns the pressed-state style overlay for the given variant. Exported
* for direct testing of the per-variant feedback model.
*/
export const pressedStyleFor = (
variant: PressableVariant,
pressedBackgroundColor: string,
): ViewStyle => {
switch (variant) {
case PressableVariant.Highlight:
return { backgroundColor: pressedBackgroundColor };
case PressableVariant.None:
return {};
case PressableVariant.Default:
default:
return { opacity: PRESSED_OPACITY };
}
};

/**
* Design-system Pressable.
*
* Replaces `TouchableOpacity` across the app. Instead of dimming the
* entire subtree on press, this layers the semi-transparent
* `background.pressed` token on top of whatever resting surface the
* parent owns. The component itself never sets a resting background.
* Replaces `TouchableOpacity` across the app. The component supports two
* visual feedback modes via the `variant` prop:
*
* `default` (the default) dims the caller's subtree by lowering opacity to
* `PRESSED_OPACITY`. Mirrors the familiar `TouchableOpacity` model while
* keeping content visible under pure-black mode.
*
* `highlight` composites `background.pressed` over the caller's resting
* surface. Use for list rows, settings rows, and similar surfaces where a
* backdrop highlight is the established design pattern.
*/
const Pressable = forwardRef<View, PressableProps>(
({ style, accessibilityRole = 'button', children, ...props }, ref) => {
(
{
style,
accessibilityRole = 'button',
children,
variant = PressableVariant.Default,
...props
},
ref,
) => {
const { colors } = useTheme();

const composedStyle = useCallback(
(state: PressableStateCallbackType): StyleProp<ViewStyle> => [
typeof style === 'function' ? style(state) : style,
state.pressed && { backgroundColor: colors.background.pressed },
state.pressed && pressedStyleFor(variant, colors.background.pressed),
],
[style, colors.background.pressed],
[style, colors.background.pressed, variant],
);

return (
Expand Down
32 changes: 30 additions & 2 deletions app/component-library/components-temp/Pressable/Pressable.types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,34 @@
import type { PressableProps as RNPressableProps } from 'react-native';
import type { PressableProps as RNGHPressableProps } from 'react-native-gesture-handler';

export type PressableProps = RNPressableProps;
/**
* Visual feedback applied on press.
*
* `Default` dims the caller's subtree (matches the legacy `TouchableOpacity`
* behaviour with a gentler opacity that keeps content visible under
* pure-black mode). Use for the broad majority of touchable surfaces.
*
* `Highlight` composites the semantic `background.pressed` token over the
* caller's resting surface. Use for list rows, settings rows, and other
* surfaces where a backdrop highlight is the established design pattern.
*
* `None` applies no visual feedback. Use when the caller component already
* renders its own press-state styling (e.g. a button that maintains a
* `pressed` state internally and toggles its own background or border).
*/
export const PressableVariant = {
Default: 'default',
Highlight: 'highlight',
None: 'none',
} as const;

export type PressableGHProps = RNGHPressableProps;
export type PressableVariant =
(typeof PressableVariant)[keyof typeof PressableVariant];

export type PressableProps = RNPressableProps & {
variant?: PressableVariant;
};

export type PressableGHProps = RNGHPressableProps & {
variant?: PressableVariant;
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ jest.mock('react-native-gesture-handler', () => {
});

import PressableGH from './PressableGH';
import { PressableVariant } from './Pressable.types';

describe('PressableGH', () => {
it('renders children', () => {
Expand Down Expand Up @@ -75,4 +76,22 @@ describe('PressableGH', () => {
expect(ref.current).not.toBeNull();
expect(typeof ref.current?.measure).toBe('function');
});

it('accepts the variant prop without crashing', () => {
expect(() =>
render(
<PressableGH variant={PressableVariant.Highlight} onPress={jest.fn()}>
<Text>x</Text>
</PressableGH>,
),
).not.toThrow();

expect(() =>
render(
<PressableGH variant={PressableVariant.Default} onPress={jest.fn()}>
<Text>x</Text>
</PressableGH>,
),
).not.toThrow();
});
});
Loading
Loading