Skip to content
Merged
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
13 changes: 13 additions & 0 deletions .changeset/dry-plants-glow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@equinor/mad-components": minor
---

- **BREAKING CHANGE**: Removed the `title` prop on the Progress component. Use the `Label`
component to achieve similar functionality in the future
- **BREAKING CHANGE**: Removed the counters shown in the description of `Progress.Item` when it is
populated with tasks. See further down for how to add this back if needed
- Modernized the `Progress` and `Progress.Item` component look
- Moved the 'show more' button to underneath the `Progress.Item` component on smaller devices
- Added option for passing a method into the description prop of `Progress.Item` with tasks. The
method should return a string and takes in the number of completed tasks and the number of total
tasks as arguments
170 changes: 90 additions & 80 deletions apps/chronicles/screens/components/components/ProgressScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import {
EDSStyleSheet,
Progress,
Spacer,
useStyles,
Typography,
CircularProgress,
useStyles,
} from "@equinor/mad-components";
import { ScrollView, View } from "react-native";
import { useProgressUpload } from "../../../hooks/useProgressUpload";
Expand Down Expand Up @@ -60,116 +59,127 @@ export const ProgressScreen = () => {
contentContainerStyle={styles.contentContainer}
>
<View style={styles.textContainer}>
<Typography group="basic" variant="h2">
Progress
</Typography>

<Typography>
The Progress component can be used for tracking and displaying the progress of
tasks or processes, such as «create folder» or «upload images».
</Typography>
<Typography>
Progress can be used with one or multiple Progress Items, and one Progress Item
can contain one single task or multiple tasks.
tasks or processes such as «create folder» or «upload images».
</Typography>
</View>

<Spacer amount="small" />
<Spacer />

<View style={styles.textContainer}>
<Typography>
Tasks have different statuses that is based on the overall progress.
</Typography>
<Typography> Status can either be:</Typography>
<View style={{ flexDirection: "row", gap: 8, alignItems: "center" }}>
<Typography color="primary">inProgress</Typography>
<CircularProgress size={18} value={0.7} />
<Typography color="textTertiary">, notStarted, </Typography>
<Typography color="success">sucess</Typography>
<Typography>or</Typography>
<Typography color="danger">error</Typography>
</View>
</View>

<Spacer amount="small" />

<View style={styles.textContainer}>
<UploadSimulator
onUploadSuccess={() => void handleUploadSuccess()}
onUploadFailed={() => void handleUploadFailed()}
/>
</View>
<Typography variant="h3">Progress and Progress.Item</Typography>

<Spacer />
<Spacer amount="small" />

<View style={styles.textContainer}>
<Typography>Progress with one single task: </Typography>
<Typography>
The root Progress component is a container for progress items. It automatically
separates the items with a separator. The progress items each describe a single
process, and are provided with a summarizing status prop to indicate its
progress:
</Typography>
</View>

<Spacer amount="small" />
<Progress title="Create folder">
<Progress.Item
title="Creating cat images folder"
description="This folder contains cat images"
status="success"
/>
<Progress>
<Progress.Item title="Waiting to be started" status="notStarted" />
<Progress.Item title="Item in progress" status="inProgress" />
<Progress.Item title="Errorneous item" status="error" />
<Progress.Item title="Successful item" status="success" />
</Progress>

<Spacer />

<View style={styles.textContainer}>
<Typography variant="h3">Progress item tasks</Typography>
<Spacer amount="small" />
<Typography>
If some of the tasks fail, you can either retry uploading the task or copy the
error message.
</Typography>
<Typography>
The retry button can be shown on the specific task item that failed or at the
bottom of the Progress.Item.
Each progress item can expand its progress into multiple tasks. This allows for
a flexible way to display a progress in multiple levels of granularity to users.
When tasks are provided to the progress item, it automatically calculates the
correct summarized status without having to explicitly provide this.
</Typography>
<Spacer amount="small" />
<Typography>Progress with multiple tasks: </Typography>
</View>

<Spacer amount="small" />

<Progress title="Upload animal images">
<Progress>
<Progress.Item
title="Upload images of cats"
description="uploading cats with hats"
tasks={catTasks}
onRetryButtonPress={() => void handleRetryCatUpload()}
/>
<Progress.Item
title="Upload images of dogs throwing logs"
description="uploading dogs throwing logs"
tasks={dogTasks}
title="Performing tasks"
description="Here's to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the square holes. The ones who see things differently..."
tasks={[
{
title: "Task 1",
status: "success",
},
{
title: "Task 2",
status: "success",
},
{
title: "Task 3",
status: "error",
},
{
title: "Task with an icon",
status: "notStarted",
icon: "message-processing-outline",
},
]}
/>
</Progress>

<Spacer />
<View style={styles.simulatorContainer}>
<View style={styles.textContainer}>
<UploadSimulator
onUploadSuccess={() => void handleUploadSuccess()}
onUploadFailed={() => void handleUploadFailed()}
/>
</View>

<View style={styles.textContainer}>
<Typography>Progress with multiple progress items:</Typography>
</View>
<Spacer />

<View style={styles.textContainer}>
<Typography>
If some of the tasks fail, you can either retry uploading the task or copy
the error message.
</Typography>
<Typography>
The retry button can be shown on the specific task item that failed or at
the bottom of the Progress.Item.
</Typography>
<Spacer amount="small" />
<Typography>Progress with multiple tasks: </Typography>
</View>

<Spacer amount="small" />
<Spacer amount="small" />

<Progress>
<Progress.Item
title="Upload images of cats"
description={(completedTasks, totalTasks) =>
`Uploading cats with hats (${completedTasks}/${totalTasks})`
}
tasks={catTasks}
onRetryButtonPress={() => void handleRetryCatUpload()}
/>
<Progress.Item
title="Upload images of dogs throwing logs"
description={(completedTasks, totalTasks) =>
`Uploading dogs throwing logs (${completedTasks}/${totalTasks})`
}
tasks={dogTasks}
/>
</Progress>
</View>

<Progress title="Multiple progress items">
<Progress.Item title="Preparing cat hats" status="notStarted" />
<Progress.Item title="Training cats to wear hats" status="inProgress" />
<Progress.Item title="Cats refusing to wear hats" status="error" />
<Progress.Item
title="Uploading images of cats with hats"
description="uploading cats with hats"
status="success"
/>
</Progress>
<Spacer />
</ScrollView>
);
};

const themeStyles = EDSStyleSheet.create(theme => ({
simulatorContainer: {
borderColor: theme.colors.interactive.primary,
borderWidth: theme.geometry.border.focusedBorderWidth,
borderStyle: "dashed",
},
contentContainer: {
paddingVertical: theme.spacing.container.paddingVertical,
},
Expand Down
47 changes: 47 additions & 0 deletions packages/components/src/components/Progress/ActionButtonsRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react";
import { View, ViewProps } from "react-native";
import { useStyles } from "../../hooks/useStyles";
import { EDSStyleSheet } from "../../styling";
import { Button } from "../Button";
import { useProgressItemContext } from "./ProgressItem/ProgressItemContext";

type ActionButtonsRowProps = {
shouldShowRetryButton: boolean;
shouldShowCopyTextButton: boolean;
handleRetryButtonPress: () => void;
handleCopyTextButtonPress: () => void;
} & ViewProps;

export const ActionButtonsRow = ({
shouldShowRetryButton,
shouldShowCopyTextButton,
handleRetryButtonPress,
handleCopyTextButtonPress,
...viewProps
}: ActionButtonsRowProps) => {
const styles = useStyles(tokenStyles);
const { status } = useProgressItemContext();
return (
<View {...viewProps} style={[styles.container, viewProps.style]}>
{shouldShowCopyTextButton && status === "error" ? (
<Button
title="Copy to clipboard"
iconName="clipboard-outline"
variant="outlined"
onPress={handleCopyTextButtonPress}
/>
) : null}
{shouldShowRetryButton && status === "error" ? (
<Button iconName="restart" title="Retry" onPress={handleRetryButtonPress} />
) : null}
</View>
);
};

const tokenStyles = EDSStyleSheet.create(token => ({
container: {
flexDirection: "row",
alignItems: "center",
gap: token.spacing.spacer.small,
},
}));
32 changes: 23 additions & 9 deletions packages/components/src/components/Progress/Progress.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import React from "react";
import React, { Fragment } from "react";
import { View } from "react-native";
import { useStyles } from "../../hooks/useStyles";
import { useValidChildren } from "../../hooks/useValidChildren";
import { EDSStyleSheet } from "../../styling";
import { StrictChildrenReactNode } from "../../utils/types";
import { Cell } from "../Cell";
import { ProgressItemProps } from "./ProgressItem";
import { ProgressItemProps } from "./ProgressItem/ProgressItem";

export type ProgressProps = {
/**
* Optional title for the progress group. This title can be used to provide a heading or context for the set of progress items contained within.
*/
title?: string;
/**
* Children elements of the Progress component, which should be one or more `ProgressItem` components. The `Progress` component acts as a container that groups these items together.
* This allows for structured display of multiple progress-tracking elements, each representing a distinct task or process.
Expand All @@ -17,6 +16,21 @@ export type ProgressProps = {
| StrictChildrenReactNode<ProgressItemProps>[];
};

export const Progress = ({ title, children }: ProgressProps) => {
return <Cell.Group title={title}>{children}</Cell.Group>;
export const Progress = ({ children }: ProgressProps) => {
const styles = useStyles(tokenStyles);
const validChildren = useValidChildren(children);
return validChildren.map((child, index) => (
<Fragment key={`progress-item-${index}`}>
{child}
{index < validChildren.length - 1 && <View style={styles.divider} />}
</Fragment>
));
};

const tokenStyles = EDSStyleSheet.create(token => ({
divider: {
marginHorizontal: token.spacing.container.paddingHorizontal,
height: token.geometry.border.borderWidth,
backgroundColor: token.colors.border.medium,
},
}));

This file was deleted.

Loading
Loading