-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Progress Bar Component #99
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
54694b3
initial incentive bar
zwkohn 39256e9
remove console log
zwkohn 701587d
use computedWidth of container
zwkohn 2fd549d
renaming; more general
zwkohn b953e02
allow stepIcon to be any ReactElement
zwkohn 7efe1cd
remove step lines
zwkohn ecd9297
remove left/right margin; adjust step percent
zwkohn e655b7f
Merge remote-tracking branch 'origin/main' into zkohn/incentives
zwkohn 7b82f4d
some PR cleanup
zwkohn fe5846a
fix export
zwkohn b285a41
clean up doc
zwkohn cd672b0
fix exports
zwkohn a08c901
add borderColor; fix margintop calc
zwkohn e36ea9b
fixing default margin
zwkohn 7240ae7
truncate the percentages; add sb css
zwkohn 512ff86
cleanup exports; add padding to Template
zwkohn dbe3a4f
add defaultMargin to args
zwkohn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
.mdhui-progress-bar { | ||
display: block; | ||
width: 100%; | ||
position: relative; | ||
--icon_size: 24px; | ||
--icon_border_width: 2px; | ||
} | ||
|
||
.mdhui-progress-bar.mdhui-progress-bar-default-margin { | ||
margin: 16px; | ||
width:calc(100% - 32px) | ||
} | ||
|
||
.mdhui-progress-bar .mdhui-progress-bar-background { | ||
border-radius: 500px; | ||
border-width: var(--icon_border_width) ; | ||
border-style: none; | ||
background: #fff; | ||
overflow: hidden; | ||
width: 100%; | ||
position: relative; | ||
height:calc( var(--icon_size) + 4px); | ||
z-index:1; | ||
} | ||
|
||
.mdhui-progress-bar .mdhui-progress-bar-background .mdhui-progress-bar-fill { | ||
position: absolute; | ||
min-height: 1px; | ||
height: calc( var(--icon_size) + 4px); | ||
top:0; | ||
border-radius: var(--icon_size); | ||
z-index:1 | ||
} | ||
|
||
.mdhui-progress-bar .mdhui-progress-steps { | ||
top:0; | ||
width: 100%; | ||
position: absolute; | ||
z-index: 2; | ||
display:inline-block; | ||
} | ||
|
||
.mdhui-progress-bar .step-icon { | ||
position: absolute; | ||
transform: translate(-100%, 0); | ||
} | ||
|
||
.mdhui-progress-bar .step-icon * { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
} |
111 changes: 111 additions & 0 deletions
111
src/components/presentational/ProgressBar/ProgressBar.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import React from "react"; | ||
import ProgressBar, { ProgressBarProps } from "./ProgressBar"; | ||
import { Meta, StoryFn } from "@storybook/react"; | ||
import Layout from "../Layout"; | ||
import { faStar } from "@fortawesome/free-regular-svg-icons"; | ||
import { faStar as faSolidStar } from "@fortawesome/free-solid-svg-icons"; | ||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||
import ProgressBarStep from "./ProgressBarStep"; | ||
|
||
export default { | ||
title: "Presentational/ProgressBar", | ||
component: ProgressBar, | ||
parameters: { | ||
layout: 'auto', | ||
}, | ||
argTypes: { | ||
backgroundColor: { control: 'object', description: "The background color of the progress bar" }, | ||
fillColor: { control: 'object', description: "The fill color of the progress bar" }, | ||
fillPercent: { control: 'number', description: "The percent of the progress bar that is filled" }, | ||
steps: { control: 'object', description: "An array of steps to display on the progress bar. A step specifies the position on the progress bar as a percent and a React element to display at that position." }, | ||
}, | ||
args: { | ||
defaultMargin: true | ||
} | ||
|
||
} as Meta<typeof ProgressBar>; | ||
|
||
const Template: StoryFn<typeof ProgressBar> = (args: ProgressBarProps) => <Layout colorScheme="auto"><div style={{padding: "35px 0"}}><ProgressBar {...args}/></div></Layout>; | ||
|
||
export const Default = Template.bind({}); | ||
Default.args = { | ||
fillPercent: 35, | ||
} | ||
|
||
export const GradientFill75TargetStep = Template.bind({}); | ||
GradientFill75TargetStep.args = { | ||
fillPercent: 75, | ||
backgroundColor: { lightMode: "#d3d3d3", darkMode: "#c2c2c2" }, | ||
fillColor: "linear-gradient(90deg, #6cb144, #adc247)", | ||
steps: [{ | ||
percent: 100, | ||
icon: | ||
<ProgressBarStep borderColor="rgba(148, 148, 148, 1)" backgroundColor="rgba(148, 148, 148, 1)" height="24px"> | ||
<FontAwesomeIcon icon={faStar} size={"1x"} style={{ color: "#fcfcfc", marginTop: "-3px" }} /> | ||
</ProgressBarStep> | ||
}], | ||
|
||
} as ProgressBarProps; | ||
|
||
export const GradientFill100TargetStep = Template.bind({}); | ||
GradientFill100TargetStep.args = { | ||
fillPercent: 100, | ||
fillColor: "linear-gradient(90deg, #6cb144, #adc247)", | ||
steps: [{ | ||
percent: 100, | ||
icon: | ||
<ProgressBarStep borderColor="gold" backgroundColor="#EA6B54" height="24px"> | ||
<FontAwesomeIcon icon={faStar} size={"1x"} style={{ color: "gold", marginTop: "-3px" }} /> | ||
</ProgressBarStep> | ||
}], | ||
} as ProgressBarProps; | ||
|
||
export const GradientFillIconSteps = Template.bind({}); | ||
GradientFillIconSteps.args = { | ||
fillPercent: 50, | ||
backgroundColor: "#d3d3d3", | ||
fillColor: "linear-gradient(270deg, #F0CA68 0%, #E5917F 100%)", | ||
steps: [...Array(4)].map((_e, i) => { | ||
let value = (i + 1) * 25; | ||
let icon = (value <= 50) ? | ||
<ProgressBarStep borderColor="gold" backgroundColor="#EA6B54" height="16px"> | ||
<FontAwesomeIcon icon={faSolidStar} size={"1x"} style={{ color: "white", marginTop: "-3px" }} /> | ||
</ProgressBarStep> : | ||
<ProgressBarStep borderColor="rgba(148, 148, 148, 1)" backgroundColor="rgba(148, 148, 148, 1)" height="16px"> | ||
<FontAwesomeIcon icon={faSolidStar} size={"1x"} style={{ color: "white", marginTop: "-3px" }} /> | ||
</ProgressBarStep> | ||
return { | ||
percent: Math.trunc(value), | ||
icon: icon | ||
} | ||
}) | ||
} as ProgressBarProps; | ||
|
||
export const LabelSteps = Template.bind({}); | ||
LabelSteps.args = { | ||
fillPercent: 100 * 75 / 175, | ||
fillColor: "rgb(34, 115, 209, 0.5)", | ||
backgroundColor: { lightMode: "#d3d3d3", darkMode: "#c2c2c2" }, | ||
steps: [...Array(7)].map((_e, i) => { | ||
let amount = (i + 1) * 25; | ||
let icon = (amount == 75) ? | ||
<ProgressBarStep borderColor="white" backgroundColor="rgb(34, 115, 209)" height="14px"> | ||
<span style={{ fontSize: "0.8em" }}>75</span> | ||
</ProgressBarStep> : | ||
((amount < 75) ? | ||
<ProgressBarStep borderColor="white" backgroundColor="rgb(34, 115, 209)" height="14px"> | ||
<FontAwesomeIcon icon={faSolidStar} size={"1x"} style={{ color: "white", marginTop: "-3px" }} /> | ||
</ProgressBarStep> : | ||
<ProgressBarStep borderColor="rgba(148, 148, 148, 1)" backgroundColor="rgba(148, 148, 148, 1)" height="14px"> | ||
<FontAwesomeIcon icon={faStar} size={"1x"} style={{ color: "rgb(34, 115, 209)", marginTop: "-3px" }} /> | ||
</ProgressBarStep> | ||
); | ||
return { | ||
percent: Math.trunc(100 * amount / 175), | ||
icon: icon | ||
} | ||
}) | ||
} as ProgressBarProps | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { ColorDefinition, resolveColor } from "../../../helpers/colors"; | ||
import "./ProgressBar.css"; | ||
import React, { ReactElement, useContext, useEffect } from "react"; | ||
import { LayoutContext } from '../Layout'; | ||
|
||
export interface ProgressBarProps { | ||
backgroundColor?: ColorDefinition; | ||
borderColor?: ColorDefinition; | ||
fillColor?: ColorDefinition; | ||
fillPercent: number; | ||
chrisnowak marked this conversation as resolved.
Show resolved
Hide resolved
|
||
steps?: | ||
{ | ||
percent: number; | ||
icon: ReactElement; | ||
}[] | ||
, | ||
innerRef?: React.Ref<HTMLDivElement>; | ||
defaultMargin?: boolean | ||
} | ||
|
||
ProgressBar.defaultProps = { | ||
chrisnowak marked this conversation as resolved.
Show resolved
Hide resolved
|
||
backgroundColor: "var(--mdhui-background-color-0)", | ||
fillColor: "var(--mdhui-color-primary)", | ||
fillPercent: 0 | ||
} | ||
|
||
export default function ProgressBar(props: ProgressBarProps) { | ||
let layoutContext = useContext(LayoutContext); | ||
let classes = ["mdhui-progress-bar"]; | ||
if (props.defaultMargin) { | ||
classes.push("mdhui-progress-bar-default-margin"); | ||
} | ||
|
||
return ( | ||
<div className={classes.join(" ")} ref={props.innerRef}> | ||
<div className="mdhui-progress-bar-background" style={{ background: resolveColor(layoutContext?.colorScheme, props.backgroundColor) }}> | ||
<div className="mdhui-progress-bar-fill" style={{ width: Math.trunc(props.fillPercent) + "%", background: resolveColor(layoutContext?.colorScheme, props.fillColor) }} /> | ||
</div> | ||
<div className="mdhui-progress-steps"> | ||
{props.steps && | ||
<> | ||
{props.steps.map((step, i) => | ||
<div key={`${i}-step`} className="step-icon" style={{ left: Math.trunc(step.percent) + "%" }}> | ||
{step.icon} | ||
</div> | ||
)} | ||
</> | ||
} | ||
</div> | ||
</div> | ||
); | ||
} |
20 changes: 20 additions & 0 deletions
20
src/components/presentational/ProgressBar/ProgressBarStep.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import React, { useContext } from "react"; | ||
import { ColorDefinition, resolveColor } from "../../../helpers/colors"; | ||
import { LayoutContext } from "../Layout"; | ||
|
||
export interface ProgressBarStepProps { | ||
borderColor?: ColorDefinition; | ||
backgroundColor?: ColorDefinition; | ||
children?: React.ReactNode; | ||
height: string; | ||
} | ||
|
||
export default function ProgressBarStep(props: ProgressBarStepProps) { | ||
let layoutContext = useContext(LayoutContext); | ||
let calcTopMargin = "calc( var(--icon_size) / 2 - "+props.height+" / 2 - 4px)"; | ||
return ( | ||
<span style={{ border: "2px solid", borderColor: resolveColor(layoutContext?.colorScheme,props.borderColor), borderRadius: props.height, height: props.height, width: props.height, marginTop: calcTopMargin, backgroundColor: resolveColor(layoutContext?.colorScheme, props.backgroundColor), padding: "4px 4px" }}> | ||
{props.children} | ||
</span> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { default } from './ProgressBar' | ||
export { default as ProgressBarStep } from './ProgressBarStep' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh...did you just add a border to this? I didn't think there was a border before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But the border width is added to the width so it ends up overflowing 100% width
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would probably drop the border because it makes it look a bit awkward when stuff overlaps it:
![Screenshot 2023-11-30 at 2 04 36 PM](https://private-user-images.githubusercontent.com/1643171/287041809-67594572-ca71-4fa7-aeaf-10a3a313fd35.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzg5NzI5OTUsIm5iZiI6MTczODk3MjY5NSwicGF0aCI6Ii8xNjQzMTcxLzI4NzA0MTgwOS02NzU5NDU3Mi1jYTcxLTRmYTctYWVhZi0xMGEzYTMxM2ZkMzUucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDIwNyUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTAyMDdUMjM1ODE1WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9NDNkY2MzZWY0Nzg3NmU1MjkxZWViMTE5MzVmOWMyZWZlOWZkNTBiZGZhOGE2ZjU1OGM4Mjc3OGJkYmI2YmUwNiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.SAAtqZR2GWYQbQXAndXQ7znG_a7U-zNcXcp94UrINAU)