Skip to content

Commit

Permalink
[NO-JIRA][BpkAccordion]: Fix flow types in BpkAccordion (#3674)
Browse files Browse the repository at this point in the history
* [NO-JIRA][BpkAccordion]: Fix flow types in BpkAccordion

* Convert BpkAccordion to TypeScript

* Convert accordion stories to typescript

* fix typecheck

* Update examples/bpk-component-accordion/stories.tsx

Co-authored-by: Ollie Curtis <[email protected]>

---------

Co-authored-by: Aleksandr Sannikov <[email protected]>
Co-authored-by: Ollie Curtis <[email protected]>
  • Loading branch information
3 people authored Nov 25, 2024
1 parent 114022e commit 5c3bfec
Show file tree
Hide file tree
Showing 17 changed files with 97 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
* limitations under the License.
*/

/* @flow strict */

import {
colorMonteverde,
colorPanjin,
Expand All @@ -32,6 +30,7 @@ import {
BpkAccordionItem,
withAccordionItemState,
} from '../../packages/bpk-component-accordion';
// @ts-expect-error Untyped import - see `decisions/imports-ts-suppressions.md`.
import BpkCheckbox from '../../packages/bpk-component-checkbox';
import { withAlignment } from '../../packages/bpk-component-icon';
import StopsIcon from '../../packages/bpk-component-icon/sm/stops';
Expand All @@ -44,7 +43,7 @@ const StatefulAccordionItem = withAccordionItemState(BpkAccordionItem);
const AlignedStopsIcon = withAlignment(StopsIcon, lineHeightBase, iconSizeSm);
const AlignedTimeIcon = withAlignment(TimeIcon, lineHeightBase, iconSizeSm);

const CheckboxWrapper = (props) => (
const CheckboxWrapper = (props: any) => (
<div style={{ padding: `1rem 0` }} {...props} />
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ export const WithoutDividerOnDark = SingleItemExampleWithoutDividerOnDark;
export const VisualTest = SingleItemExample;
export const VisualTestOnDark = WithDarkBackgroundExample;

export const VisualTestWithZoom = VisualTest.bind({});
VisualTestWithZoom.args = {
zoomEnabled: true,
export const VisualTestWithZoom = {
render: VisualTest,
args: {
zoomEnabled: true,
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
* limitations under the License.
*/

/* @flow strict */

import BpkAccordion from './src/BpkAccordion';
import BpkAccordionItem from './src/BpkAccordionItem';
import withAccordionItemState from './src/withAccordionItemState';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
* limitations under the License.
*/

/* @flow strict */

import { render } from '@testing-library/react';

import BpkAccordion from './BpkAccordion';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,35 @@
* limitations under the License.
*/

/* @flow strict */

import PropTypes from 'prop-types';
import { createContext, Node } from 'react';
import { createContext } from 'react';
import type { ReactNode } from 'react';

import { cssModules } from '../../bpk-react-utils';

import STYLES from './BpkAccordion.module.scss';

const getClassName = cssModules(STYLES);

type Props = { children: Node, className: ?string };
export type BpkAccordionProps = {
children: ReactNode;
className?: string;
divider?: boolean;
onDark?: boolean;
};

export const BpkAccordionContext = createContext({
onDark: false,
divider: true,
});

const BpkAccordion = (props: Props) => {
const { children, className, divider, onDark, ...rest } = props;
const BpkAccordion = (props: BpkAccordionProps) => {
const {
children,
className,
divider = true,
onDark = false,
...rest
} = props;

const classNames = getClassName(
'bpk-accordion',
Expand All @@ -45,25 +54,11 @@ const BpkAccordion = (props: Props) => {

return (
<BpkAccordionContext.Provider value={{ onDark, divider }}>
{/* // $FlowFixMe[cannot-spread-inexact] - inexact rest. See decisions/flowfixme.md */}
<div className={classNames} {...rest}>
{children}
</div>
</BpkAccordionContext.Provider>
);
};

BpkAccordion.propTypes = {
children: PropTypes.node.isRequired,
className: PropTypes.string,
onDark: PropTypes.bool,
divider: PropTypes.bool,
};

BpkAccordion.defaultProps = {
className: null,
onDark: false,
divider: true,
};

export default BpkAccordion;
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
* limitations under the License.
*/

/* @flow strict */

import { render } from '@testing-library/react';

import StopsIcon from '../../bpk-component-icon/sm/stops';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@
* limitations under the License.
*/

/* @flow strict */

import PropTypes from 'prop-types';
import { Node, Element, useContext, cloneElement } from 'react';
import { useContext, cloneElement } from 'react';
import type { ReactNode, ReactElement } from 'react';

// @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
import AnimateHeight from '../../bpk-animate-height';
import { withButtonAlignment } from '../../bpk-component-icon';
import ChevronDownIcon from '../../bpk-component-icon/sm/chevron-down';
Expand All @@ -35,18 +34,20 @@ const getClassName = cssModules(STYLES);

const ExpandIcon = withButtonAlignment(ChevronDownIcon);

type Props = {
children: Node,
id: string,
title: string,
expanded: boolean,
icon: ?Element<any>,
onClick: () => mixed,
tagName: 'span' | 'p' | 'text' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6',
textStyle: $Values<typeof TEXT_STYLES>,
export type BpkAccordionItemProps = {
children: ReactNode;
id: string;
title: string;
className?: string;
expanded?: boolean;
initiallyExpanded?: boolean;
icon?: ReactElement;
onClick?: () => void;
tagName?: 'span' | 'p' | 'text' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
textStyle?: (typeof TEXT_STYLES)[keyof typeof TEXT_STYLES];
};

const BpkAccordionItem = (props: Props) => {
const BpkAccordionItem = (props: BpkAccordionItemProps) => {
const { divider, onDark } = useContext(BpkAccordionContext);
const itemClassNames = [getClassName('bpk-accordion__item')];
const iconClassNames = [getClassName('bpk-accordion__item-expand-icon')];
Expand All @@ -59,20 +60,19 @@ const BpkAccordionItem = (props: Props) => {

const {
children,
expanded,
icon,
expanded = false,
icon = null,
id,
onClick,
tagName,
textStyle,
onClick = () => null,
tagName = 'h3',
textStyle = TEXT_STYLES.bodyDefault,
title,
...rest
} = props;

// if this component is passed initiallyExpanded, this makes sure it doesn't
// end up on the node. Not ideal as our container component shouldn't be passing
// it, but the benefit of a better container api versus this was worth it
// $FlowFixMe[prop-missing] - see above
delete rest.initiallyExpanded;

if (divider) {
Expand Down Expand Up @@ -147,7 +147,9 @@ const BpkAccordionItem = (props: Props) => {
</BpkText>
</div>
<span
className={`${getClassName('bpk-accordion__icon-wrapper')} ${iconClassNames.join(' ')}`}
className={`${getClassName(
'bpk-accordion__icon-wrapper',
)} ${iconClassNames.join(' ')}`}
>
<ExpandIcon />
</span>
Expand All @@ -163,23 +165,4 @@ const BpkAccordionItem = (props: Props) => {
);
};

BpkAccordionItem.propTypes = {
children: PropTypes.node.isRequired,
id: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
expanded: PropTypes.bool,
icon: PropTypes.node,
onClick: PropTypes.func,
tagName: PropTypes.string,
textStyle: PropTypes.string,
};

BpkAccordionItem.defaultProps = {
expanded: false,
icon: null,
onClick: () => null,
tagName: 'h3',
textStyle: TEXT_STYLES.bodyDefault,
};

export default BpkAccordionItem;
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
* limitations under the License.
*/

/* @flow strict */

import { render } from '@testing-library/react';
import { axe } from 'jest-axe';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
* limitations under the License.
*/

/* @flow strict */

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,39 @@
* limitations under the License.
*/

/* @flow strict */

import PropTypes from 'prop-types';
import { Component } from 'react';
import type { ComponentType } from 'react';

import { wrapDisplayName } from '../../bpk-react-utils';

import type { BpkAccordionItemProps } from './BpkAccordionItem';

type Props = {
initiallyExpanded: boolean,
expanded: boolean,
onClick: ?() => mixed,
initiallyExpanded: boolean;
expanded: boolean;
onClick?: () => void;
};

type State = {
expanded: boolean,
expanded: boolean;
};

const withAccordionItemState = (ComposedComponent: ComponentType<any>) => {
class WithAccordionItemState extends Component<Props, State> {
static propTypes = {
initiallyExpanded: PropTypes.bool,
expanded: PropTypes.bool,
onClick: PropTypes.func,
};
const withAccordionItemState = <P extends BpkAccordionItemProps>(
ComposedComponent: ComponentType<P>,
) => {
class WithAccordionItemState extends Component<P & Props, State> {
static displayName = wrapDisplayName(
ComposedComponent,
'withAccordionItemState',
);

static defaultProps = {
initiallyExpanded: false,
expanded: false,
onClick: null,
};

constructor(props: Props) {
constructor(props: P & Props) {
super(props);

this.state = {
Expand All @@ -69,21 +69,15 @@ const withAccordionItemState = (ComposedComponent: ComponentType<any>) => {
const { expanded, initiallyExpanded, onClick, ...rest } = this.props;

return (
// $FlowFixMe[cannot-spread-inexact] - inexact rest. See 'decisions/flowfixme.md'.
<ComposedComponent
expanded={this.state.expanded}
onClick={this.onClick}
{...rest}
{...(rest as P)}
/>
);
}
}

WithAccordionItemState.displayName = wrapDisplayName(
ComposedComponent,
'withAccordionItemState',
);

return WithAccordionItemState;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
* limitations under the License.
*/

/* @flow strict */

import { render } from '@testing-library/react';
import '@testing-library/jest-dom';

Expand All @@ -40,6 +38,7 @@ describe('withSingleItemAccordionState(BpkAccordion)', () => {

it('should render correctly with arbitrary props', () => {
const { asFragment } = render(
// @ts-expect-error - foo is not a valid prop
<EnhancedComponent className="someClass" foo="bar">
<div>Accordion Item 1</div>
<div>Accordion Item 2</div>
Expand All @@ -51,25 +50,32 @@ describe('withSingleItemAccordionState(BpkAccordion)', () => {

it('should render correctly with custom initially expanded item', () => {
const { asFragment } = render(
/* eslint-disable react/no-unknown-property */
<EnhancedComponent>
<div>Accordion Item 1</div>
{/* eslint-disable-next-line react/no-unknown-property */}
{/*
// @ts-expect-error testing unknown property */}
<div initiallyExpanded>Accordion Item 2</div>
<div>Accordion Item 3</div>
</EnhancedComponent>,
/* eslint-enable react/no-unknown-property */
);
expect(asFragment()).toMatchSnapshot();
});

it('should render correctly even when multiple items are marked as initially expanded', () => {
const { asFragment } = render(
/* eslint-disable react/no-unknown-property */
<EnhancedComponent>
<div>Accordion Item 1</div>
{/* eslint-disable-next-line react/no-unknown-property */}
{/*
// @ts-expect-error testing unknown property */}
<div initiallyExpanded>Accordion Item 2</div>
{/* eslint-disable-next-line react/no-unknown-property */}
{/*
// @ts-expect-error testing unknown property */}
<div initiallyExpanded>Accordion Item 3</div>
</EnhancedComponent>,
/* eslint-enable react/no-unknown-property */
);
expect(asFragment()).toMatchSnapshot();
});
Expand Down
Loading

0 comments on commit 5c3bfec

Please sign in to comment.