Skip to content

Commit

Permalink
Merge branch 'ONE-3411-merge-react-native-components' into 'main'
Browse files Browse the repository at this point in the history
[ONE-3411] Merge react-native-components for wallet

Closes ONE-3411

See merge request procivis/one/one-react-native-components!144
  • Loading branch information
procivisAG committed Sep 19, 2024
2 parents 6b5de27 + 8b72c8e commit 7730b90
Show file tree
Hide file tree
Showing 13 changed files with 349 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .ondevice/storybook.requires.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ try {

const getStories = () => {
return [
require("../src/action-modal/ActionModal.stories.tsx"),
require("../src/buttons/back-button.stories.tsx"),
require("../src/buttons/button.stories.tsx"),
require("../src/buttons/ghost-button.stories.tsx"),
Expand All @@ -52,6 +53,7 @@ const getStories = () => {
require("../src/screens/image-preview-screen.stories.tsx"),
require("../src/screens/qr-code-scanner-screen.stories.tsx"),
require("../src/searchbar/search-bar.stories.tsx"),
require("../src/state/error-screen.stories.tsx"),
require("../src/text/typography.stories.tsx"),
];
};
Expand Down
4 changes: 2 additions & 2 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1299,11 +1299,11 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
FBLazyVector: 98c189b92292d4bfeac13ffa8df3ce3d84e2fc5b
FBReactNativeSpec: 4fe1d8c2fadc7949344b197d933f76b40401aac5
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: ed62e0dcd013bf4a3b487f164feec1c4e705b5b5
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
RCT-Folly: 7169b2b1c44399c76a47b5deaaba715eeeb476c0
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@procivis/one-react-native-components",
"version": "0.1.38",
"version": "0.1.39",
"author": "Procivis AG (https://procivis.ch)",
"license": "Apache-2.0",
"description": "Common Procivis ONE UI components for react-native",
Expand Down
35 changes: 35 additions & 0 deletions src/action-modal/ActionModal.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { ComponentMeta, Story } from '@storybook/react';
import React, { useState } from 'react';
import { View } from 'react-native';

import { Button } from '../buttons';
import { Typography } from '../text';
import ActionModal from './ActionModal';

const Basic: Story = () => {
const [visible, setVisible] = useState(false);
return (
<>
<Button title="Show modal" onPress={() => setVisible(true)} />
<ActionModal visible={visible}>
<View>
<Typography color={'white'}>Example text in modal</Typography>
<Button title="Hide modal" onPress={() => setVisible(false)} />
</View>
</ActionModal>
</>
);
};

export { Basic as ActionModal };

export default {
title: 'base/Action Modal',
component: ActionModal,
parameters: {
design: {
type: 'figma',
url: 'https://www.figma.com/file/Gd0Tj0234hxtl3HMcCJThW/App-Component-Library-(Design)?node-id=391-9097&t=WhKthlRU5MCuUWfw-0',
},
},
} as ComponentMeta<typeof ActionModal>;
45 changes: 45 additions & 0 deletions src/action-modal/ActionModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React, { FunctionComponent, PropsWithChildren } from 'react';
import { Modal, StyleProp, StyleSheet, View, ViewStyle } from 'react-native';

import { useAppColorScheme } from '../theme';

interface Props {
contentStyle?: StyleProp<ViewStyle>;
style?: StyleProp<ViewStyle>;
visible: boolean;
testID?: string;
}

const styles = StyleSheet.create({
background: {
height: '100%',
width: '100%',
},
contentContainer: {
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
marginTop: 'auto',
width: '100%',
},
});

const ActionModal: FunctionComponent<PropsWithChildren<Props>> = ({
children,
contentStyle,
style,
visible,
testID,
}) => {
const colorScheme = useAppColorScheme();
const overlay = 'rgba(0, 0, 0, 0.5)';

return (
<Modal animationType="fade" statusBarTranslucent style={style} transparent visible={visible}>
<View testID={testID} style={[styles.background, { backgroundColor: overlay }]}>
<View style={[styles.contentContainer, { backgroundColor: colorScheme.white }, contentStyle]}>{children}</View>
</View>
</Modal>
);
};

export default ActionModal;
3 changes: 3 additions & 0 deletions src/action-modal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import ActionModal from './ActionModal';

export { ActionModal };
80 changes: 80 additions & 0 deletions src/gradient/gradient-background.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React, { FunctionComponent, useMemo } from 'react';
import { StyleSheet, useWindowDimensions } from 'react-native';
import Svg, { Defs, LinearGradient, Rect, Stop, SvgProps } from 'react-native-svg';

import { colorArray } from '../utils/color';

export interface GradientBackgroundProps extends SvgProps {
/**
* Custom boundary colors
* default: colorScheme.linearGradient
*/
colors?: readonly [string, string];
/**
* Gradient color change direction
* default: `undefined` (for background)
*/
direction?: 'horizontal' | 'vertical';
/**
* Flag for disabling absolute fill
* default: `true`
*/
absoluteFill?: boolean;
}

const linearGradient = ['rgba(255, 255, 255, 1)', 'rgba(255, 255, 255, 0)'];

const GradientBackground: FunctionComponent<GradientBackgroundProps> = ({
style,
colors,
direction,
absoluteFill = true,
...props
}) => {
const sceenDimensions = useWindowDimensions();

const width = props.width ?? sceenDimensions.width;
const height = props.height ?? sceenDimensions.height;

const svgColors = useMemo(
() =>
(colors ?? linearGradient).map(colorArray).map(([r, g, b, a]) => ({
stopColor: `rgb(${r * 255},${g * 255},${b * 255})`,
stopOpacity: a,
})),
[colors],
);

let gradientDirectionProps;
switch (direction) {
case 'vertical':
gradientDirectionProps = {
gradientTransform: 'rotate(90)',
};
break;
case 'horizontal':
gradientDirectionProps = {};
break;
default:
gradientDirectionProps = { x1: 0, y1: 0, x2: 0, y2: 1 };
break;
}
return (
<Svg
accessible={false}
width={width}
height={height}
style={[absoluteFill ? StyleSheet.absoluteFill : undefined, style]}
{...props}>
<Defs>
<LinearGradient id="grad" {...gradientDirectionProps}>
<Stop offset={0} {...svgColors[0]} />
<Stop offset={1} {...svgColors[1]} />
</LinearGradient>
</Defs>
<Rect x={0} y={0} width={width} height={height} fill="url(#grad)" />
</Svg>
);
};

export default GradientBackground;
3 changes: 3 additions & 0 deletions src/gradient/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import GradientBackground from './gradient-background';

export { GradientBackground };
20 changes: 20 additions & 0 deletions src/icons/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import Svg, { Path, Rect, SvgProps } from 'react-native-svg';

import { useAppColorScheme } from '../theme/color-scheme-context';

interface IconProps {
accent?: boolean;
}

// https://www.figma.com/file/52qDYWUMjXAGre1dcnz5bz/Procivis-One-Wallet?node-id=415-10315&t=S6UEbGflD2ZT95eA-4
export const ScanIcon: FC<SvgProps> = ({ color, ...props }) => {
return (
Expand Down Expand Up @@ -132,3 +136,19 @@ export const FilterIcon: FC<SvgProps> = ({ color, ...props }) => {
</Svg>
);
};

export const ErrorStateIcon: React.FunctionComponent<IconProps> = ({ accent = true }) => {
const colorScheme = useAppColorScheme();
return (
<Svg fill="none" viewBox="0 0 160 161" width={150} height={150}>
<Rect width={160} height={160} y={0.5} fill={accent ? '#FFA0A0' : colorScheme.accent} rx={80} />
<Rect width={136} height={136} x={12} y={12.5} fill={accent ? colorScheme.accent : colorScheme.white} rx={68} />
<Path
fill={accent ? colorScheme.white : colorScheme.black}
fillRule="evenodd"
d="m80.298 53.684 30.874 50.17H49.424l30.874-50.17ZM77.162 91.31h6.271v6.272h-6.271V91.31Zm6.271-21.949h-6.271V85.04h6.271V69.362Z"
clipRule="evenodd"
/>
</Svg>
);
};
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './accessibility';
export * from './action-modal';
export * from './blur';
export * from './buttons';
export * from './camera';
Expand All @@ -18,6 +19,7 @@ export * from './pin';
export * from './screens';
export * from './searchbar';
export * from './settings';
export * from './state';
export * from './text';
export * from './theme';
export * from './utils';
36 changes: 36 additions & 0 deletions src/state/error-screen.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { ComponentMeta, Story } from '@storybook/react';
import React from 'react';

import ErrorScreen, { ErrorScreenProps, ErrorScreenVariation } from './error-screen';

const Basic: Story<ErrorScreenProps> = (props) => <ErrorScreen {...props} />;

Basic.args = {
title: 'Error',
subtitle: 'The app has reached an error state.',
variation: ErrorScreenVariation.Neutral,
buttons: [
{ label: 'Primary', onPress: () => null },
{ label: 'Secondary', onPress: () => null },
],
};

export { Basic as ErrorScreen };

export default {
title: 'view/loading/Error Screen',
component: ErrorScreen,
parameters: {
noSafeArea: true,
design: {
type: 'figma',
url: 'https://www.figma.com/file/baolhE7fB2BMdCN5RVjusX/App-Feature-Library?node-id=782%3A31982&t=EX6zyqvONranvehN-4',
},
},
argTypes: {
variation: {
options: [ErrorScreenVariation.Neutral, ErrorScreenVariation.Accent],
control: { type: 'radio' },
},
},
} as ComponentMeta<typeof ErrorScreen>;
Loading

0 comments on commit 7730b90

Please sign in to comment.