@ledgerhq/lumen-ui-rnative 0.1.34 → 0.1.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module/index.js +1 -0
- package/dist/module/index.js.map +1 -1
- package/dist/module/lib/Animations/Pulse/Pulse.js +16 -6
- package/dist/module/lib/Animations/Pulse/Pulse.js.map +1 -1
- package/dist/module/lib/Components/BottomSheet/BottomSheet.js +12 -7
- package/dist/module/lib/Components/BottomSheet/BottomSheet.js.map +1 -1
- package/dist/module/lib/Components/BottomSheet/BottomSheet.stories.js +220 -1
- package/dist/module/lib/Components/BottomSheet/BottomSheet.stories.js.map +1 -1
- package/dist/module/lib/Components/BottomSheet/BottomSheet.test.js +73 -0
- package/dist/module/lib/Components/BottomSheet/BottomSheet.test.js.map +1 -1
- package/dist/module/lib/Components/BottomSheet/BottomSheetHeader.js +1 -1
- package/dist/module/lib/Components/BottomSheet/BottomSheetHeader.js.map +1 -1
- package/dist/module/lib/Components/BottomSheet/CustomHandle.js +15 -2
- package/dist/module/lib/Components/BottomSheet/CustomHandle.js.map +1 -1
- package/dist/module/lib/Components/Card/Card.js.map +1 -1
- package/dist/module/lib/Components/DescriptionItem/DescriptionItem.js +184 -0
- package/dist/module/lib/Components/DescriptionItem/DescriptionItem.js.map +1 -0
- package/dist/module/lib/Components/DescriptionItem/DescriptionItem.mdx +139 -0
- package/dist/module/lib/Components/DescriptionItem/DescriptionItem.stories.js +258 -0
- package/dist/module/lib/Components/DescriptionItem/DescriptionItem.stories.js.map +1 -0
- package/dist/module/lib/Components/DescriptionItem/DescriptionItem.test.js +94 -0
- package/dist/module/lib/Components/DescriptionItem/DescriptionItem.test.js.map +1 -0
- package/dist/module/lib/Components/DescriptionItem/index.js +5 -0
- package/dist/module/lib/Components/DescriptionItem/index.js.map +1 -0
- package/dist/module/lib/Components/DescriptionItem/types.js +4 -0
- package/dist/module/lib/Components/DescriptionItem/types.js.map +1 -0
- package/dist/module/lib/Components/ListItem/ListItem.js.map +1 -1
- package/dist/module/lib/Components/MediaImage/MediaImage.js +5 -1
- package/dist/module/lib/Components/MediaImage/MediaImage.js.map +1 -1
- package/dist/module/lib/Components/NavBar/CoinCapsule.js +1 -0
- package/dist/module/lib/Components/NavBar/CoinCapsule.js.map +1 -1
- package/dist/module/lib/Components/OptionList/OptionList.js +45 -4
- package/dist/module/lib/Components/OptionList/OptionList.js.map +1 -1
- package/dist/module/lib/Components/OptionList/OptionList.mdx +19 -0
- package/dist/module/lib/Components/OptionList/OptionList.stories.js +254 -1
- package/dist/module/lib/Components/OptionList/OptionList.stories.js.map +1 -1
- package/dist/module/lib/Components/OptionList/OptionList.test.js +136 -1
- package/dist/module/lib/Components/OptionList/OptionList.test.js.map +1 -1
- package/dist/module/lib/Components/OptionList/useOptionList/useOptionListItems.js +39 -13
- package/dist/module/lib/Components/OptionList/useOptionList/useOptionListItems.js.map +1 -1
- package/dist/module/lib/Components/OptionList/useOptionList/useOptionListItems.test.js +117 -2
- package/dist/module/lib/Components/OptionList/useOptionList/useOptionListItems.test.js.map +1 -1
- package/dist/module/lib/Components/PageIndicator/PageIndicator.test.js.map +1 -1
- package/dist/module/lib/Components/Skeleton/Skeleton.js +10 -3
- package/dist/module/lib/Components/Skeleton/Skeleton.js.map +1 -1
- package/dist/module/lib/Components/TabBar/TabBar.js +7 -6
- package/dist/module/lib/Components/TabBar/TabBar.js.map +1 -1
- package/dist/module/lib/Components/index.js +1 -0
- package/dist/module/lib/Components/index.js.map +1 -1
- package/dist/module/styles/lx/resolveStyle.js.map +1 -1
- package/dist/typescript/src/index.d.ts +1 -0
- package/dist/typescript/src/index.d.ts.map +1 -1
- package/dist/typescript/src/lib/Animations/Pulse/Pulse.d.ts +1 -1
- package/dist/typescript/src/lib/Animations/Pulse/Pulse.d.ts.map +1 -1
- package/dist/typescript/src/lib/Animations/Pulse/types.d.ts +2 -1
- package/dist/typescript/src/lib/Animations/Pulse/types.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/BottomSheet/BottomSheet.d.ts +1 -1
- package/dist/typescript/src/lib/Components/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/BottomSheet/CustomHandle.d.ts +5 -2
- package/dist/typescript/src/lib/Components/BottomSheet/CustomHandle.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/BottomSheet/types.d.ts +16 -3
- package/dist/typescript/src/lib/Components/BottomSheet/types.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Card/Card.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/DescriptionItem/DescriptionItem.d.ts +42 -0
- package/dist/typescript/src/lib/Components/DescriptionItem/DescriptionItem.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/DescriptionItem/index.d.ts +3 -0
- package/dist/typescript/src/lib/Components/DescriptionItem/index.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/DescriptionItem/types.d.ts +39 -0
- package/dist/typescript/src/lib/Components/DescriptionItem/types.d.ts.map +1 -0
- package/dist/typescript/src/lib/Components/ListItem/ListItem.d.ts +3 -3
- package/dist/typescript/src/lib/Components/ListItem/ListItem.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/MediaImage/MediaImage.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/OptionList/OptionList.d.ts +3 -2
- package/dist/typescript/src/lib/Components/OptionList/OptionList.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/OptionList/types.d.ts +42 -5
- package/dist/typescript/src/lib/Components/OptionList/types.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/OptionList/useOptionList/useOptionListItems.d.ts +9 -1
- package/dist/typescript/src/lib/Components/OptionList/useOptionList/useOptionListItems.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/Skeleton/Skeleton.d.ts +1 -1
- package/dist/typescript/src/lib/Components/Skeleton/Skeleton.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/TabBar/TabBar.d.ts.map +1 -1
- package/dist/typescript/src/lib/Components/index.d.ts +1 -0
- package/dist/typescript/src/lib/Components/index.d.ts.map +1 -1
- package/dist/typescript/src/lib/types/index.d.ts +3 -3
- package/dist/typescript/src/lib/types/index.d.ts.map +1 -1
- package/dist/typescript/src/styles/lx/resolveStyle.d.ts +3 -3
- package/dist/typescript/src/styles/lx/resolveStyle.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/lib/Animations/Pulse/Pulse.tsx +38 -30
- package/src/lib/Animations/Pulse/types.ts +2 -1
- package/src/lib/Components/BottomSheet/BottomSheet.stories.tsx +174 -1
- package/src/lib/Components/BottomSheet/BottomSheet.test.tsx +59 -0
- package/src/lib/Components/BottomSheet/BottomSheet.tsx +19 -7
- package/src/lib/Components/BottomSheet/BottomSheetHeader.tsx +1 -1
- package/src/lib/Components/BottomSheet/CustomHandle.tsx +26 -5
- package/src/lib/Components/BottomSheet/types.ts +24 -3
- package/src/lib/Components/Card/Card.tsx +3 -3
- package/src/lib/Components/DescriptionItem/DescriptionItem.mdx +139 -0
- package/src/lib/Components/DescriptionItem/DescriptionItem.stories.tsx +234 -0
- package/src/lib/Components/DescriptionItem/DescriptionItem.test.tsx +112 -0
- package/src/lib/Components/DescriptionItem/DescriptionItem.tsx +224 -0
- package/src/lib/Components/DescriptionItem/index.ts +2 -0
- package/src/lib/Components/DescriptionItem/types.ts +44 -0
- package/src/lib/Components/ListItem/ListItem.tsx +3 -3
- package/src/lib/Components/MediaImage/MediaImage.tsx +5 -1
- package/src/lib/Components/NavBar/CoinCapsule.tsx +1 -0
- package/src/lib/Components/OptionList/OptionList.mdx +19 -0
- package/src/lib/Components/OptionList/OptionList.stories.tsx +254 -0
- package/src/lib/Components/OptionList/OptionList.test.tsx +143 -0
- package/src/lib/Components/OptionList/OptionList.tsx +49 -3
- package/src/lib/Components/OptionList/types.ts +46 -5
- package/src/lib/Components/OptionList/useOptionList/useOptionListItems.test.ts +124 -2
- package/src/lib/Components/OptionList/useOptionList/useOptionListItems.ts +53 -10
- package/src/lib/Components/PageIndicator/PageIndicator.test.tsx +2 -1
- package/src/lib/Components/Skeleton/Skeleton.tsx +9 -5
- package/src/lib/Components/TabBar/TabBar.tsx +3 -2
- package/src/lib/Components/index.ts +1 -0
- package/src/lib/types/index.ts +3 -3
- package/src/styles/lx/resolveStyle.ts +4 -3
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import type { FC } from 'react';
|
|
2
3
|
import { useState } from 'react';
|
|
3
4
|
import { Button } from '../Button';
|
|
4
5
|
import { SearchInput } from '../SearchInput';
|
|
5
|
-
import {
|
|
6
|
+
import { Spot } from '../Spot';
|
|
7
|
+
import { Box, RadialGradient, Text } from '../Utility';
|
|
6
8
|
import { BottomSheet } from './BottomSheet';
|
|
7
9
|
import { BottomSheetHeader } from './BottomSheetHeader';
|
|
8
10
|
import {
|
|
@@ -11,6 +13,7 @@ import {
|
|
|
11
13
|
BottomSheetView,
|
|
12
14
|
BottomSheetVirtualizedList,
|
|
13
15
|
} from './Scrollables';
|
|
16
|
+
import type { BottomSheetBackgroundProps } from './types';
|
|
14
17
|
import { useBottomSheetRef } from './useBottomSheetRef';
|
|
15
18
|
|
|
16
19
|
const meta = {
|
|
@@ -654,3 +657,173 @@ export const VirtualizedList: Story = {
|
|
|
654
657
|
);
|
|
655
658
|
},
|
|
656
659
|
};
|
|
660
|
+
|
|
661
|
+
type StrongBackgroundColor = 'errorStrong' | 'successStrong' | 'mutedStrong';
|
|
662
|
+
|
|
663
|
+
const createGradientBackground =
|
|
664
|
+
(color: StrongBackgroundColor): FC<BottomSheetBackgroundProps> =>
|
|
665
|
+
({ style }) => (
|
|
666
|
+
<Box
|
|
667
|
+
style={style}
|
|
668
|
+
lx={{ backgroundColor: 'canvasSheet', overflow: 'hidden' }}
|
|
669
|
+
>
|
|
670
|
+
<RadialGradient
|
|
671
|
+
center={{ x: 0.5, y: 0 }}
|
|
672
|
+
stops={[
|
|
673
|
+
{ color, offset: 0, opacity: 0.3 },
|
|
674
|
+
{ color, offset: 1, opacity: 0 },
|
|
675
|
+
]}
|
|
676
|
+
lx={{
|
|
677
|
+
position: 'absolute',
|
|
678
|
+
top: 's0',
|
|
679
|
+
left: 's0',
|
|
680
|
+
right: 's0',
|
|
681
|
+
height: 's320',
|
|
682
|
+
}}
|
|
683
|
+
/>
|
|
684
|
+
</Box>
|
|
685
|
+
);
|
|
686
|
+
|
|
687
|
+
const ErrorBackground = createGradientBackground('errorStrong');
|
|
688
|
+
const SuccessBackground = createGradientBackground('successStrong');
|
|
689
|
+
const MutedBackground = createGradientBackground('mutedStrong');
|
|
690
|
+
|
|
691
|
+
export const InfoStateVariants: Story = {
|
|
692
|
+
args: {
|
|
693
|
+
snapPoints: 'full',
|
|
694
|
+
hideCloseButton: false,
|
|
695
|
+
onBack: undefined,
|
|
696
|
+
onClose: undefined,
|
|
697
|
+
enableHandlePanningGesture: true,
|
|
698
|
+
enablePanDownToClose: true,
|
|
699
|
+
enableBlurKeyboardOnGesture: true,
|
|
700
|
+
enableDynamicSizing: false,
|
|
701
|
+
detached: false,
|
|
702
|
+
backdropPressBehavior: 'close',
|
|
703
|
+
hideHandle: true,
|
|
704
|
+
},
|
|
705
|
+
render: (args) => {
|
|
706
|
+
const errorBottomSheetRef = useBottomSheetRef();
|
|
707
|
+
const successBottomSheetRef = useBottomSheetRef();
|
|
708
|
+
const mutedBottomSheetRef = useBottomSheetRef();
|
|
709
|
+
|
|
710
|
+
return (
|
|
711
|
+
<Box
|
|
712
|
+
lx={{
|
|
713
|
+
height: 's320',
|
|
714
|
+
width: 'full',
|
|
715
|
+
alignItems: 'center',
|
|
716
|
+
justifyContent: 'center',
|
|
717
|
+
paddingTop: 's32',
|
|
718
|
+
gap: 's12',
|
|
719
|
+
}}
|
|
720
|
+
>
|
|
721
|
+
<Button
|
|
722
|
+
size='sm'
|
|
723
|
+
onPress={() => errorBottomSheetRef.current?.present()}
|
|
724
|
+
>
|
|
725
|
+
Error
|
|
726
|
+
</Button>
|
|
727
|
+
<Button
|
|
728
|
+
size='sm'
|
|
729
|
+
onPress={() => successBottomSheetRef.current?.present()}
|
|
730
|
+
>
|
|
731
|
+
Success
|
|
732
|
+
</Button>
|
|
733
|
+
<Button
|
|
734
|
+
size='sm'
|
|
735
|
+
onPress={() => mutedBottomSheetRef.current?.present()}
|
|
736
|
+
>
|
|
737
|
+
Muted
|
|
738
|
+
</Button>
|
|
739
|
+
|
|
740
|
+
<BottomSheet
|
|
741
|
+
{...args}
|
|
742
|
+
ref={errorBottomSheetRef}
|
|
743
|
+
backgroundComponent={ErrorBackground}
|
|
744
|
+
>
|
|
745
|
+
<BottomSheetView>
|
|
746
|
+
<BottomSheetHeader density='compact' />
|
|
747
|
+
<Box lx={{ alignItems: 'center', gap: 's24' }}>
|
|
748
|
+
<Spot appearance='error' size={72} />
|
|
749
|
+
<Box lx={{ alignItems: 'center', gap: 's12' }}>
|
|
750
|
+
<Text typography='heading4SemiBold' lx={{ color: 'base' }}>
|
|
751
|
+
Title
|
|
752
|
+
</Text>
|
|
753
|
+
<Text
|
|
754
|
+
typography='body2'
|
|
755
|
+
lx={{ color: 'muted', textAlign: 'center' }}
|
|
756
|
+
>
|
|
757
|
+
Description
|
|
758
|
+
</Text>
|
|
759
|
+
</Box>
|
|
760
|
+
</Box>
|
|
761
|
+
<Box lx={{ marginTop: 's24' }}>
|
|
762
|
+
<Button appearance='base' size='lg' isFull>
|
|
763
|
+
Label
|
|
764
|
+
</Button>
|
|
765
|
+
</Box>
|
|
766
|
+
</BottomSheetView>
|
|
767
|
+
</BottomSheet>
|
|
768
|
+
|
|
769
|
+
<BottomSheet
|
|
770
|
+
{...args}
|
|
771
|
+
ref={successBottomSheetRef}
|
|
772
|
+
backgroundComponent={SuccessBackground}
|
|
773
|
+
>
|
|
774
|
+
<BottomSheetView>
|
|
775
|
+
<BottomSheetHeader density='compact' />
|
|
776
|
+
<Box lx={{ alignItems: 'center', gap: 's24' }}>
|
|
777
|
+
<Spot appearance='check' size={72} />
|
|
778
|
+
<Box lx={{ alignItems: 'center', gap: 's12' }}>
|
|
779
|
+
<Text typography='heading4SemiBold' lx={{ color: 'base' }}>
|
|
780
|
+
Title
|
|
781
|
+
</Text>
|
|
782
|
+
<Text
|
|
783
|
+
typography='body2'
|
|
784
|
+
lx={{ color: 'muted', textAlign: 'center' }}
|
|
785
|
+
>
|
|
786
|
+
Description
|
|
787
|
+
</Text>
|
|
788
|
+
</Box>
|
|
789
|
+
</Box>
|
|
790
|
+
<Box lx={{ marginTop: 's24' }}>
|
|
791
|
+
<Button appearance='base' size='lg' isFull>
|
|
792
|
+
Label
|
|
793
|
+
</Button>
|
|
794
|
+
</Box>
|
|
795
|
+
</BottomSheetView>
|
|
796
|
+
</BottomSheet>
|
|
797
|
+
|
|
798
|
+
<BottomSheet
|
|
799
|
+
{...args}
|
|
800
|
+
ref={mutedBottomSheetRef}
|
|
801
|
+
backgroundComponent={MutedBackground}
|
|
802
|
+
>
|
|
803
|
+
<BottomSheetView>
|
|
804
|
+
<BottomSheetHeader density='compact' />
|
|
805
|
+
<Box lx={{ alignItems: 'center', gap: 's24' }}>
|
|
806
|
+
<Spot appearance='info' size={72} />
|
|
807
|
+
<Box lx={{ alignItems: 'center', gap: 's12' }}>
|
|
808
|
+
<Text typography='heading4SemiBold' lx={{ color: 'base' }}>
|
|
809
|
+
Title
|
|
810
|
+
</Text>
|
|
811
|
+
<Text
|
|
812
|
+
typography='body2'
|
|
813
|
+
lx={{ color: 'muted', textAlign: 'center' }}
|
|
814
|
+
>
|
|
815
|
+
Description
|
|
816
|
+
</Text>
|
|
817
|
+
</Box>
|
|
818
|
+
</Box>
|
|
819
|
+
<Box lx={{ marginTop: 's24' }}>
|
|
820
|
+
<Button appearance='base' size='lg' isFull>
|
|
821
|
+
Label
|
|
822
|
+
</Button>
|
|
823
|
+
</Box>
|
|
824
|
+
</BottomSheetView>
|
|
825
|
+
</BottomSheet>
|
|
826
|
+
</Box>
|
|
827
|
+
);
|
|
828
|
+
},
|
|
829
|
+
};
|
|
@@ -184,6 +184,65 @@ describe('BottomSheet', () => {
|
|
|
184
184
|
expect(element.props['data-detached']).toBe('true');
|
|
185
185
|
});
|
|
186
186
|
|
|
187
|
+
it('uses default background style when no backgroundComponent is provided', () => {
|
|
188
|
+
const { BottomSheet } = require('./BottomSheet');
|
|
189
|
+
const { getByTestId } = renderWithTheme(
|
|
190
|
+
<BottomSheet testID='bottom-sheet'>
|
|
191
|
+
<Text>Content</Text>
|
|
192
|
+
</BottomSheet>,
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
const element = getByTestId('bottom-sheet');
|
|
196
|
+
expect(element.props['data-has-background-component']).toBe('false');
|
|
197
|
+
expect(element.props['data-has-background-style']).toBe('true');
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('renders the default handle when hideHandle is not set', () => {
|
|
201
|
+
const { BottomSheet } = require('./BottomSheet');
|
|
202
|
+
const { getByTestId, queryByTestId } = renderWithTheme(
|
|
203
|
+
<BottomSheet testID='bottom-sheet'>
|
|
204
|
+
<Text>Content</Text>
|
|
205
|
+
</BottomSheet>,
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
expect(getByTestId('bottom-sheet-handle')).toBeTruthy();
|
|
209
|
+
expect(queryByTestId('bottom-sheet-handle-hidden')).toBeNull();
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('renders the hidden handle placeholder when hideHandle is true', () => {
|
|
213
|
+
const { BottomSheet } = require('./BottomSheet');
|
|
214
|
+
const { getByTestId, queryByTestId } = renderWithTheme(
|
|
215
|
+
<BottomSheet hideHandle testID='bottom-sheet'>
|
|
216
|
+
<Text>Content</Text>
|
|
217
|
+
</BottomSheet>,
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
expect(getByTestId('bottom-sheet-handle-hidden')).toBeTruthy();
|
|
221
|
+
expect(queryByTestId('bottom-sheet-handle')).toBeNull();
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('forwards backgroundComponent and skips default background style', () => {
|
|
225
|
+
const { BottomSheet } = require('./BottomSheet');
|
|
226
|
+
const CustomBackground = () => (
|
|
227
|
+
<View testID='custom-bg'>
|
|
228
|
+
<Text>BG</Text>
|
|
229
|
+
</View>
|
|
230
|
+
);
|
|
231
|
+
const { getByTestId } = renderWithTheme(
|
|
232
|
+
<BottomSheet
|
|
233
|
+
backgroundComponent={CustomBackground}
|
|
234
|
+
testID='bottom-sheet'
|
|
235
|
+
>
|
|
236
|
+
<Text>Content</Text>
|
|
237
|
+
</BottomSheet>,
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
const element = getByTestId('bottom-sheet');
|
|
241
|
+
expect(element.props['data-has-background-component']).toBe('true');
|
|
242
|
+
expect(element.props['data-has-background-style']).toBe('false');
|
|
243
|
+
expect(getByTestId('custom-bg')).toBeTruthy();
|
|
244
|
+
});
|
|
245
|
+
|
|
187
246
|
it('respects enableHandlePanningGesture prop', () => {
|
|
188
247
|
const { BottomSheet } = require('./BottomSheet');
|
|
189
248
|
const { getByTestId } = renderWithTheme(
|
|
@@ -6,7 +6,7 @@ import { StyleSheet } from 'react-native';
|
|
|
6
6
|
import { useStyleSheet } from '../../../styles';
|
|
7
7
|
import { RuntimeConstants } from '../../utils';
|
|
8
8
|
import { CustomBackdrop } from './CustomBackdrop';
|
|
9
|
-
import { CustomHandle } from './CustomHandle';
|
|
9
|
+
import { CustomHandle, HiddenHandle } from './CustomHandle';
|
|
10
10
|
import type { BottomSheetProps } from './types';
|
|
11
11
|
|
|
12
12
|
const OFFSET_TOP = 25;
|
|
@@ -25,7 +25,13 @@ const MAX_DYNAMIC_CONTENT_SIZE = {
|
|
|
25
25
|
fullWithOffset: FULL_WITH_OFFSET,
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
const useStyles = ({
|
|
28
|
+
const useStyles = ({
|
|
29
|
+
shadow,
|
|
30
|
+
hasCustomBackground,
|
|
31
|
+
}: {
|
|
32
|
+
shadow: boolean;
|
|
33
|
+
hasCustomBackground: boolean;
|
|
34
|
+
}) => {
|
|
29
35
|
return useStyleSheet(
|
|
30
36
|
(t) => ({
|
|
31
37
|
root: StyleSheet.flatten([
|
|
@@ -35,7 +41,7 @@ const useStyles = ({ shadow }: { shadow: boolean }) => {
|
|
|
35
41
|
flex: 1,
|
|
36
42
|
borderTopLeftRadius: t.borderRadius.xl,
|
|
37
43
|
borderTopRightRadius: t.borderRadius.xl,
|
|
38
|
-
|
|
44
|
+
overflow: 'hidden',
|
|
39
45
|
},
|
|
40
46
|
shadow && {
|
|
41
47
|
boxShadow: t.shadows.lg,
|
|
@@ -46,7 +52,7 @@ const useStyles = ({ shadow }: { shadow: boolean }) => {
|
|
|
46
52
|
backgroundColor: t.colors.bg.canvasSheet,
|
|
47
53
|
},
|
|
48
54
|
}),
|
|
49
|
-
[shadow],
|
|
55
|
+
[shadow, hasCustomBackground],
|
|
50
56
|
);
|
|
51
57
|
};
|
|
52
58
|
|
|
@@ -74,6 +80,8 @@ export const BottomSheet = ({
|
|
|
74
80
|
onBackdropPress,
|
|
75
81
|
onChange,
|
|
76
82
|
snapPoints = 'fullWithOffset',
|
|
83
|
+
backgroundComponent,
|
|
84
|
+
hideHandle = false,
|
|
77
85
|
ref,
|
|
78
86
|
...props
|
|
79
87
|
}: BottomSheetProps) => {
|
|
@@ -82,7 +90,10 @@ export const BottomSheet = ({
|
|
|
82
90
|
const mergedRefs = useMergedRef<GorhomBottomSheetModal>(ref, innerRef);
|
|
83
91
|
const [isOpen, setIsOpen] = useState(false);
|
|
84
92
|
|
|
85
|
-
const styles = useStyles({
|
|
93
|
+
const styles = useStyles({
|
|
94
|
+
shadow: hideBackdrop && isOpen,
|
|
95
|
+
hasCustomBackground: Boolean(backgroundComponent),
|
|
96
|
+
});
|
|
86
97
|
|
|
87
98
|
/**
|
|
88
99
|
* Match the snap points to the preset or the custom snap points array
|
|
@@ -163,7 +174,8 @@ export const BottomSheet = ({
|
|
|
163
174
|
{...props}
|
|
164
175
|
ref={mergedRefs}
|
|
165
176
|
style={styles.root}
|
|
166
|
-
backgroundStyle={styles.background}
|
|
177
|
+
backgroundStyle={backgroundComponent ? undefined : styles.background}
|
|
178
|
+
backgroundComponent={backgroundComponent}
|
|
167
179
|
onChange={handleChange}
|
|
168
180
|
onAnimate={handleAnimate}
|
|
169
181
|
/**
|
|
@@ -188,7 +200,7 @@ export const BottomSheet = ({
|
|
|
188
200
|
/**
|
|
189
201
|
* Components
|
|
190
202
|
*/
|
|
191
|
-
handleComponent={CustomHandle}
|
|
203
|
+
handleComponent={hideHandle ? HiddenHandle : CustomHandle}
|
|
192
204
|
backdropComponent={hideBackdrop ? undefined : renderBackdrop}
|
|
193
205
|
>
|
|
194
206
|
<BottomSheetProvider value={{ onBack, hideCloseButton }}>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BottomSheetVariables } from '@gorhom/bottom-sheet/lib/typescript/types';
|
|
2
|
-
import type { Ref } from 'react';
|
|
2
|
+
import type { ComponentRef, Ref } from 'react';
|
|
3
3
|
import { View } from 'react-native';
|
|
4
4
|
import { useStyleSheet } from '../../../styles';
|
|
5
5
|
|
|
@@ -12,13 +12,13 @@ const useStyles = () => {
|
|
|
12
12
|
alignItems: 'center',
|
|
13
13
|
justifyContent: 'center',
|
|
14
14
|
alignSelf: 'center',
|
|
15
|
-
backgroundColor:
|
|
15
|
+
backgroundColor: 'transparent',
|
|
16
16
|
},
|
|
17
17
|
handle: {
|
|
18
18
|
height: t.spacings.s4,
|
|
19
19
|
width: t.sizes.s36,
|
|
20
20
|
borderRadius: t.borderRadius.full,
|
|
21
|
-
backgroundColor: t.colors.bg.
|
|
21
|
+
backgroundColor: t.colors.bg.mutedTransparentPressed,
|
|
22
22
|
},
|
|
23
23
|
}),
|
|
24
24
|
[],
|
|
@@ -28,12 +28,33 @@ const useStyles = () => {
|
|
|
28
28
|
export const CustomHandle = ({
|
|
29
29
|
ref,
|
|
30
30
|
...props
|
|
31
|
-
}: BottomSheetVariables & { ref?: Ref<
|
|
31
|
+
}: BottomSheetVariables & { ref?: Ref<ComponentRef<typeof View>> }) => {
|
|
32
32
|
const styles = useStyles();
|
|
33
33
|
|
|
34
34
|
return (
|
|
35
|
-
<View
|
|
35
|
+
<View
|
|
36
|
+
{...props}
|
|
37
|
+
ref={ref}
|
|
38
|
+
style={styles.container}
|
|
39
|
+
testID='bottom-sheet-handle'
|
|
40
|
+
>
|
|
36
41
|
<View style={styles.handle} />
|
|
37
42
|
</View>
|
|
38
43
|
);
|
|
39
44
|
};
|
|
45
|
+
|
|
46
|
+
export const HiddenHandle = ({
|
|
47
|
+
ref,
|
|
48
|
+
...props
|
|
49
|
+
}: BottomSheetVariables & { ref?: Ref<ComponentRef<typeof View>> }) => {
|
|
50
|
+
const styles = useStyles();
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<View
|
|
54
|
+
{...props}
|
|
55
|
+
ref={ref}
|
|
56
|
+
style={styles.container}
|
|
57
|
+
testID='bottom-sheet-handle-hidden'
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
@@ -5,16 +5,23 @@ import type {
|
|
|
5
5
|
BottomSheetSectionList as GorhomBottomSheetSectionList,
|
|
6
6
|
BottomSheetScrollView as GorhomBottomSheetScrollView,
|
|
7
7
|
BottomSheetVirtualizedList as GorhomBottomSheetVirtualizedList,
|
|
8
|
+
BottomSheetBackgroundProps,
|
|
8
9
|
} from '@gorhom/bottom-sheet';
|
|
9
|
-
|
|
10
10
|
import type { Density } from '@ledgerhq/lumen-utils-shared';
|
|
11
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
ComponentRef,
|
|
13
|
+
FC,
|
|
14
|
+
PropsWithChildren,
|
|
15
|
+
ReactNode,
|
|
16
|
+
Ref,
|
|
17
|
+
} from 'react';
|
|
18
|
+
|
|
12
19
|
import type { StyledViewProps } from '../../../styles';
|
|
13
20
|
export type BottomSheetProps = PropsWithChildren & {
|
|
14
21
|
/**
|
|
15
22
|
* Ref to the bottom sheet component.
|
|
16
23
|
*/
|
|
17
|
-
ref?: Ref<
|
|
24
|
+
ref?: Ref<ComponentRef<typeof GorhomBottomSheetModal>>;
|
|
18
25
|
/**
|
|
19
26
|
* Used to locate this view in end-to-end tests.
|
|
20
27
|
*/
|
|
@@ -131,8 +138,22 @@ export type BottomSheetProps = PropsWithChildren & {
|
|
|
131
138
|
* @default true
|
|
132
139
|
*/
|
|
133
140
|
enableBlurKeyboardOnGesture?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Custom background component rendered behind the sheet content and handle.
|
|
143
|
+
* Use to render gradients or other effects that should span the full sheet area,
|
|
144
|
+
* including the handle strip. When provided, the default sheet background is removed.
|
|
145
|
+
* @default undefined
|
|
146
|
+
*/
|
|
147
|
+
backgroundComponent?: FC<BottomSheetBackgroundProps> | null;
|
|
148
|
+
/**
|
|
149
|
+
* If true, the drag handle (grabber) at the top of the sheet is hidden.
|
|
150
|
+
* @default false
|
|
151
|
+
*/
|
|
152
|
+
hideHandle?: boolean;
|
|
134
153
|
};
|
|
135
154
|
|
|
155
|
+
export type { BottomSheetBackgroundProps };
|
|
156
|
+
|
|
136
157
|
export type BottomSheetHeaderProps = {
|
|
137
158
|
/**
|
|
138
159
|
* The density of the header.
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
DisabledProvider,
|
|
4
4
|
isTextChildren,
|
|
5
5
|
} from '@ledgerhq/lumen-utils-shared';
|
|
6
|
-
import type { ReactNode, Ref } from 'react';
|
|
6
|
+
import type { ComponentRef, ReactNode, Ref } from 'react';
|
|
7
7
|
import { useCallback, useEffect, useMemo } from 'react';
|
|
8
8
|
import type { LayoutChangeEvent, ViewStyle } from 'react-native';
|
|
9
9
|
import { StyleSheet, View } from 'react-native';
|
|
@@ -486,7 +486,7 @@ export const CardContentTitle = ({
|
|
|
486
486
|
if (isTextChildren(children)) {
|
|
487
487
|
return (
|
|
488
488
|
<Text
|
|
489
|
-
ref={ref as Ref<
|
|
489
|
+
ref={ref as Ref<ComponentRef<typeof Text>>}
|
|
490
490
|
lx={lx}
|
|
491
491
|
style={StyleSheet.flatten([styles.asText, style])}
|
|
492
492
|
numberOfLines={1}
|
|
@@ -553,7 +553,7 @@ export const CardContentDescription = ({
|
|
|
553
553
|
if (isTextChildren(children)) {
|
|
554
554
|
return (
|
|
555
555
|
<Text
|
|
556
|
-
ref={ref as Ref<
|
|
556
|
+
ref={ref as Ref<ComponentRef<typeof Text>>}
|
|
557
557
|
lx={lx}
|
|
558
558
|
style={StyleSheet.flatten([styles.asText, style])}
|
|
559
559
|
numberOfLines={1}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import * as DescriptionItemStories from './DescriptionItem.stories';
|
|
3
|
+
import { CustomTabs, Tab } from '../../../../.storybook/components';
|
|
4
|
+
|
|
5
|
+
<Meta title='Containment/DescriptionItem' of={DescriptionItemStories} />
|
|
6
|
+
|
|
7
|
+
# DescriptionItem
|
|
8
|
+
|
|
9
|
+
> View in [Figma](https://www.figma.com/design/JxaLVMTWirCpU0rsbZ30k7/2.-Components-Library?node-id=10311-11837&m=dev).
|
|
10
|
+
|
|
11
|
+
<CustomTabs>
|
|
12
|
+
<Tab label="Overview">
|
|
13
|
+
|
|
14
|
+
## Introduction
|
|
15
|
+
|
|
16
|
+
DescriptionItem is a compound component for displaying key-value rows — typically used inside a summary panel, transaction detail, or settings screen. It composes a leading label side and a trailing value side, with the trailing always taking priority over the leading when space is constrained.
|
|
17
|
+
|
|
18
|
+
## Anatomy
|
|
19
|
+
|
|
20
|
+
<Canvas of={DescriptionItemStories.Base} />
|
|
21
|
+
|
|
22
|
+
- **DescriptionItem**: Root row container. Accepts an optional `size` prop (`md` | `sm`).
|
|
23
|
+
- **DescriptionItemLeading**: Left section holding the label and any optional sibling (e.g. a tooltip icon).
|
|
24
|
+
- **DescriptionItemLabel**: Muted text label. Wraps to a second line before truncating (`numberOfLines={2}`).
|
|
25
|
+
- **DescriptionItemTrailing**: Right section holding the value or any inline element (Tag, Link, etc.). Never shrinks — always has layout priority.
|
|
26
|
+
- **DescriptionItemValue**: Semi-bold value text. Truncates to a single line (`numberOfLines={1}`).
|
|
27
|
+
|
|
28
|
+
## Properties
|
|
29
|
+
|
|
30
|
+
<Canvas of={DescriptionItemStories.Base} />
|
|
31
|
+
<Controls of={DescriptionItemStories.Base} />
|
|
32
|
+
|
|
33
|
+
### Trailing variants
|
|
34
|
+
|
|
35
|
+
The trailing section accepts any content — a plain value, a `Tag`, multiple `Tag`s, or a custom element. Use `DescriptionItemValue` for plain text; place other components directly in `DescriptionItemTrailing`.
|
|
36
|
+
|
|
37
|
+
<Canvas of={DescriptionItemStories.TrailingVariants} />
|
|
38
|
+
|
|
39
|
+
### Size
|
|
40
|
+
|
|
41
|
+
Two sizes are available — `md` (default) and `sm`.
|
|
42
|
+
|
|
43
|
+
- The size of `DescriptionItemValue` is inherited from the parent `DescriptionItem`.
|
|
44
|
+
- The size of additional trailing content (e.g. `Tag`) needs to be set explicitly.
|
|
45
|
+
|
|
46
|
+
<Canvas of={DescriptionItemStories.SizeShowcase} />
|
|
47
|
+
|
|
48
|
+
### With info tooltip
|
|
49
|
+
|
|
50
|
+
Pair a `Tooltip` with an info icon inside `DescriptionItemLeading` to surface additional context without cluttering the label.
|
|
51
|
+
|
|
52
|
+
<Canvas of={DescriptionItemStories.WithInfoIcon} />
|
|
53
|
+
|
|
54
|
+
### Truncation
|
|
55
|
+
|
|
56
|
+
The label can wrap to two lines before truncating. The trailing value truncates after one line. When both sides have long content, the trailing always gets layout priority.
|
|
57
|
+
|
|
58
|
+
<Canvas of={DescriptionItemStories.TruncationBehavior} />
|
|
59
|
+
|
|
60
|
+
</Tab>
|
|
61
|
+
<Tab label="Implementation">
|
|
62
|
+
|
|
63
|
+
## Setup
|
|
64
|
+
|
|
65
|
+
Install and set up the library with our [Setup Guide →](?path=/docs/getting-started-setup--docs).
|
|
66
|
+
|
|
67
|
+
## Basic Usage
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import {
|
|
71
|
+
DescriptionItem,
|
|
72
|
+
DescriptionItemLabel,
|
|
73
|
+
DescriptionItemLeading,
|
|
74
|
+
DescriptionItemTrailing,
|
|
75
|
+
DescriptionItemValue,
|
|
76
|
+
} from '@ledgerhq/lumen-ui-rnative';
|
|
77
|
+
|
|
78
|
+
function MyComponent() {
|
|
79
|
+
return (
|
|
80
|
+
<DescriptionItem size='md'>
|
|
81
|
+
<DescriptionItemLeading>
|
|
82
|
+
<DescriptionItemLabel>Fees</DescriptionItemLabel>
|
|
83
|
+
</DescriptionItemLeading>
|
|
84
|
+
<DescriptionItemTrailing>
|
|
85
|
+
<DescriptionItemValue>0.001 BTC</DescriptionItemValue>
|
|
86
|
+
</DescriptionItemTrailing>
|
|
87
|
+
</DescriptionItem>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### With info tooltip
|
|
93
|
+
|
|
94
|
+
Use a `Tooltip` alongside the label to add contextual information:
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
import {
|
|
98
|
+
DescriptionItem,
|
|
99
|
+
DescriptionItemLabel,
|
|
100
|
+
DescriptionItemLeading,
|
|
101
|
+
DescriptionItemTrailing,
|
|
102
|
+
DescriptionItemValue,
|
|
103
|
+
InteractiveIcon,
|
|
104
|
+
Tooltip,
|
|
105
|
+
TooltipTrigger,
|
|
106
|
+
TooltipContent,
|
|
107
|
+
} from '@ledgerhq/lumen-ui-rnative';
|
|
108
|
+
import { Information } from '@ledgerhq/lumen-ui-rnative/symbols';
|
|
109
|
+
import { Text } from 'react-native';
|
|
110
|
+
|
|
111
|
+
function MyComponent() {
|
|
112
|
+
return (
|
|
113
|
+
<DescriptionItem>
|
|
114
|
+
<DescriptionItemLeading>
|
|
115
|
+
<DescriptionItemLabel>Fees</DescriptionItemLabel>
|
|
116
|
+
<Tooltip>
|
|
117
|
+
<TooltipTrigger>
|
|
118
|
+
<InteractiveIcon
|
|
119
|
+
icon={Information}
|
|
120
|
+
size={16}
|
|
121
|
+
iconType='stroked'
|
|
122
|
+
accessibilityLabel='More information'
|
|
123
|
+
/>
|
|
124
|
+
</TooltipTrigger>
|
|
125
|
+
<TooltipContent
|
|
126
|
+
content={<Text>Network fee paid to miners</Text>}
|
|
127
|
+
/>
|
|
128
|
+
</Tooltip>
|
|
129
|
+
</DescriptionItemLeading>
|
|
130
|
+
<DescriptionItemTrailing>
|
|
131
|
+
<DescriptionItemValue>0.001 BTC</DescriptionItemValue>
|
|
132
|
+
</DescriptionItemTrailing>
|
|
133
|
+
</DescriptionItem>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
</Tab>
|
|
139
|
+
</CustomTabs>
|