Skip to content

Commit

Permalink
Aksel v7 (#3139)
Browse files Browse the repository at this point in the history
* Tooltip labeling (#3094)

* feat: Better labeling of Tooltip

* feat: Better keyshortcuts for screenreaders in Tooltip

* memo: Updated story

* bug: Better error logging for example-parsing

* refactor: describeChild -> describesChild

* fire: Removed extra story

* bug: removed extra tabIndex

* memo: Update Tooltip demo description

* Update aksel.nav.no/website/pages/eksempler/tooltip/labeling.tsx

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* refactor: Updated defaultValue for describesChild

* bug: removed Tooltip prop from ToggleGroup

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* Tailwind: Fixed 'screen' -> 'screens' bug to properly adopt breakpoints. (#3119)

* 💥 Screen -> Screens in tailwind-config

* refactor: Adopt updated screens-config in Aksel.nav.no project

* Icons: Removed old and renamed icons (#3120)

* 💥 Removed renamed icons

* ErrorSummary: Add fallback for heading + better focus handling (#3140)

Co-authored-by: Ken <ken.aleksander@gmail.com>
Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* feat: Added composeEventHandlers to onFocus in ErrorSummary

* memo: Removed inaccurate description for tooltip demo

* feat: Omitted tabIndex from ErrorSummary

---------

Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
Co-authored-by: Ken <ken.aleksander@gmail.com>
  • Loading branch information
3 people committed Sep 13, 2024
1 parent 46a14b1 commit 1c11a6a
Show file tree
Hide file tree
Showing 38 changed files with 230 additions and 202 deletions.
5 changes: 5 additions & 0 deletions .changeset/great-crews-hang.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@navikt/ds-react": major
---

ErrorSummary: Added fallback text for `heading`.
5 changes: 5 additions & 0 deletions .changeset/little-files-cough.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@navikt/ds-react": major
---

Tooltip: :boom: Updated labeling of items inside Tooltip. [See migration guide for how to update](https://aksel.nav.no/grunnleggende/kode/migrering#3b5cf05fd100).
5 changes: 5 additions & 0 deletions .changeset/small-apples-pretend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@navikt/aksel-icons": major
---

Icons: Removed renamed icons. [See migration guide for changes](https://aksel.nav.no/grunnleggende/kode/migrering#194b60833d9e).
5 changes: 5 additions & 0 deletions .changeset/stupid-pianos-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@navikt/ds-tailwind": major
---

Tailwind: Extended 'screens'-config in theme to match Aksel breakpoints. Tailwind and Primitives can now be used side by side with matching dynamic breakpoints. [See migration guide for potential issues when adopting](https://aksel.nav.no/grunnleggende/kode/migrering#3a2340f6f69b).
6 changes: 6 additions & 0 deletions .changeset/thick-roses-sneeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@navikt/ds-react": patch
"@navikt/ds-css": patch
---

ErrorSummary: Focus heading instead of container for improved experience with screen reader.
3 changes: 0 additions & 3 deletions @navikt/aksel-icons/icons/BeaconSignals.svg

This file was deleted.

19 changes: 0 additions & 19 deletions @navikt/aksel-icons/icons/BeaconSignals.yml

This file was deleted.

3 changes: 0 additions & 3 deletions @navikt/aksel-icons/icons/BeaconSignalsFill.svg

This file was deleted.

19 changes: 0 additions & 19 deletions @navikt/aksel-icons/icons/BeaconSignalsFill.yml

This file was deleted.

3 changes: 0 additions & 3 deletions @navikt/aksel-icons/icons/Buldings2.svg

This file was deleted.

8 changes: 0 additions & 8 deletions @navikt/aksel-icons/icons/Buldings2.yml

This file was deleted.

3 changes: 0 additions & 3 deletions @navikt/aksel-icons/icons/Buldings2Fill.svg

This file was deleted.

8 changes: 0 additions & 8 deletions @navikt/aksel-icons/icons/Buldings2Fill.yml

This file was deleted.

3 changes: 0 additions & 3 deletions @navikt/aksel-icons/icons/Buldings3.svg

This file was deleted.

8 changes: 0 additions & 8 deletions @navikt/aksel-icons/icons/Buldings3.yml

This file was deleted.

3 changes: 0 additions & 3 deletions @navikt/aksel-icons/icons/Buldings3Fill.svg

This file was deleted.

8 changes: 0 additions & 8 deletions @navikt/aksel-icons/icons/Buldings3Fill.yml

This file was deleted.

8 changes: 8 additions & 0 deletions @navikt/core/css/form/error-summary.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
padding: var(--a-spacing-3);
}

.navds-error-summary__heading {
scroll-margin-top: var(--a-spacing-6);
}

.navds-error-summary--small .navds-error-summary__heading {
scroll-margin-top: var(--a-spacing-4);
}

.navds-error-summary__heading:focus {
outline: none;
}
Expand Down
36 changes: 23 additions & 13 deletions @navikt/core/react/src/form/error-summary/ErrorSummary.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import cl from "clsx";
import React, { HTMLAttributes, forwardRef, isValidElement } from "react";
import React, { HTMLAttributes, forwardRef, useRef } from "react";
import { BodyShort, Heading } from "../../typography";
import { useId } from "../../util/hooks";
import ErrorSummaryItem, { ErrorSummaryItemType } from "./ErrorSummaryItem";
import { composeEventHandlers } from "../../util/composeEventHandlers";
import { useId, useMergeRefs } from "../../util/hooks";
import ErrorSummaryItem from "./ErrorSummaryItem";

export interface ErrorSummaryProps extends HTMLAttributes<HTMLDivElement> {
export interface ErrorSummaryProps
extends Omit<HTMLAttributes<HTMLDivElement>, "tabIndex"> {
/**
* Collection of `ErrorSummary.Item`.
*/
Expand All @@ -16,6 +18,7 @@ export interface ErrorSummaryProps extends HTMLAttributes<HTMLDivElement> {
size?: "medium" | "small";
/**
* Heading above links.
* @default "Du må rette disse feilene før du kan fortsette:"
*/
heading?: React.ReactNode;
/**
Expand All @@ -41,7 +44,7 @@ interface ErrorSummaryComponent
* </ErrorSummary.Item>
* ```
*/
Item: ErrorSummaryItemType;
Item: typeof ErrorSummaryItem;
}

/**
Expand Down Expand Up @@ -69,16 +72,21 @@ export const ErrorSummary = forwardRef<HTMLDivElement, ErrorSummaryProps>(
className,
size = "medium",
headingTag = "h2",
heading,
heading = "Du må rette disse feilene før du kan fortsette:",
...rest
},
ref,
) => {
const headingId = useId();

const sectionRef = useRef<HTMLDivElement>(null);
const headingRef = useRef<HTMLHeadingElement>(null);

const mergedRef = useMergeRefs(ref, sectionRef);

return (
<section
ref={ref}
ref={mergedRef}
{...rest}
className={cl(
className,
Expand All @@ -89,22 +97,24 @@ export const ErrorSummary = forwardRef<HTMLDivElement, ErrorSummaryProps>(
aria-live="polite"
aria-relevant="all"
aria-labelledby={headingId}
onFocus={composeEventHandlers(rest.onFocus, (event) => {
if (event.target === sectionRef.current) {
headingRef?.current?.focus();
}
})}
>
<Heading
className="navds-error-summary__heading"
as={headingTag}
size="small"
id={headingId}
ref={headingRef}
tabIndex={-1}
>
{heading}
</Heading>
<BodyShort as="ul" size={size} className="navds-error-summary__list">
{React.Children.map(children, (child) => {
if (!isValidElement(child)) {
return null;
}
return <li key={child.toString()}>{child}</li>;
})}
{children}
</BodyShort>
</section>
);
Expand Down
18 changes: 10 additions & 8 deletions @navikt/core/react/src/form/error-summary/ErrorSummaryItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,23 @@ export interface ErrorSummaryItemProps
href?: string;
}

export type ErrorSummaryItemType = OverridableComponent<
type ErrorSummaryItemType = OverridableComponent<
ErrorSummaryItemProps,
HTMLAnchorElement
>;

export const ErrorSummaryItem: ErrorSummaryItemType = forwardRef(
({ children, as: Component = "a", className, ...rest }, ref) => {
return (
<Component
{...rest}
ref={ref}
className={cl(className, "navds-error-summary__item", "navds-link")}
>
{children}
</Component>
<li>
<Component
{...rest}
ref={ref}
className={cl(className, "navds-error-summary__item", "navds-link")}
>
{children}
</Component>
</li>
);
},
);
Expand Down
97 changes: 76 additions & 21 deletions @navikt/core/react/src/form/error-summary/error-summary.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
import { Meta, StoryObj } from "@storybook/react";
import React from "react";
import { expect, userEvent, within } from "@storybook/test";
import React, { useRef } from "react";
import { VStack } from "../../layout/stack";
import { ErrorSummary } from "./ErrorSummary";

export default {
title: "ds-react/Errorsummary",
title: "ds-react/ErrorSummary",
component: ErrorSummary,
argTypes: {
headingTag: {
control: {
type: "text",
},
},
size: {
control: {
type: "radio",
},
options: ["medium", "small"],
},
},
parameters: {
chromatic: { disable: true },
},
Expand All @@ -27,18 +15,32 @@ export default {
type Story = StoryObj<typeof ErrorSummary>;

export const Default: Story = {
render: (props) => (
<ErrorSummary
heading="Feiloppsummering komponent"
headingTag={props.headingTag || "h2"}
size={props.size ?? undefined}
>
render: ({ headingTag, ...rest }) => (
<ErrorSummary headingTag={headingTag || undefined} {...rest}>
<ErrorSummary.Item href="#1">Checkbox må fylles ut</ErrorSummary.Item>
<ErrorSummary.Item href="#2">
Tekstfeltet må ha en godkjent e-mail
</ErrorSummary.Item>
</ErrorSummary>
),
argTypes: {
heading: {
control: {
type: "text",
},
},
headingTag: {
control: {
type: "text",
},
},
size: {
control: {
type: "radio",
},
options: ["medium", "small"],
},
},
};

export const Small: Story = {
Expand All @@ -52,6 +54,59 @@ export const Small: Story = {
),
};

export const A11yDemo: Story = {
name: "A11y Demo",
render: () => {
const ref = useRef<HTMLHeadingElement>(null);
return (
<div>
<button
onClick={() => {
ref.current?.focus();
}}
>
Fokuser ErrorSummary
</button>
<ErrorSummary heading="Feiloppsummering tittel" ref={ref}>
<ErrorSummary.Item href="#1">Checkbox må fylles ut</ErrorSummary.Item>
<ErrorSummary.Item href="#2">
Tekstfeltet må ha en godkjent e-mail
</ErrorSummary.Item>
</ErrorSummary>
</div>
);
},
};

export const FocusDemo: Story = {
render: () => {
const ref = useRef<HTMLHeadingElement>(null);
return (
<div>
<button onClick={() => ref.current?.focus()}>Focus summary</button>
<ErrorSummary heading="Feiloppsummering tittel" ref={ref}>
<ErrorSummary.Item href="#1">Checkbox må fylles ut</ErrorSummary.Item>
<ErrorSummary.Item href="#2">
Tekstfeltet må ha en godkjent e-mail
</ErrorSummary.Item>
</ErrorSummary>
</div>
);
},
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);

const button = canvas.getByText("Focus summary");
const heading = canvas.getByText("Feiloppsummering tittel");

await step("click button", async () => {
await userEvent.click(button);
});

expect(heading).toHaveFocus();
},
};

export const Chromatic: Story = {
render: () => (
<VStack gap="4">
Expand Down
Loading

0 comments on commit 1c11a6a

Please sign in to comment.