Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .nx/version-plans/version-plan-1773849698407.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ledgerhq/lumen-ui-rnative': patch
---

feat(MediaCard): introduce MediaCard component with docs, tests, and figma code connect.
4 changes: 2 additions & 2 deletions apps/app-sandbox-rnative/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
},
"dependencies": {
"@gorhom/bottom-sheet": "^5.2.6",
"@ledgerhq/lumen-design-core": "0.1.3",
"@ledgerhq/lumen-ui-rnative": "0.1.9",
"@ledgerhq/lumen-design-core": "0.1.5",
"@ledgerhq/lumen-ui-rnative": "0.1.11",
"@sbaiahmed1/react-native-blur": "^4.5.5",
"expo": "~53.0.0",
"expo-haptics": "~14.1.4",
Expand Down
4 changes: 4 additions & 0 deletions apps/app-sandbox-rnative/src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
Banners,
CardButtons,
ContentBanners,
MediaCards,
Tooltips,
ListItems,
Gradients,
Expand Down Expand Up @@ -177,6 +178,9 @@ const AppContent = ({
<SandboxBlock title='ListItems'>
<ListItems />
</SandboxBlock>
<SandboxBlock title='MediaCards'>
<MediaCards />
</SandboxBlock>
<SandboxBlock title='NavBars'>
<NavBars />
</SandboxBlock>
Expand Down
35 changes: 35 additions & 0 deletions apps/app-sandbox-rnative/src/app/blocks/MediaCards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
Box,
MediaCard,
MediaCardTitle,
Tag,
} from '@ledgerhq/lumen-ui-rnative';

const EXAMPLE_SRC =
'https://ledger-wp-website-s3-prd.ledger.com/uploads/2026/03/hero_visual-1.webp';

export const MediaCards = () => {
return (
<Box lx={{ flexDirection: 'column', gap: 's12', width: 'full' }}>
<MediaCard
imageUrl={EXAMPLE_SRC}
onPress={() => ({})}
onClose={() => ({})}
>
<Tag label='Promo' size='md' />
<MediaCardTitle>
Black Friday sale. 3 days with no fees on your transactions.
</MediaCardTitle>
</MediaCard>

<MediaCard
imageUrl={EXAMPLE_SRC}
onPress={() => ({})}
onClose={() => ({})}
>
<MediaCardTitle>Secure your crypto assets</MediaCardTitle>
Get started with Ledger and protect your digital assets today.
</MediaCard>
</Box>
);
};
1 change: 1 addition & 0 deletions apps/app-sandbox-rnative/src/app/blocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ export * from './InteractiveIcons';
export * from './Banners';
export * from './CardButtons';
export * from './ContentBanners';
export * from './MediaCards';
export * from './Tooltips';
export * from './Gradients';
3 changes: 3 additions & 0 deletions libs/ui-rnative/src/i18n/locales/de.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"common": {
"closeAriaLabel": "Schließen"
},
"components": {
"addressInput": {
"qrCodeAriaLabel": "QR-Code scannen"
Expand Down
3 changes: 3 additions & 0 deletions libs/ui-rnative/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"common": {
"closeAriaLabel": "Close"
},
"components": {
"addressInput": {
"qrCodeAriaLabel": "Scan QR code"
Expand Down
3 changes: 3 additions & 0 deletions libs/ui-rnative/src/i18n/locales/es.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"common": {
"closeAriaLabel": "Cerrar"
},
"components": {
"addressInput": {
"qrCodeAriaLabel": "Escanear código QR"
Expand Down
3 changes: 3 additions & 0 deletions libs/ui-rnative/src/i18n/locales/fr.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"common": {
"closeAriaLabel": "Fermer"
},
"components": {
"addressInput": {
"qrCodeAriaLabel": "Scanner le code QR"
Expand Down
3 changes: 3 additions & 0 deletions libs/ui-rnative/src/i18n/locales/ja.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"common": {
"closeAriaLabel": "閉じる"
},
"components": {
"addressInput": {
"qrCodeAriaLabel": "QRコードをスキャン"
Expand Down
3 changes: 3 additions & 0 deletions libs/ui-rnative/src/i18n/locales/ko.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"common": {
"closeAriaLabel": "닫기"
},
"components": {
"addressInput": {
"qrCodeAriaLabel": "QR 코드 스캔"
Expand Down
3 changes: 3 additions & 0 deletions libs/ui-rnative/src/i18n/locales/pt.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"common": {
"closeAriaLabel": "Fechar"
},
"components": {
"addressInput": {
"qrCodeAriaLabel": "Escanear QR Code"
Expand Down
3 changes: 3 additions & 0 deletions libs/ui-rnative/src/i18n/locales/ru.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"common": {
"closeAriaLabel": "Закрыть"
},
"components": {
"addressInput": {
"qrCodeAriaLabel": "Сканировать QR-код"
Expand Down
3 changes: 3 additions & 0 deletions libs/ui-rnative/src/i18n/locales/th.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"common": {
"closeAriaLabel": "ปิด"
},
"components": {
"addressInput": {
"qrCodeAriaLabel": "สแกน QR Code"
Expand Down
3 changes: 3 additions & 0 deletions libs/ui-rnative/src/i18n/locales/tr.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"common": {
"closeAriaLabel": "Kapat"
},
"components": {
"addressInput": {
"qrCodeAriaLabel": "Karekodu okut"
Expand Down
3 changes: 3 additions & 0 deletions libs/ui-rnative/src/i18n/locales/zh.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"common": {
"closeAriaLabel": "关闭"
},
"components": {
"addressInput": {
"qrCodeAriaLabel": "扫描二维码"
Expand Down
94 changes: 94 additions & 0 deletions libs/ui-rnative/src/lib/Components/MediaCard/MediaCard.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks';
import * as MediaCardStories from './MediaCard.stories';
import { CustomTabs, Tab } from '../../../../.storybook/components';
import CommonRulesDoAndDont from '../../../../.storybook/components/DoVsDont/CommonRulesDoAndDont.mdx';

<Meta title='Communication/MediaCard' of={MediaCardStories} />

# MediaCard

<CustomTabs>
<Tab label="Overview">

## Introduction

MediaCard is a promotional card component that displays a full-bleed background image with gradient overlays for text readability. It uses a simplified compound pattern with `MediaCardTitle` for the text and free-form children for leading content (e.g. tags, icons).

## Anatomy

<Canvas of={MediaCardStories.Base} />

- **MediaCard**: Root pressable container with background image and gradient overlays
- **MediaCardTitle**: Styled title text (clamps at 3 lines)
- **Leading content**: Any element rendered before `MediaCardTitle` (tags, badges, icons) — no wrapper needed
- **Close button**: Rendered via the `onClose` prop (positioned absolute top-right)

## Properties

<Canvas of={MediaCardStories.Base} />
<Controls of={MediaCardStories.Base} />

### Layout

The card fills its parent width by default.

<Canvas of={MediaCardStories.LayoutShowcase} />

### Compositions

Leading content is optional — just place any element before `MediaCardTitle` inside `MediaCard`.

<Canvas of={MediaCardStories.CompositionShowcase} />

## Accessibility

- The root element uses `accessibilityRole='button'` and responds to press events
- The close button includes an `accessibilityLabel` (auto-translated via i18n)
- The background image is not accessible (`accessible={false}`) since it is decorative
- Components forward refs and spread props for accessibility support

</Tab>
<Tab label="Implementation">

## Setup

Install and set up the library with our [Setup Guide →](?path=/docs/getting-started-setup--docs).

## Basic Usage

```tsx
import { MediaCard, MediaCardTitle, Tag } from '@ledgerhq/lumen-ui-rnative';

function MyComponent() {
return (
<MediaCard
imageUrl='https://example.com/promo.jpg'
onPress={() => console.log('pressed')}
onClose={() => console.log('closed')}
>
<Tag label='New' size='md' />
<MediaCardTitle>Card title</MediaCardTitle>
</MediaCard>
);
}
```

### Layout Adjustments with lx

Use the `lx` prop for layout adjustments like margins or positioning:

```tsx
<MediaCard
imageUrl='https://example.com/promo.jpg'
onPress={() => console.log('pressed')}
onClose={() => console.log('closed')}
lx={{ marginTop: 's16', marginBottom: 's8' }}
>
<MediaCardTitle>With margin</MediaCardTitle>
</MediaCard>
```

<CommonRulesDoAndDont />

</Tab>
</CustomTabs>
Loading
Loading