Repository: marigold-ui/marigold
Pull request #1920 (2022-03-28 07:12:45)

feat: Intorduce <HelperText> for fields
Ref #1889

changeset-bot[bot]: ###  ⚠️  No Changeset found

Latest commit: a22a01fa7febca14e04ea95faf5fa13fb72a80bb

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/master/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/marigold-ui/marigold/new/helper-text?filename=.changeset/sour-rings-punch.md&value=---%0A%22%40marigold%2Fcomponents%22%3A%20patch%0A---%0A%0Afeat%3A%20Intorduce%20%3CHelperText%3E%20for%20fields%0A)



Patch:
diff --git a/packages/components/src/Field-Next/HelperText.stories.tsx b/packages/components/src/Field-Next/HelperText.stories.tsx
new file mode 100644
index 000000000..a6f9856f8
--- /dev/null
+++ b/packages/components/src/Field-Next/HelperText.stories.tsx
@@ -0,0 +1,29 @@
+import React from 'react';
+import type { Meta, ComponentStory } from '@storybook/react';
+import { HelperText } from './HelperText';
+
+export default {
+  title: 'Field/HelperText',
+  argTypes: {
+    children: {
+      control: {
+        type: 'text',
+      },
+      description: 'Text of the label',
+      defaultValue: 'This is the helper text!',
+    },
+    variant: {
+      control: {
+        type: 'select',
+      },
+      options: ['description', 'error'],
+      description: 'Choose between description and error',
+      defaultValue: 'description',
+    },
+  },
+} as Meta;
+
+export const Basic: ComponentStory<typeof HelperText> = ({
+  children,
+  ...args
+}) => <HelperText {...args}>{children}</HelperText>;
diff --git a/packages/components/src/Field-Next/HelperText.tsx b/packages/components/src/Field-Next/HelperText.tsx
new file mode 100644
index 000000000..1daa31342
--- /dev/null
+++ b/packages/components/src/Field-Next/HelperText.tsx
@@ -0,0 +1,37 @@
+import React from 'react';
+import { Exclamation } from '@marigold/icons';
+
+import { Box } from '../Box';
+
+// Theme Extension
+// ---------------
+export interface HelperTextThemeExtension<Value> {
+  helperText?: {
+    description: Value;
+    error: Value;
+    icon: {
+      size: number | string;
+    };
+  };
+}
+
+// Props
+// ---------------
+export interface HelperTextProps {
+  variant?: 'description' | 'error';
+}
+
+// Component
+// ---------------
+export const HelperText: React.FC<HelperTextProps> = ({
+  variant = 'description',
+  children,
+}) => (
+  <Box
+    variant={`helperText.${variant}`}
+    __baseCSS={{ display: 'flex', alignItems: 'center', gap: 4 }}
+  >
+    {variant === 'error' ? <Exclamation role="presentation" /> : null}
+    {children}
+  </Box>
+);


Test patch:
diff --git a/packages/components/src/Field-Next/HelperText.test.tsx b/packages/components/src/Field-Next/HelperText.test.tsx
new file mode 100644
index 000000000..eee607816
--- /dev/null
+++ b/packages/components/src/Field-Next/HelperText.test.tsx
@@ -0,0 +1,50 @@
+import React from 'react';
+import { render, screen, within } from '@testing-library/react';
+import { ThemeProvider } from '@marigold/system';
+import { HelperText } from './HelperText';
+
+const theme = {
+  colors: {
+    text: 'black',
+    error: 'red',
+  },
+  helperText: {
+    description: {
+      color: 'text',
+    },
+    error: {
+      color: 'error',
+    },
+  },
+};
+
+test('supports description variant', () => {
+  render(
+    <ThemeProvider theme={theme}>
+      <HelperText>label</HelperText>
+    </ThemeProvider>
+  );
+  const label = screen.getByText(/label/);
+  expect(label).toHaveStyle(`color: black`);
+});
+
+test('supports error variant', () => {
+  render(
+    <ThemeProvider theme={theme}>
+      <HelperText variant="error">label</HelperText>
+    </ThemeProvider>
+  );
+  const label = screen.getByText(/label/);
+  expect(label).toHaveStyle(`color: red`);
+});
+
+test('renders icon when variant is error', () => {
+  render(
+    <ThemeProvider theme={theme}>
+      <HelperText variant="error">label</HelperText>
+    </ThemeProvider>
+  );
+  const label = screen.getByText(/label/);
+  const icon = within(label).getByRole(/presentation/);
+  expect(icon).toBeInTheDocument();
+});