Skip to content

Commit

Permalink
feat(component): covert Fieldset to FC and remove static members (#319)
Browse files Browse the repository at this point in the history
BREAKING CHANGE:
`Form.Fieldset` renamed to `Fieldset` and will now have to
`import { Fieldset } from '@bigcommerce/big-design';`
  • Loading branch information
chanceaclark authored Jan 9, 2020
1 parent a525e59 commit f75bd49
Show file tree
Hide file tree
Showing 24 changed files with 271 additions and 193 deletions.
10 changes: 9 additions & 1 deletion packages/big-design/setupTests.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '@testing-library/jest-dom/extend-expect';

import * as utils from './src/utils';
import { warning } from './src/utils/warning';

/**
* Because this util generates straightforward IDs which are saved in the snapshots,
Expand All @@ -25,6 +26,13 @@ jest.mock('./src/utils', () => {
};
});

beforeEach(() => {
jest.mock('./src/utils/warning', () => {
return {
warning: jest.fn(),
};
});

afterEach(() => {
(utils as any).resetCounter();
(warning as any).mockClear();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React, { memo } from 'react';

import { Small, TextProps } from '../../Typography';

export const FieldsetDescription: React.FC<TextProps> = memo(({ className, style, ...props }) => <Small {...props} />);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { FieldsetDescription } from './Description';
56 changes: 56 additions & 0 deletions packages/big-design/src/components/Fieldset/Fieldset.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, { memo, useMemo } from 'react';

import { warning } from '../../utils/warning';

import { StyledFieldset } from './styled';
import { FieldsetDescription } from './Description';
import { FieldsetLegend } from './Legend';

export interface FieldsetProps extends React.FieldsetHTMLAttributes<HTMLFieldSetElement> {
legend?: React.ReactChild;
description?: React.ReactChild;
}

export const Fieldset: React.FC<FieldsetProps> = memo(
({ className, legend, description, children, style, ...props }) => {
const renderedLegend = useMemo(() => {
if (typeof legend === 'string') {
return <FieldsetLegend>{legend}</FieldsetLegend>;
}

if (React.isValidElement(legend) && legend.type === FieldsetLegend) {
return legend;
}

if (!legend) {
return null;
}

warning('legend must be either a string or a FieldsetLegend component.');
}, [legend]);

const renderedDescription = useMemo(() => {
if (typeof description === 'string') {
return <FieldsetDescription>{description}</FieldsetDescription>;
}

if (React.isValidElement(description) && description.type === FieldsetDescription) {
return description;
}

if (!description) {
return null;
}

warning('description must be either a string or a FieldsetDescription component.');
}, [description]);

return (
<StyledFieldset {...props}>
{renderedLegend}
{renderedDescription}
{children}
</StyledFieldset>
);
},
);
9 changes: 9 additions & 0 deletions packages/big-design/src/components/Fieldset/Legend/Legend.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React, { memo } from 'react';

import { HeadingProps } from '../../Typography';

import { StyledFieldsetLegend } from './styled';

export const FieldsetLegend: React.FC<HeadingProps> = memo(({ className, style, ...props }) => (
<StyledFieldsetLegend {...props} />
));
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { FieldsetLegend } from './Legend';
12 changes: 12 additions & 0 deletions packages/big-design/src/components/Fieldset/Legend/styled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { theme as defaultTheme } from '@bigcommerce/big-design-theme';
import styled, { DefaultTheme, StyledComponent } from 'styled-components';

import { StyleableH3 } from '../../Typography/private';

export const StyledFieldsetLegend = styled(StyleableH3).attrs({ as: 'legend' })`
&:not(:last-child) {
margin-bottom: ${({ theme }) => theme.spacing.xxSmall};
}
` as StyledComponent<'legend', DefaultTheme>;

StyledFieldsetLegend.defaultProps = { theme: defaultTheme };
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { FieldsetProps as _FieldsetProps } from './Fieldset';

export { FieldsetDescription } from './Description';
export { Fieldset } from './Fieldset';
export { FieldsetLegend } from './Legend';
export type FieldsetProps = _FieldsetProps;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { render } from '@test/utils';
import 'jest-styled-components';
import React from 'react';

import { warning } from '../../utils/warning';

import { Fieldset } from './index';
import { FieldsetDescription } from './Description';
import { FieldsetLegend } from './Legend';

test('renders a fieldset tag', () => {
const { container } = render(<Fieldset />);
Expand All @@ -27,12 +31,12 @@ test('renders description', () => {

test('accepts a Legend Component', () => {
const CustomLegend = (
<Fieldset.Legend>
<FieldsetLegend>
This is a custom legend
<a href="#" data-testid="test">
has a url
</a>
</Fieldset.Legend>
</FieldsetLegend>
);

const { queryByTestId } = render(<Fieldset legend={CustomLegend} />);
Expand All @@ -50,19 +54,27 @@ test('does not accept non-Legend Components', () => {
</div>
);

const { queryByTestId } = render(<Fieldset legend={NotALegend} />);
render(<Fieldset legend={NotALegend} />);

expect(warning).toHaveBeenCalledTimes(1);
});

test('renders in legend is null or undefined', () => {
const { container } = render(<Fieldset />);

const fieldset = container.querySelector('fieldset');

expect(queryByTestId('test')).not.toBeInTheDocument();
expect(fieldset).toBeInTheDocument();
});

test('accepts a Description Component', () => {
const CustomDescription = (
<Fieldset.Description>
<FieldsetDescription>
This is a custom Description
<a href="#" data-testid="test">
has a url
</a>
</Fieldset.Description>
</FieldsetDescription>
);

const { queryByTestId } = render(<Fieldset description={CustomDescription} />);
Expand All @@ -80,7 +92,7 @@ test('does not accept non-Description Components', () => {
</div>
);

const { queryByTestId } = render(<Fieldset description={NotADescription} />);
render(<Fieldset description={NotADescription} />);

expect(queryByTestId('test')).not.toBeInTheDocument();
expect(warning).toHaveBeenCalledTimes(1);
});
14 changes: 14 additions & 0 deletions packages/big-design/src/components/Fieldset/styled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { theme as defaultTheme } from '@bigcommerce/big-design-theme';
import styled from 'styled-components';

export const StyledFieldset = styled.fieldset`
border: none;
margin: 0 0 ${({ theme }) => theme.spacing.xLarge};
padding: 0;
&:last-child {
margin: 0;
}
`;

StyledFieldset.defaultProps = { theme: defaultTheme };
53 changes: 0 additions & 53 deletions packages/big-design/src/components/Form/Fieldset/Fieldset.tsx

This file was deleted.

26 changes: 0 additions & 26 deletions packages/big-design/src/components/Form/Fieldset/styled.tsx

This file was deleted.

3 changes: 2 additions & 1 deletion packages/big-design/src/components/Form/Form.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import hoistNonReactStatics from 'hoist-non-react-statics';
import React, { Ref } from 'react';

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

import { StyledForm } from './styled';
import { FormControlError } from './Error';
import { Fieldset } from './Fieldset';
import { FormGroup } from './Group';
import { FormControlLabel } from './Label';

Expand Down
Loading

0 comments on commit f75bd49

Please sign in to comment.