Skip to content

Commit

Permalink
Progressbar tweaks (etter docs-møtet) (#2892)
Browse files Browse the repository at this point in the history
Co-authored-by: Julian Nymark <[email protected]>
Co-authored-by: Halvor Haugan <[email protected]>
  • Loading branch information
3 people authored May 7, 2024
1 parent 4797cca commit 0c06fa1
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 101 deletions.
6 changes: 6 additions & 0 deletions .changeset/chilly-taxis-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@navikt/ds-react": patch
"@navikt/ds-css": patch
---

Progressbar: Tweak API, examples, stories and css
12 changes: 7 additions & 5 deletions @navikt/core/css/progress-bar.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,14 @@
}

.navds-progress-bar__foreground--indeterminate {
--__ac-progress-bar-duration: initial;
--__ac-progress-bar-delay: initial;
--__ac-progress-bar-simulated: initial;

animation-name: navds-progress-bar-indeterminate-grow, navds-progress-bar-indeterminate;
animation-timing-function: ease-in-out, ease-in-out;
animation-duration: var(--__ac-progress-bar-duration), 2500ms;
animation-duration: var(--__ac-progress-bar-simulated), 2500ms;
animation-fill-mode: forwards, none;
animation-iteration-count: 1, infinite;
animation-delay: 0s, calc((var(--__ac-progress-bar-duration) + var(--__ac-progress-bar-delay)));
animation-delay: 0s, var(--__ac-progress-bar-simulated);
}

/* navds-progress-bar-indeterminate wave animation */
Expand Down Expand Up @@ -85,11 +84,14 @@
transform: translateX(-40%);
}

40%,
50% {
transform: translateX(-20%);
}

75% {
transform: translateX(-10%);
}

100% {
transform: translateX(-10%);
}
Expand Down
31 changes: 10 additions & 21 deletions @navikt/core/react/src/progress-bar/ProgressBar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export const Default: StoryFn = (args) => {
size={args.size}
value={value}
aria-labelledby="progress-bar-label"
/* duration={args.indeterminate ? 0 : undefined} */
/>
</>
) : (
Expand All @@ -58,16 +57,12 @@ export const Default: StoryFn = (args) => {
};
Default.args = {
size: "medium",
indeterminate: false,
};
Default.argTypes = {
size: {
options: ["large", "medium", "small"],
control: { type: "radio" },
},
indeterminate: {
control: { type: "boolean" },
},
};

export const Sizes: StoryFn = (args) => {
Expand Down Expand Up @@ -103,35 +98,29 @@ Sizes.args = {
valueMax: 12,
};

/**
* Duration is temp disabled due to potential API-updates
*/
export const IndeterminateState: Story = {
render: () => {
const values = [2, 5, 10, 20];
const values = [0, 5, 10, 20];
return (
<>
<p id="progress-bar-label-immediate-indeterminate">
Duration prop satt til 0 sek
</p>
<ProgressBar
valueMax={100}
/* duration={0} */
size="medium"
value={50}
aria-labelledby="progress-bar-label-immediate-indeterminate"
/>
{values.map((value) => (
<div key={value}>
<p id={`progress-bar-label-${value}`}>
duration-prop satt til {value} sek
Simulert til å laste i opptil {value} sek.
{value === 0 &&
" Ved 0 sek vises indeterminate state umiddelbart."}
</p>
<ProgressBar
valueMax={100}
/* duration={value} */
size="medium"
value={value}
aria-labelledby={`progress-bar-label-${value}`}
simulated={{
seconds: value,
onTimeout: () => {
console.log("Ferdig!");
},
}}
/>
</div>
))}
Expand Down
65 changes: 45 additions & 20 deletions @navikt/core/react/src/progress-bar/ProgressBar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import cl from "clsx";
import React, { HTMLAttributes, forwardRef } from "react";
import React, { HTMLAttributes, forwardRef, useRef } from "react";

interface ProgressBarPropsBase
extends Omit<HTMLAttributes<HTMLDivElement>, "role"> {
Expand All @@ -9,7 +9,7 @@ interface ProgressBarPropsBase
*/
size?: "large" | "medium" | "small";
/**
* Current progress. When duration is set, value is ignored.
* Current progress. If set, the `simulated` prop overrides `value`.
*/
value?: number;
/**
Expand All @@ -18,13 +18,20 @@ interface ProgressBarPropsBase
*/
valueMax?: number;
/**
* Expected task duration in seconds.
* ProgressBar grows with a preset animation for {duration} seconds.
* After a 4 sec delay, it then shows an indeterminate animation.
* A duration of 0 will show an indeterminate animation immediately.
* Temporary removed to avoid conflicts when updating API
* Visually simulates loading.
* ProgressBar grows with a preset animation for set number of seconds,
* then shows an indeterminate animation on timeout.
*/
//duration?: number;
simulated?: {
/**
* Duration in seconds.
*/
seconds: number;
/**
* Callback function when progress is indeterminate.
*/
onTimeout: () => void;
};
/**
* String ID of the element that labels the progress bar.
* Not needed if `aria-label` is used.
Expand All @@ -40,7 +47,7 @@ interface ProgressBarPropsBase
export type ProgressBarProps = ProgressBarPropsBase &
(
| {
"aria-hidden": string;
"aria-hidden": true;
}
| {
"aria-labelledby": string;
Expand All @@ -61,7 +68,11 @@ export type ProgressBarProps = ProgressBarPropsBase &
*
* @example
* // For loading content with an approximate duration in sec.
* <ProgressBar duration={30} />
* <ProgressBar simulated={{
* seconds: 30,
* onTimeout: () => console.log("Oops, this is taking more time than expected!")
* }}
* />
*
* @example
* // As a step indicator for forms, questionnaires, etc.
Expand All @@ -76,12 +87,24 @@ export const ProgressBar = forwardRef<HTMLDivElement, ProgressBarProps>(
"aria-labelledby": ariaLabelledBy,
"aria-label": ariaLabel,
className,
simulated,
...rest
},
ref,
) => {
const translate = 100 - (Math.round(value) / valueMax) * 100;
const duration = undefined;
const onTimeoutRef = useRef<() => void>();
onTimeoutRef.current = simulated?.onTimeout;

React.useEffect(() => {
if (simulated?.seconds && onTimeoutRef.current) {
const timeout = setTimeout(
onTimeoutRef.current,
simulated.seconds * 1000,
);
return () => clearTimeout(timeout);
}
}, [simulated?.seconds]);

return (
<div
Expand All @@ -91,11 +114,11 @@ export const ProgressBar = forwardRef<HTMLDivElement, ProgressBarProps>(
`navds-progress-bar--${size}`,
className,
)}
aria-valuemax={duration ? 0 : Math.round(valueMax)}
aria-valuenow={duration ? 0 : Math.round(value)}
aria-valuemax={simulated?.seconds ? 0 : Math.round(valueMax)}
aria-valuenow={simulated?.seconds ? 0 : Math.round(value)}
aria-valuetext={
duration
? "Fremdrift kan ikke beregnes"
simulated?.seconds
? `Fremdrift kan ikke beregnes, antatt tid er: ${simulated?.seconds} sekunder`
: `${Math.round(value)} av ${Math.round(valueMax)}`
}
role="progressbar"
Expand All @@ -105,14 +128,16 @@ export const ProgressBar = forwardRef<HTMLDivElement, ProgressBarProps>(
>
<div
className={cl("navds-progress-bar__foreground", {
"navds-progress-bar__foreground--indeterminate":
Number.isInteger(duration),
"navds-progress-bar__foreground--indeterminate": Number.isInteger(
simulated?.seconds,
),
})}
style={{
"--__ac-progress-bar-duration": Number.isInteger(duration)
? `${duration}s`
"--__ac-progress-bar-simulated": Number.isInteger(
simulated?.seconds,
)
? `${simulated?.seconds}s`
: undefined,
"--__ac-progress-bar-delay": `${duration === 0 ? 0 : 4}s`,
"--__ac-progress-bar-translate": `-${translate}%`,
}}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import React from "react";
import { ProgressBar } from "@navikt/ds-react";
import { withDsExample } from "@/web/examples/withDsExample";

const Example = () => {
const [isIndeterminate, setIsIndeterminate] = React.useState(false);
return (
<div>
<p id="indeterminate">Laster opp fil</p>
{/* TODO: Remove outcommented duration prop */}
<ProgressBar /* duration={6} */ aria-labelledby="indeterminate" />
<div style={{ width: "300px" }}>
<p id="indeterminate-working">Jobber med saken</p>
<ProgressBar
simulated={{
seconds: 6,
onTimeout: () => {
console.log("Ferdig!");
setIsIndeterminate(true);
},
}}
aria-labelledby="indeterminate-working"
/>
{isIndeterminate && <p>Oi, dette tok lenger tid en forventet!</p>}
</div>
);
};
Expand All @@ -21,5 +32,5 @@ export const Demo = {

export const args = {
index: 3,
desc: "Med duration-propen kan man legge inn et anslag i sekunder, så simulerer komponenten progresjon.",
desc: "Med simulated-propen kan man legge inn et anslag i sekunder, så simulerer komponenten progresjon.",
};
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,5 @@ export const Demo = {

export const args = {
index: 2,
desc: "ProgressBar kan brukes til å vise hvor i en flyt brukeren er",
};
45 changes: 0 additions & 45 deletions aksel.nav.no/website/pages/eksempler/progress-bar/loadingBar.tsx

This file was deleted.

8 changes: 3 additions & 5 deletions aksel.nav.no/website/pages/eksempler/progress-bar/sizes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,23 @@ import { withDsExample } from "@/web/examples/withDsExample";
const Example = () => {
return (
<VStack gap="4">
<p id="progress-bar-label-small">Fremdrift i søknaden (liten versjon)</p>
<p id="progress-bar-label-small">Fremdrift (liten versjon)</p>
<ProgressBar
value={1}
valueMax={12}
size="small"
aria-labelledby="progress-bar-label-small"
/>

<p id="progress-bar-label-medium">
Fremdrift i søknaden (medium versjon)
</p>
<p id="progress-bar-label-medium">Fremdrift (medium versjon)</p>
<ProgressBar
value={6}
valueMax={12}
size="medium"
aria-labelledby="progress-bar-label-medium"
/>

<p id="progress-bar-label-large">Fremdrift i søknaden (stor versjon)</p>
<p id="progress-bar-label-large">Fremdrift (stor versjon)</p>
<ProgressBar
value={11}
valueMax={12}
Expand Down

0 comments on commit 0c06fa1

Please sign in to comment.