Skip to content

Commit

Permalink
BREAKING CHANGE(web-react): Rename CheckboxField component to `Checkb…
Browse files Browse the repository at this point in the history
…ox` #DS-522

 ## Migration Guide

Rename and use `Checkbox` component instead of `CheckboxField`.

- `<CheckboxField …>` → `<Checkbox …>`

Please refer back to this guide or reach out to our team
if you encounter any issues during migration.
  • Loading branch information
crishpeen authored and literat committed Jul 21, 2023
1 parent 3044ce1 commit e44f569
Show file tree
Hide file tree
Showing 25 changed files with 204 additions and 204 deletions.
2 changes: 1 addition & 1 deletion packages/web-react/scripts/entryPoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const entryPoints = [
{ dirs: ['components', 'Alert'] },
{ dirs: ['components', 'Breadcrumbs'] },
{ dirs: ['components', 'Button'] },
{ dirs: ['components', 'CheckboxField'] },
{ dirs: ['components', 'Checkbox'] },
{ dirs: ['components', 'Collapse'] },
{ dirs: ['components', 'Container'] },
{ dirs: ['components', 'Dialog'] },
Expand Down
22 changes: 22 additions & 0 deletions packages/web-react/src/components/Checkbox/Checkbox.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ComponentMeta } from '@storybook/react';
import argTypes from './stories/argTypes';
import Checkbox from './Checkbox';

export default {
title: 'Components/Checkbox',
component: Checkbox,
parameters: {
docs: {
description: {
component: 'Use Checkbox when you have a group of choices and any selection from the group is allowed.',
},
},
},
argTypes,
} as ComponentMeta<typeof Checkbox>;

export { default as Checkbox } from './stories/Checkbox';
export { default as CheckboxValidationState } from './stories/CheckboxValidationState';
export { default as CheckboxHelperText } from './stories/CheckboxHelperText';
export { default as CheckboxItem } from './stories/CheckboxItem';
export { default as Props } from './stories/CheckboxProps';
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React, { forwardRef, ForwardedRef } from 'react';
import classNames from 'classnames';
import { useStyleProps } from '../../hooks';
import { SpiritCheckboxFieldProps } from '../../types';
import { SpiritCheckboxProps } from '../../types';
import { useValidationText } from '../Field';
import { useCheckboxFieldStyleProps } from './useCheckboxFieldStyleProps';
import { useCheckboxStyleProps } from './useCheckboxStyleProps';

/* We need an exception for components exported with forwardRef */
/* eslint no-underscore-dangle: ['error', { allow: ['_CheckboxField'] }] */
const _CheckboxField = (props: SpiritCheckboxFieldProps, ref: ForwardedRef<HTMLInputElement>): JSX.Element => {
const { classProps, props: modifiedProps } = useCheckboxFieldStyleProps(props);
/* eslint no-underscore-dangle: ['error', { allow: ['_Checkbox'] }] */
const _Checkbox = (props: SpiritCheckboxProps, ref: ForwardedRef<HTMLInputElement>): JSX.Element => {
const { classProps, props: modifiedProps } = useCheckboxStyleProps(props);
const {
id,
label,
Expand Down Expand Up @@ -52,6 +52,6 @@ const _CheckboxField = (props: SpiritCheckboxFieldProps, ref: ForwardedRef<HTMLI
);
};

export const CheckboxField = forwardRef<HTMLInputElement, SpiritCheckboxFieldProps>(_CheckboxField);
export const Checkbox = forwardRef<HTMLInputElement, SpiritCheckboxProps>(_Checkbox);

export default CheckboxField;
export default Checkbox;
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# CheckboxField
# Checkbox

CheckboxField enables the user to check/uncheck choice.
Checkbox enables the user to check/uncheck choice.
It has input, a label, and an optional helperText.
It could be disabled or have a validation state.
The label could be hidden and show if the input is required.

Basic example usage:

```jsx
<CheckboxField id="checkboxfieldDefault" label="Label" name="checkboxfieldDefault" />
<Checkbox id="checkboxDefault" label="Label" name="checkboxDefault" />
```

Advanced example usage:

```jsx
<CheckboxField
id="checkboxfieldAdvanced"
<Checkbox
id="checkboxAdvanced"
isChecked
isRequired
name="checkboxfieldAdvanced"
name="checkboxAdvanced"
validationText="validation text"
validationState="danger"
helperText="Helper text"
Expand All @@ -44,11 +44,11 @@ Advanced example usage:

## Custom component

Text field classes are fabricated using `useCheckboxFieldStyleProps` hook. You can use it to create your own custom CheckboxField component.
Text field classes are fabricated using `useCheckboxStyleProps` hook. You can use it to create your own custom Checkbox component.

```jsx
const CustomCheckboxField = (props: SpiritCheckboxFieldProps): JSX.Element => {
const { classProps, props: modifiedProps } = useCheckboxFieldStyleProps(props);
const CustomCheckbox = (props: SpiritCheckboxProps): JSX.Element => {
const { classProps, props: modifiedProps } = useCheckboxStyleProps(props);

return (
<label htmlFor={props.id} className={classProps.root}>
Expand All @@ -63,7 +63,7 @@ const CustomCheckboxField = (props: SpiritCheckboxFieldProps): JSX.Element => {
};
```

For detailed information see [CheckboxField](https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/src/scss/components/CheckboxField/README.md) component
For detailed information see [Checkbox](https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/src/scss/components/Checkbox/README.md) component

[item]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/src/components/Item/README.md
[dictionary-validation]: https://github.com/lmc-eu/spirit-design-system/blob/main/docs/DICTIONARIES.md#validation
Original file line number Diff line number Diff line change
Expand Up @@ -7,60 +7,60 @@ import { stylePropsTest } from '../../../../tests/providerTests/stylePropsTest';
import { restPropsTest } from '../../../../tests/providerTests/restPropsTest';
import { validationStatePropsTest } from '../../../../tests/providerTests/dictionaryPropsTest';
import { validationTextPropsTest } from '../../../../tests/providerTests/validationTextPropsTest';
import CheckboxField from '../CheckboxField';
import Checkbox from '../Checkbox';

describe('CheckboxField', () => {
classNamePrefixProviderTest(CheckboxField, 'CheckboxField');
describe('Checkbox', () => {
classNamePrefixProviderTest(Checkbox, 'Checkbox');

itemPropsTest(CheckboxField);
itemPropsTest(Checkbox);

stylePropsTest(CheckboxField);
stylePropsTest(Checkbox);

restPropsTest(CheckboxField, 'input');
restPropsTest(Checkbox, 'input');

validationStatePropsTest(CheckboxField, 'CheckboxField--');
validationStatePropsTest(Checkbox, 'Checkbox--');

validationTextPropsTest(CheckboxField, '.CheckboxField__validationText');
validationTextPropsTest(Checkbox, '.Checkbox__validationText');

it('should have text classname', () => {
const dom = render(<CheckboxField id="checkbox" label="Label" />);
const dom = render(<Checkbox id="checkbox" label="Label" />);

const element = dom.container.querySelector('label > span') as HTMLElement;
expect(element).toHaveClass('CheckboxField__text');
expect(element).toHaveClass('Checkbox__text');
});

it('should have label classname', () => {
const dom = render(<CheckboxField id="checkbox" label="Label" isLabelHidden />);
const dom = render(<Checkbox id="checkbox" label="Label" isLabelHidden />);

const element = dom.container.querySelector('label > span > span:first-child') as HTMLElement;
expect(element).toHaveClass('CheckboxField__label');
expect(element).toHaveClass('Checkbox__label');
});

it('should have hidden classname', () => {
const dom = render(<CheckboxField id="checkbox" label="Label" isLabelHidden />);
const dom = render(<Checkbox id="checkbox" label="Label" isLabelHidden />);

const element = dom.container.querySelector('label > span > span:first-child') as HTMLElement;
expect(element).toHaveClass('CheckboxField__label--hidden');
expect(element).toHaveClass('Checkbox__label--hidden');
});

it('should have required classname', () => {
const dom = render(<CheckboxField id="checkbox" label="Label" isRequired />);
const dom = render(<Checkbox id="checkbox" label="Label" isRequired />);

const element = dom.container.querySelector('label > span > span:first-child') as HTMLElement;
expect(element).toHaveClass('CheckboxField__label--required');
expect(element).toHaveClass('Checkbox__label--required');
});

it('should have input classname', () => {
const dom = render(<CheckboxField id="checkbox" label="Label" />);
const dom = render(<Checkbox id="checkbox" label="Label" />);

const element = dom.container.querySelector('input') as HTMLElement;
expect(element).toHaveClass('CheckboxField__input');
expect(element).toHaveClass('Checkbox__input');
});

it('should have helper text', () => {
const dom = render(<CheckboxField id="checkbox" label="Label" helperText="text" />);
const dom = render(<Checkbox id="checkbox" label="Label" helperText="text" />);

const element = dom.container.querySelector('.CheckboxField__helperText') as HTMLElement;
const element = dom.container.querySelector('.Checkbox__helperText') as HTMLElement;
expect(element.textContent).toBe('text');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { renderHook } from '@testing-library/react-hooks';
import { SpiritCheckboxProps } from '../../../types';
import { ValidationStates } from '../../../constants';
import { useCheckboxStyleProps } from '../useCheckboxStyleProps';

describe('useCheckboxStyleProps', () => {
it('should return defaults', () => {
const props = { id: 'checkbox', label: 'Label' };
const { result } = renderHook(() => useCheckboxStyleProps(props));

expect(result.current.classProps).toEqual({
root: 'Checkbox',
text: 'Checkbox__text',
input: 'Checkbox__input',
label: 'Checkbox__label',
validationText: 'Checkbox__validationText',
helperText: 'Checkbox__helperText',
});
});

it('should return required input', () => {
const props = { isRequired: true } as SpiritCheckboxProps;
const { result } = renderHook(() => useCheckboxStyleProps(props));

expect(result.current.classProps.label).toBe('Checkbox__label Checkbox__label--required');
});

it('should return hidden label', () => {
const props = { isLabelHidden: true } as SpiritCheckboxProps;
const { result } = renderHook(() => useCheckboxStyleProps(props));

expect(result.current.classProps.label).toBe('Checkbox__label Checkbox__label--hidden');
});

it('should return field as an Item', () => {
const props = { isItem: true } as SpiritCheckboxProps;
const { result } = renderHook(() => useCheckboxStyleProps(props));

expect(result.current.classProps.root).toBe('Checkbox Checkbox--item');
});

it.each([Object.values(ValidationStates)])('should return field with %s', (state) => {
const props = { validationState: state } as SpiritCheckboxProps;
const { result } = renderHook(() => useCheckboxStyleProps(props));

expect(result.current.classProps.root).toBe(`Checkbox Checkbox--${state}`);
});
});
3 changes: 3 additions & 0 deletions packages/web-react/src/components/Checkbox/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './Checkbox';
export * from './useCheckboxStyleProps';
export { default as Checkbox } from './Checkbox';
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
import { ComponentStory } from '@storybook/react';
import Checkbox from '../Checkbox';
import { SpiritCheckboxProps } from '../../../types';

const Story: ComponentStory<typeof Checkbox> = (args: SpiritCheckboxProps) => <Checkbox {...args} />;

export default Story;
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import { ComponentStory } from '@storybook/react';
import CheckboxField from '../CheckboxField';
import { SpiritCheckboxFieldProps } from '../../../types';
import Checkbox from '../Checkbox';
import { SpiritCheckboxProps } from '../../../types';

const Story: ComponentStory<typeof CheckboxField> = (args: SpiritCheckboxFieldProps) => <CheckboxField {...args} />;
const Story: ComponentStory<typeof Checkbox> = (args: SpiritCheckboxProps) => <Checkbox {...args} />;

Story.args = {
id: 'example',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import { ComponentStory } from '@storybook/react';
import CheckboxField from '../CheckboxField';
import { SpiritCheckboxFieldProps } from '../../../types';
import Checkbox from '../Checkbox';
import { SpiritCheckboxProps } from '../../../types';

const Story: ComponentStory<typeof CheckboxField> = (args: SpiritCheckboxFieldProps) => <CheckboxField {...args} />;
const Story: ComponentStory<typeof Checkbox> = (args: SpiritCheckboxProps) => <Checkbox {...args} />;

Story.args = {
isChecked: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';
import { Checkbox } from '../Checkbox';
import Props from '../../../../docs/stories/Props';

const Story = () => <Props component={Checkbox} />;

export default Story;
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import React from 'react';
import CheckboxField from '../CheckboxField';
import Checkbox from '../Checkbox';

const Story = () => (
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '1.5rem 1rem' }}>
<CheckboxField
id="checkboxfield0"
<Checkbox
id="checkbox0"
label="Checkbox success"
name="example"
validationState="success"
validationText="Success validation text"
/>
<CheckboxField
id="checkboxfield1"
<Checkbox
id="checkbox1"
label="Checkbox warning"
name="example"
validationState="warning"
validationText="Warning validation text"
/>
<CheckboxField
id="checkboxfield2"
<Checkbox
id="checkbox2"
label="Checkbox danger"
name="example"
validationState="danger"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import classNames from 'classnames';
import { useClassNamePrefix } from '../../hooks';
import { SpiritCheckboxProps, CheckboxProps } from '../../types';

export interface CheckboxStyles {
/** className props */
classProps: {
root: string;
text: string;
label: string;
input: string;
helperText: string;
validationText: string;
};
/** props to be passed to the input element */
props: CheckboxProps;
}

export function useCheckboxStyleProps(props: SpiritCheckboxProps): CheckboxStyles {
const { validationState, isItem, isLabelHidden, ...restProps } = props;
const { isDisabled, isRequired } = restProps;

const checkboxClass = useClassNamePrefix('Checkbox');
const checkboxDisabledClass = `${checkboxClass}--disabled`;
const checkboxItemClass = `${checkboxClass}--item`;
const checkboxInputClass = `${checkboxClass}__input`;
const checkboxTextClass = `${checkboxClass}__text`;
const checkboxLabelClass = `${checkboxClass}__label`;
const checkboxLabelRequiredClass = `${checkboxClass}__label--required`;
const checkboxLabelHiddenClass = `${checkboxClass}__label--hidden`;
const checkboxHelperTextClass = `${checkboxClass}__helperText`;
const checkboxValidationTextClass = `${checkboxClass}__validationText`;
const checkboxValidationClass = `${checkboxClass}--${validationState}`;

const rootStyles = classNames(checkboxClass, {
[checkboxDisabledClass]: isDisabled,
[checkboxItemClass]: isItem,
[checkboxValidationClass]: validationState,
});
const labelStyles = classNames(checkboxLabelClass, {
[checkboxLabelRequiredClass]: isRequired,
[checkboxLabelHiddenClass]: isLabelHidden,
});

return {
classProps: {
root: rootStyles,
text: checkboxTextClass,
label: labelStyles,
input: checkboxInputClass,
helperText: checkboxHelperTextClass,
validationText: checkboxValidationTextClass,
},
props: {
...restProps,
validationState,
},
};
}
Loading

0 comments on commit e44f569

Please sign in to comment.