From eca5fe4ed0325b01860f816c70247c26e2158f9c Mon Sep 17 00:00:00 2001
From: Aram <37216945+alimpens@users.noreply.github.com>
Date: Wed, 6 Nov 2024 17:47:10 +0100
Subject: [PATCH] feat: Add Icon to Error Message (#1746)

---
 .../components/error-message/error-message.scss    |  2 ++
 .../react/src/ErrorMessage/ErrorMessage.test.tsx   | 14 ++++++++++++++
 packages/react/src/ErrorMessage/ErrorMessage.tsx   |  7 ++++++-
 .../src/components/ams/error-message.tokens.json   |  1 +
 .../components/ErrorMessage/ErrorMessage.docs.mdx  |  7 +++++++
 .../ErrorMessage/ErrorMessage.stories.tsx          |  7 +++++++
 6 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/packages/css/src/components/error-message/error-message.scss b/packages/css/src/components/error-message/error-message.scss
index 4dd6e3fd19..31232a453e 100644
--- a/packages/css/src/components/error-message/error-message.scss
+++ b/packages/css/src/components/error-message/error-message.scss
@@ -12,9 +12,11 @@
 
 .ams-error-message {
   color: var(--ams-error-message-color);
+  display: inline-flex;
   font-family: var(--ams-error-message-font-family);
   font-size: var(--ams-error-message-font-size);
   font-weight: var(--ams-error-message-font-weight);
+  gap: var(--ams-error-message-gap);
   line-height: var(--ams-error-message-line-height);
 
   @include text-rendering;
diff --git a/packages/react/src/ErrorMessage/ErrorMessage.test.tsx b/packages/react/src/ErrorMessage/ErrorMessage.test.tsx
index a57a4c5e0e..999ffcecb2 100644
--- a/packages/react/src/ErrorMessage/ErrorMessage.test.tsx
+++ b/packages/react/src/ErrorMessage/ErrorMessage.test.tsx
@@ -54,4 +54,18 @@ describe('Error message', () => {
 
     expect(ref.current).toBe(component)
   })
+
+  it('shows an icon', () => {
+    const { container } = render(<ErrorMessage />)
+
+    const iconWrapper = container.querySelector('.ams-icon')
+    const icon = container.querySelector('svg')
+
+    expect(iconWrapper).toBeInTheDocument()
+    expect(icon).toBeInTheDocument()
+  })
+
+  // TODO: we can't currently test this, because we can't pass a class or anything to the SVG
+  // We plan on changing this, so we can test this in the future
+  it.skip('shows a custom icon', () => {})
 })
diff --git a/packages/react/src/ErrorMessage/ErrorMessage.tsx b/packages/react/src/ErrorMessage/ErrorMessage.tsx
index 95d4f1321d..ad47546017 100644
--- a/packages/react/src/ErrorMessage/ErrorMessage.tsx
+++ b/packages/react/src/ErrorMessage/ErrorMessage.tsx
@@ -3,21 +3,26 @@
  * Copyright Gemeente Amsterdam
  */
 
+import { AlertIcon } from '@amsterdam/design-system-react-icons'
 import clsx from 'clsx'
 import { forwardRef } from 'react'
 import type { ForwardedRef, HTMLAttributes, PropsWithChildren } from 'react'
+import { Icon } from '../Icon'
 
 export type ErrorMessageProps = {
+  /** An icon to display instead of the default icon. */
+  icon?: Function
   /** An accessible phrase that screen readers announce before the error message. Should translate to something like ‘input error’. */
   prefix?: string
 } & PropsWithChildren<HTMLAttributes<HTMLParagraphElement>>
 
 export const ErrorMessage = forwardRef(
   (
-    { children, className, prefix = 'Invoerfout', ...restProps }: ErrorMessageProps,
+    { children, className, icon, prefix = 'Invoerfout', ...restProps }: ErrorMessageProps,
     ref: ForwardedRef<HTMLParagraphElement>,
   ) => (
     <p {...restProps} ref={ref} className={clsx('ams-error-message', className)}>
+      <Icon svg={icon ? icon : AlertIcon} size="level-6" />
       <span className="ams-visually-hidden">
         {prefix}
         {': '}
diff --git a/proprietary/tokens/src/components/ams/error-message.tokens.json b/proprietary/tokens/src/components/ams/error-message.tokens.json
index a742de7279..84ccb6548a 100644
--- a/proprietary/tokens/src/components/ams/error-message.tokens.json
+++ b/proprietary/tokens/src/components/ams/error-message.tokens.json
@@ -5,6 +5,7 @@
       "font-family": { "value": "{ams.text.font-family}" },
       "font-size": { "value": "{ams.text.level.6.font-size}" },
       "font-weight": { "value": "{ams.text.font-weight.normal}" },
+      "gap": { "value": "{ams.space.xs}" },
       "line-height": { "value": "{ams.text.level.6.line-height}" }
     }
   }
diff --git a/storybook/src/components/ErrorMessage/ErrorMessage.docs.mdx b/storybook/src/components/ErrorMessage/ErrorMessage.docs.mdx
index ce55a97394..5929aa8747 100644
--- a/storybook/src/components/ErrorMessage/ErrorMessage.docs.mdx
+++ b/storybook/src/components/ErrorMessage/ErrorMessage.docs.mdx
@@ -21,3 +21,10 @@ This makes the error message more clear for screen reader users.
 If you want to change this prefix, to support another language for example, you can use the `prefix` prop.
 
 <Canvas of={ErrorMessageStories.CustomPrefix} />
+
+### With custom icon
+
+Replace the icon with another to use Error Message in a different theme or visual identity.
+Applications for the City of Amsterdam must use the default icon.
+
+<Canvas of={ErrorMessageStories.WithCustomIcon} />
diff --git a/storybook/src/components/ErrorMessage/ErrorMessage.stories.tsx b/storybook/src/components/ErrorMessage/ErrorMessage.stories.tsx
index 3dc79cad2b..1e0357567e 100644
--- a/storybook/src/components/ErrorMessage/ErrorMessage.stories.tsx
+++ b/storybook/src/components/ErrorMessage/ErrorMessage.stories.tsx
@@ -4,6 +4,7 @@
  */
 
 import { ErrorMessage } from '@amsterdam/design-system-react/src'
+import { AnnouncementIcon } from '@amsterdam/design-system-react-icons'
 import { Meta, StoryObj } from '@storybook/react'
 
 const meta = {
@@ -31,3 +32,9 @@ export const CustomPrefix: Story = {
     prefix: 'Error',
   },
 }
+
+export const WithCustomIcon: Story = {
+  args: {
+    icon: AnnouncementIcon,
+  },
+}