diff --git a/.changeset/chilly-taxis-buy.md b/.changeset/chilly-taxis-buy.md
new file mode 100644
index 0000000000..9261f14f29
--- /dev/null
+++ b/.changeset/chilly-taxis-buy.md
@@ -0,0 +1,6 @@
+---
+"@navikt/ds-react": patch
+"@navikt/ds-css": patch
+---
+
+Progressbar: Tweak API, examples, stories and css
diff --git a/@navikt/core/css/progress-bar.css b/@navikt/core/css/progress-bar.css
index 7273235303..3ff4c1ca6f 100644
--- a/@navikt/core/css/progress-bar.css
+++ b/@navikt/core/css/progress-bar.css
@@ -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 */
@@ -85,11 +84,14 @@
transform: translateX(-40%);
}
- 40%,
50% {
transform: translateX(-20%);
}
+ 75% {
+ transform: translateX(-10%);
+ }
+
100% {
transform: translateX(-10%);
}
diff --git a/@navikt/core/react/src/progress-bar/ProgressBar.stories.tsx b/@navikt/core/react/src/progress-bar/ProgressBar.stories.tsx
index d6298aebd1..e65326f80c 100644
--- a/@navikt/core/react/src/progress-bar/ProgressBar.stories.tsx
+++ b/@navikt/core/react/src/progress-bar/ProgressBar.stories.tsx
@@ -47,7 +47,6 @@ export const Default: StoryFn = (args) => {
size={args.size}
value={value}
aria-labelledby="progress-bar-label"
- /* duration={args.indeterminate ? 0 : undefined} */
/>
>
) : (
@@ -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) => {
@@ -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 (
<>
-
- Duration prop satt til 0 sek
-
-
{values.map((value) => (
- duration-prop satt til {value} sek
+ Simulert til å laste i opptil {value} sek.
+ {value === 0 &&
+ " Ved 0 sek vises indeterminate state umiddelbart."}
{
+ console.log("Ferdig!");
+ },
+ }}
/>
))}
diff --git a/@navikt/core/react/src/progress-bar/ProgressBar.tsx b/@navikt/core/react/src/progress-bar/ProgressBar.tsx
index 8c035d80da..5cdd27b8ce 100644
--- a/@navikt/core/react/src/progress-bar/ProgressBar.tsx
+++ b/@navikt/core/react/src/progress-bar/ProgressBar.tsx
@@ -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, "role"> {
@@ -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;
/**
@@ -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.
@@ -40,7 +47,7 @@ interface ProgressBarPropsBase
export type ProgressBarProps = ProgressBarPropsBase &
(
| {
- "aria-hidden": string;
+ "aria-hidden": true;
}
| {
"aria-labelledby": string;
@@ -61,7 +68,11 @@ export type ProgressBarProps = ProgressBarPropsBase &
*
* @example
* // For loading content with an approximate duration in sec.
- *
+ * console.log("Oops, this is taking more time than expected!")
+ * }}
+ * />
*
* @example
* // As a step indicator for forms, questionnaires, etc.
@@ -76,12 +87,24 @@ export const ProgressBar = forwardRef(
"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 (
(
`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"
@@ -105,14 +128,16 @@ export const ProgressBar = forwardRef
(
>
diff --git a/aksel.nav.no/website/pages/eksempler/progress-bar/indeterminate.tsx b/aksel.nav.no/website/pages/eksempler/progress-bar/indeterminate.tsx
index 19956d4a71..4204c487d3 100644
--- a/aksel.nav.no/website/pages/eksempler/progress-bar/indeterminate.tsx
+++ b/aksel.nav.no/website/pages/eksempler/progress-bar/indeterminate.tsx
@@ -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 (
-
-
Laster opp fil
- {/* TODO: Remove outcommented duration prop */}
-
+
+
Jobber med saken
+
{
+ console.log("Ferdig!");
+ setIsIndeterminate(true);
+ },
+ }}
+ aria-labelledby="indeterminate-working"
+ />
+ {isIndeterminate && Oi, dette tok lenger tid en forventet!
}
);
};
@@ -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.",
};
diff --git a/aksel.nav.no/website/pages/eksempler/progress-bar/interactive.tsx b/aksel.nav.no/website/pages/eksempler/progress-bar/interactive.tsx
index af8e220229..5e693963a6 100644
--- a/aksel.nav.no/website/pages/eksempler/progress-bar/interactive.tsx
+++ b/aksel.nav.no/website/pages/eksempler/progress-bar/interactive.tsx
@@ -65,4 +65,5 @@ export const Demo = {
export const args = {
index: 2,
+ desc: "ProgressBar kan brukes til å vise hvor i en flyt brukeren er",
};
diff --git a/aksel.nav.no/website/pages/eksempler/progress-bar/loadingBar.tsx b/aksel.nav.no/website/pages/eksempler/progress-bar/loadingBar.tsx
deleted file mode 100644
index cb423d3516..0000000000
--- a/aksel.nav.no/website/pages/eksempler/progress-bar/loadingBar.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import React from "react";
-import { ProgressBar } from "@navikt/ds-react";
-import { withDsExample } from "@/web/examples/withDsExample";
-
-const Example = () => {
- const [value, setValue] = React.useState(3);
-
- // This useEffect is used to simulate loading
- React.useEffect(() => {
- const setRandomInterval = (callback: () => void) => {
- const interval = Math.random() * 4000 + 500;
- return setTimeout(() => {
- callback();
- setRandomInterval(callback);
- }, interval);
- };
- const intervalId = setRandomInterval(() => {
- setValue((oldValue) => {
- if (oldValue === 100) return 3;
- const increment = Math.random() * 25 + 5;
- return oldValue + increment > 100 ? 100 : oldValue + increment;
- });
- });
- return () => clearInterval(intervalId);
- }, []);
-
- return (
-
-
Simulated loading bar
-
-
- );
-};
-
-// EXAMPLES DO NOT INCLUDE CONTENT BELOW THIS LINE
-export default withDsExample(Example);
-
-/* Storybook story */
-export const Demo = {
- render: Example,
-};
-
-export const args = {
- index: 1,
-};
diff --git a/aksel.nav.no/website/pages/eksempler/progress-bar/sizes.tsx b/aksel.nav.no/website/pages/eksempler/progress-bar/sizes.tsx
index f090a356f8..f62458649a 100644
--- a/aksel.nav.no/website/pages/eksempler/progress-bar/sizes.tsx
+++ b/aksel.nav.no/website/pages/eksempler/progress-bar/sizes.tsx
@@ -4,7 +4,7 @@ import { withDsExample } from "@/web/examples/withDsExample";
const Example = () => {
return (
- Fremdrift i søknaden (liten versjon)
+ Fremdrift (liten versjon)
{
aria-labelledby="progress-bar-label-small"
/>
-
- Fremdrift i søknaden (medium versjon)
-
+ Fremdrift (medium versjon)
{
aria-labelledby="progress-bar-label-medium"
/>
- Fremdrift i søknaden (stor versjon)
+ Fremdrift (stor versjon)