Skip to content

Commit

Permalink
feat: Refactor <Label> (#1914)
Browse files Browse the repository at this point in the history
- no variants anymore
- no disabled (not possible anyway)
- improve a11y

Ref #1889
  • Loading branch information
sebald authored Mar 25, 2022
1 parent 72da35a commit 762122a
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 0 deletions.
27 changes: 27 additions & 0 deletions packages/components/src/Field-Next/Label.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import type { Meta, ComponentStory } from '@storybook/react';
import { Label } from './Label';

export default {
title: 'Field/Label',
argTypes: {
children: {
control: {
type: 'text',
},
description: 'Text of the label',
defaultValue: 'Label',
},
required: {
control: {
type: 'boolean',
},
description: 'Hint that the related control required',
defaultValue: false,
},
},
} as Meta;

export const Basic: ComponentStory<typeof Label> = ({ children, ...args }) => (
<Label {...args}>{children}</Label>
);
74 changes: 74 additions & 0 deletions packages/components/src/Field-Next/Label.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React from 'react';
import { render, screen, within } from '@testing-library/react';
import { ThemeProvider } from '@marigold/system';
import { Label } from './Label';

const theme = {
fonts: {
body: 'Inter Regular',
label: 'Oswald',
},
colors: {
text: 'black',
},
label: {
fontFamily: 'body',
color: 'text',
},
};

test('supports default variant and styles', () => {
render(
<ThemeProvider theme={theme}>
<Label>label</Label>
</ThemeProvider>
);
const label = screen.getByText(/label/);

expect(label).toHaveStyle(`font-family: Inter Regular`);
expect(label).toHaveStyle(`color: black`);
});

test('supports htmlFor prop', () => {
render(
<ThemeProvider theme={theme}>
<Label htmlFor="labelId">label</Label>
</ThemeProvider>
);
const label = screen.getByText(/label/);

expect(label).toHaveAttribute('for');
});

test('supports required prop', () => {
render(
<ThemeProvider theme={theme}>
<Label data-testid="label" required>
label
</Label>
</ThemeProvider>
);
const label = screen.getByTestId(/label/);
const requiredIcon = within(label).getByRole('img');
expect(requiredIcon).toBeInTheDocument();
});

test('renders <label> element by default', () => {
render(
<ThemeProvider theme={theme}>
<Label>label</Label>
</ThemeProvider>
);
const label = screen.getByText(/label/);
expect(label instanceof HTMLLabelElement).toBeTruthy();
});

test('can render as <span>', () => {
render(
<ThemeProvider theme={theme}>
<Label as="span">label</Label>
</ThemeProvider>
);
const label = screen.getByText(/label/);
expect(label instanceof HTMLSpanElement).toBeTruthy();
});
51 changes: 51 additions & 0 deletions packages/components/src/Field-Next/Label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// TODO: But this back into the root, when we realease all the new fields!
import React from 'react';
import { Required } from '@marigold/icons';
import { ComponentProps } from '@marigold/types';

import { Box } from '../Box';

// Theme Extension
// ---------------
export interface LabelThemeExtension<Value> {
label?: {
[key: string]: Value;
};
}

// Props
// ---------------
export interface LabelProps extends ComponentProps<'label'> {
as?: 'label' | 'span';
required?: boolean;
}

// Component
// ---------------
export interface LabelThemeExtension<Value> {
label?: {
[key: string]: Value;
};
}
export const Label: React.FC<LabelProps> = ({
as = 'label',
required,
children,
...props
}) => {
return (
<Box
{...props}
as={as}
variant="label"
__baseCSS={{ display: 'flex', alignItems: 'center', gap: 4 }}
>
{children}
{/*
* aria-required is set on the field and will already be announced,
* so we don't need to add it here.
*/}
{required && <Required role="img" size={16} />}
</Box>
);
};

0 comments on commit 762122a

Please sign in to comment.