Skip to content

Commit

Permalink
Feat(web-react): Introduce NavigationItem subcomponent #DS-1411
Browse files Browse the repository at this point in the history
  • Loading branch information
crishpeen committed Jan 8, 2025
1 parent 1da1e4d commit 40836e5
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 10 deletions.
14 changes: 11 additions & 3 deletions packages/web-react/src/components/Navigation/NavigationItem.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
'use client';

import classNames from 'classnames';
import React from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritNavigationItemProps } from '../../types';
import { useNavigationItemStyleProps } from './useNavigationItemStyleProps';

const defaultProps: Partial<SpiritNavigationItemProps> = {
isStretchingChildren: false,
};

const NavigationItem = (props: SpiritNavigationItemProps): JSX.Element => {
const { children, ...restProps } = props;
const propsWithDefaults = { ...defaultProps, ...props };
const { children, ...restProps } = propsWithDefaults;

const { styleProps, props: otherProps } = useStyleProps(restProps);
const { classProps, props: modifiedProps } = useNavigationItemStyleProps(restProps);
const { styleProps, props: otherProps } = useStyleProps(modifiedProps);

return (
<li {...otherProps} className={styleProps.className} style={styleProps.style}>
<li {...otherProps} className={classNames(classProps, styleProps.className)} style={styleProps.style}>
{children}
</li>
);
Expand Down
22 changes: 19 additions & 3 deletions packages/web-react/src/components/Navigation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,27 @@ import { NavigationItem } from '@lmc-eu/spirit-web-react';
<NavigationItem>{/* Navigation actions go here */}</NavigationItem>;
```

If the children are not `NavigationAction` components or the `NavigationItem` does not have the
`isStretchingChildren` class, it will centre its children vertically.

```jsx
<NavigationItem>
<Link href="#">Vertically centered Link</Link>
</NavigationItem>
<NavigationItem isStretchingChildren>
<Link href="#">Stretched Link</Link>
</NavigationItem>
<NavigationItem>
<NavigationAction href="#">Stretched NavigationAction</NavigationAction>
</NavigationItem>
```

### API

| Name | Type | Default | Required | Description |
| ---------- | ----------------------- | ------- | -------- | ----------------------------- |
| `children` | `string` \| `ReactNode` | `null` || Content of the NavigationItem |
| Name | Type | Default | Required | Description |
| ---------------------- | ----------------------- | ------- | -------- | ---------------------------------------- |
| `children` | `string` \| `ReactNode` | `null` || Content of the NavigationItem |
| `isStretchingChildren` | `boolean` | `false` || Whether the children should be stretched |

The components accept [additional attributes][readme-additional-attributes].
If you need more control over the styling of a component, you can use [style props][readme-style-props]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';
import React from 'react';
import { restPropsTest } from '../../../../tests/providerTests/restPropsTest';
import { stylePropsTest } from '../../../../tests/providerTests/stylePropsTest';
import { classNamePrefixProviderTest, restPropsTest, stylePropsTest } from '@local/tests';
import NavigationItem from '../NavigationItem';

describe('NavigationItem', () => {
classNamePrefixProviderTest(NavigationItem, 'NavigationItem');

stylePropsTest(NavigationItem);

restPropsTest(NavigationItem, 'li');

it('should have default classname', () => {
render(<NavigationItem>Content</NavigationItem>);

expect(screen.getByRole('listitem')).toHaveClass('NavigationItem');
});

it('should have stretchChildren classname', () => {
render(<NavigationItem isStretchingChildren>Content</NavigationItem>);

expect(screen.getByRole('listitem')).toHaveClass('NavigationItem--stretchChildren');
});

it('should have correct role', () => {
render(<NavigationItem>Content</NavigationItem>);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { renderHook } from '@testing-library/react';
import { useNavigationItemStyleProps } from '../useNavigationItemStyleProps';

describe('useNavigationItemStyleProps', () => {
it('should return defaults', () => {
const props = {};
const { result } = renderHook(() => useNavigationItemStyleProps(props));

expect(result.current.classProps).toBe('NavigationItem');
});

it('should return stretchChildren class', () => {
const props = { isStretchingChildren: true };
const { result } = renderHook(() => useNavigationItemStyleProps(props));

expect(result.current.classProps).toBe('NavigationItem NavigationItem--stretchChildren');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import classNames from 'classnames';
import { useClassNamePrefix } from '../../hooks';
import { SpiritNavigationItemProps } from '../../types';

export interface NavigationItemStyles {
classProps: string;
props: SpiritNavigationItemProps;
}

export const useNavigationItemStyleProps = (props: SpiritNavigationItemProps): NavigationItemStyles => {
const { isStretchingChildren, ...restProps } = props;
const itemClass = useClassNamePrefix('NavigationItem');
const itemIsStretchingChildrenClass = `${itemClass}--stretchChildren`;

const className = classNames(itemClass, {
[itemIsStretchingChildrenClass]: isStretchingChildren,
});

return {
classProps: className,
props: restProps,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export interface NavigationStyles {
classProps: string;
}

export const useNavigationStyleProps = () => {
export const useNavigationStyleProps = (): NavigationStyles => {
const navigationClass = useClassNamePrefix('Navigation');

return {
Expand Down
4 changes: 3 additions & 1 deletion packages/web-react/src/types/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ export type NavigationActionProps<E extends ElementType> = {
elementType?: E;
} & NavigationActionBaseProps;

export interface SpiritNavigationItemProps extends ChildrenProps, StyleProps {}
export interface SpiritNavigationItemProps extends ChildrenProps, StyleProps {
isStretchingChildren?: boolean;
}

export type SpiritNavigationActionProps<E extends ElementType = 'a'> = NavigationActionProps<E> &
SpiritPolymorphicElementPropsWithRef<E, NavigationActionProps<E>>;
Expand Down

0 comments on commit 40836e5

Please sign in to comment.