Skip to content

Commit

Permalink
[IOPLT-112] Adds the FooterWithButtons component (#53)
Browse files Browse the repository at this point in the history
## Short description
This PR creates a new version of the footer with buttons with the new
version of buttons from DS library

## How to test
Check the specific page in the Example app to see how it changes.

<img
src="https://github.com/pagopa/io-app-design-system/assets/3959405/ac5f85b6-50d9-4001-94b8-7b604541199d"
height="600"/>

---------

Co-authored-by: Damiano Plebani <[email protected]>
  • Loading branch information
CrisTofani and dmnplb authored Sep 1, 2023
1 parent 97bc7c4 commit 6c2c0a3
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 0 deletions.
10 changes: 10 additions & 0 deletions example/src/navigation/navigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { Search } from "../pages/Search";
import { TabNavigationScreen } from "../pages/TabNavigation";
import { Sandbox } from "../pages/Sandbox";
import { TextInputs } from "../pages/TextInputs";
import { FooterWithButton } from "../pages/FooterWithButton";
import { AppParamsList } from "./params";
import APP_ROUTES from "./routes";

Expand Down Expand Up @@ -167,6 +168,15 @@ const AppNavigator = () => (
}}
/>

<Stack.Screen
name={APP_ROUTES.COMPONENTS.FOOTER_WITH_BUTTON.route}
component={FooterWithButton}
options={{
headerTitle: APP_ROUTES.COMPONENTS.FOOTER_WITH_BUTTON.title,
headerBackTitleVisible: false
}}
/>

<Stack.Screen
name={APP_ROUTES.SCREENS.SEARCH.route}
component={Search}
Expand Down
1 change: 1 addition & 0 deletions example/src/navigation/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type AppParamsList = {
[DESIGN_SYSTEM_ROUTES.COMPONENTS.LIST_ITEMS.route]: undefined;
[DESIGN_SYSTEM_ROUTES.COMPONENTS.TAB_NAVIGATION.route]: undefined;
[DESIGN_SYSTEM_ROUTES.COMPONENTS.TEXT_INPUT.route]: undefined;
[DESIGN_SYSTEM_ROUTES.COMPONENTS.FOOTER_WITH_BUTTON.route]: undefined;
[DESIGN_SYSTEM_ROUTES.SCREENS.FULL_SCREEN_MODAL.route]: undefined;
[DESIGN_SYSTEM_ROUTES.SCREENS.SEARCH.route]: undefined;
[DESIGN_SYSTEM_ROUTES.SANDBOX.SANDBOX_SCREEN.route]: undefined;
Expand Down
4 changes: 4 additions & 0 deletions example/src/navigation/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ const APP_ROUTES = {
TAB_NAVIGATION: {
route: "DESIGN_SYSTEM_TAB_NAVIGATION",
title: "Tab Navigation"
},
FOOTER_WITH_BUTTON: {
route: "DESIGN_SYSTEM_FOOTER_WITH_BUTTON",
title: "Footer with button"
}
},
SCREENS: {
Expand Down
47 changes: 47 additions & 0 deletions example/src/pages/FooterWithButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import * as React from "react";
import { SafeAreaView, View } from "react-native";
import {
H1,
IOStyles,
FooterWithButtons,
VSpacer
} from "@pagopa/io-app-design-system";
import { constVoid } from "fp-ts/lib/function";
import { Screen } from "../components/Screen";

/**
* This Screen is used to test components in isolation while developing.
* @returns a screen with a flexed view where you can test components
*/
export const FooterWithButton = () => (
<SafeAreaView style={IOStyles.flex}>
<View style={{ flexGrow: 1 }}>
<Screen>
<VSpacer />
<H1>Footer with button</H1>
</Screen>
<FooterWithButtons
primary={{
type: "Solid",
buttonProps: {
color: "primary",
accessibilityLabel: "primary button",
onPress: constVoid,
label: "Primary button"
}
}}
secondary={{
type: "Outline",
buttonProps: {
color: "primary",
fullWidth: true,
accessibilityLabel: "secondary button",
onPress: constVoid,
label: "Secondary button"
}
}}
type="TwoButtonsInlineHalf"
/>
</View>
</SafeAreaView>
);
1 change: 1 addition & 0 deletions src/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ export * from "./tag";
export * from "./tabs";
export * from "./typography";
export * from "./textInput";
export * from "./layout";
142 changes: 142 additions & 0 deletions src/components/layout/BlockButtons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import * as React from "react";
import { View, StyleSheet } from "react-native";
import { HSpacer } from "../spacer/Spacer";
import { ButtonOutline, ButtonSolid, ButtonSolidProps } from "../buttons";
import { IOStyles } from "../../core";

const styles = StyleSheet.create({
button: {
alignContent: "center",
justifyContent: "center",
flex: 1
},
buttonTwoThirds: {
alignContent: "center",
flex: 2
}
});

type CommonProps = Readonly<{
primary: BlockButtonProps;
accessible?: boolean;
}>;

export type BlockButtonProps = {
type: "Solid" | "Outline";
buttonProps: ButtonSolidProps;
};

/**
* | single button |
*/
export interface SingleButton extends CommonProps {
type: "SingleButton";
}

/**
* | left | right |
*/
export interface TwoButtonsInlineHalf extends CommonProps {
type: "TwoButtonsInlineHalf";
secondary: BlockButtonProps;
}

/**
* | left | right |
*/
interface TwoButtonsInlineThird extends CommonProps {
type: "TwoButtonsInlineThird";
secondary: BlockButtonProps;
}

/**
* | left | right |
*/
interface TwoButtonsInlineThirdInverted extends CommonProps {
type: "TwoButtonsInlineThirdInverted";
secondary: BlockButtonProps;
}

/**
* | left | mid | right |
*/
interface ThreeButtonsInLine extends CommonProps {
type: "ThreeButtonsInLine";
secondary: BlockButtonProps;
third: BlockButtonProps;
}

type Props =
| SingleButton
| TwoButtonsInlineHalf
| TwoButtonsInlineThird
| TwoButtonsInlineThirdInverted
| ThreeButtonsInLine;

export type BlockButtonsProps = Props;

/**
* Implements a component that show buttons on a line on 1, 2 or 3 buttons
*/
export const BlockButtons = (props: Props) => {
const renderRightButton = () => {
if (props.type === "SingleButton") {
return null;
}

const secondaryButtonStyle =
props.type === "TwoButtonsInlineThird"
? styles.buttonTwoThirds
: styles.button;

return (
<React.Fragment>
<HSpacer size={16} />
{renderButton(props.secondary, secondaryButtonStyle)}
</React.Fragment>
);
};

const renderMidButton = () => {
if (props.type !== "ThreeButtonsInLine") {
return null;
}

return (
<React.Fragment>
<HSpacer size={16} />
{renderButton(props.third, styles.button)}
</React.Fragment>
);
};

const renderLeftButton = () => {
const primaryButtonStyle =
props.type === "TwoButtonsInlineThirdInverted"
? styles.buttonTwoThirds
: styles.button;

return renderButton(props.primary, primaryButtonStyle);
};

const renderButton = (
props: BlockButtonProps,
style: React.ComponentProps<typeof View>["style"]
) => (
<View style={style}>
{props.type === "Solid" ? (
<ButtonSolid {...props.buttonProps} />
) : (
<ButtonOutline {...props.buttonProps} />
)}
</View>
);

return (
<View style={{ ...IOStyles.flex, ...IOStyles.row }}>
{renderLeftButton()}
{renderMidButton()}
{renderRightButton()}
</View>
);
};
37 changes: 37 additions & 0 deletions src/components/layout/FooterWithButtons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as React from "react";

import { StyleSheet, View } from "react-native";
import { IOStyles } from "../../core";
import { BlockButtons, BlockButtonsProps } from "./BlockButtons";

// TODO: Refactor with an unique component like `FooterTopShadow` after bonus vacanze
const styles = StyleSheet.create({
container: {
overflow: "hidden",
width: "100%",
// This Magic number is an heritage of the app code-base, this component should be removed in favor of `GradientBottomAction`
marginTop: -50,
paddingTop: 50,
position: "absolute",
bottom: 0
}
});

/**
* Implements a component that show buttons as sticky footer
* It can include 1, 2 or 3 buttons. If they are 2, they can have the inlineHalf or the inlineOneThird style
*/
export const FooterWithButtons = (props: BlockButtonsProps) => (
<View
style={styles.container}
accessible={props.accessible}
pointerEvents={"box-none"}
testID="FooterWithButtons"
>
<View style={IOStyles.footer}>
<BlockButtons {...props} />
</View>
</View>
);

export default FooterWithButtons;
1 change: 1 addition & 0 deletions src/components/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from "./GradientScrollView";
export * from "./GradientBottomActions";
export * from "./HeaderFirstLevel";
export * from "./HeaderSecondLevel";
export * from "./FooterWithButtons";

0 comments on commit 6c2c0a3

Please sign in to comment.