Skip to content

Commit

Permalink
Feat(web-twig): Introduce BreadcrumbsItem component
Browse files Browse the repository at this point in the history
  * and refactor Breadcrumbs to use it

refs #DS-835
  • Loading branch information
literat committed Oct 16, 2023
1 parent 57daefb commit d80b7cb
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const Breadcrumbs = <T extends ElementType = 'nav'>(props: SpiritBreadcru
<ElementTag
{...otherProps}
{...styleProps}
className={classNames(classProps, styleProps.className)}
className={classNames(classProps.root, styleProps.className)}
aria-label="Breadcrumb"
>
<ol>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ describe('useBreadcrumbsStyleProps', () => {
const props = {};
const { result } = renderHook(() => useBreadcrumbsStyleProps(props));

expect(result.current.classProps).toBe('Breadcrumbs');
expect(result.current.classProps.root).toBe('Breadcrumbs');
expect(result.current.classProps.item).toBe('d-none d-tablet-flex');
});

it('should return style props for go back only', () => {
const props = { isGoBackOnly: true };
const { result } = renderHook(() => useBreadcrumbsStyleProps(props));

expect(result.current.classProps.root).toBe('Breadcrumbs');
expect(result.current.classProps.item).toBe('d-tablet-none');
});
});
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
import classNames from 'classnames';
import { useClassNamePrefix } from '../../hooks/useClassNamePrefix';
import { BreadcrumbsStyleProps } from '../../types';

export interface BreadcrumbsStyles {
/** className props */
classProps: string;
classProps: {
root: string;
item: string;
};
/** props to be passed to the element */
props: BreadcrumbsStyleProps;
}

export function useBreadcrumbsStyleProps<P extends BreadcrumbsStyleProps>(props: P): BreadcrumbsStyles {
const { isGoBackOnly, ...restProps } = props;
const breadcrumbsClass = useClassNamePrefix('Breadcrumbs');
const displayNoneClassName = useClassNamePrefix('d-none');
const displayTabletFlexClassName = useClassNamePrefix('d-tablet-flex');
const displayTabletNoneClassName = useClassNamePrefix('d-tablet-none');

return {
classProps: breadcrumbsClass,
props,
classProps: {
root: breadcrumbsClass,
item: classNames({
[displayNoneClassName]: !isGoBackOnly,
[displayTabletFlexClassName]: !isGoBackOnly,
[displayTabletNoneClassName]: isGoBackOnly,
}),
},
props: restProps,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@

{# Class names #}
{%- set _rootClassName = _spiritClassPrefix ~ 'Breadcrumbs' -%}
{%- set _displayNoneClassName = _spiritClassPrefix ~ 'd-none' -%}
{%- set _displayTabletNoneClassName = _spiritClassPrefix ~ 'd-tablet-none' -%}
{%- set _displayTabletFlexClassName = _spiritClassPrefix ~ 'd-tablet-flex' -%}

{# Miscellaneous #}
{%- set _styleProps = useStyleProps(props) -%}
Expand All @@ -25,24 +22,9 @@
<ol>
{% for item in _items %}
{% if loop.index is same as(_items|length - 1) and _goBackTitle is not same as('') %}
<li class="{{ _displayTabletNoneClassName }}">
<Icon name="chevron-left" />
<Link href="{{ item.url }}" color="primary" isUnderlined>{{ _goBackTitle }}</Link>
</li>
<BreadcrumbsItem href={ item.url } isGoBackOnly>{{ _goBackTitle }}</BreadcrumbsItem>
{% endif %}
<li {{ classProp([_displayNoneClassName, _displayTabletFlexClassName]) }}>
{% if loop.index0 is not same as(0) %}
<Icon name="chevron-right" />
{% endif %}
<Link
href="{{ item.url }}"
color="{{ loop.last ? 'secondary' : 'primary' }}"
isUnderlined="{{ loop.last is not same as(true) }}"
aria-current="{{ loop.last ? 'page' : 'false' }}"
>
{{ item.title }}
</Link>
</li>
<BreadcrumbsItem isCurrent={ loop.last } href={ item.url }>{{ item.title }}</BreadcrumbsItem>
{% endfor %}
</ol>
{%- else -%}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{# API #}
{%- set props = props | default([]) -%}
{%- set _children = block('content') -%}
{%- set _href = props.href -%}
{%- set _iconNameEnd = props.iconNameEnd | default('chevron-right') -%}
{%- set _iconNameStart = props.iconNameStart | default('chevron-left') -%}
{%- set _isCurrent = props.isCurrent | default(false) -%}
{%- set _isGoBackOnly = props.isGoBackOnly | default(false) -%}

{# Class names #}
{%- set _displayNoneClassName = _spiritClassPrefix ~ 'd-none' -%}
{%- set _displayTabletNoneClassName = _spiritClassPrefix ~ 'd-tablet-none' -%}
{%- set _displayTabletFlexClassName = _spiritClassPrefix ~ 'd-tablet-flex' -%}

{# Miscellaneous #}
{%- set _styleProps = useStyleProps(props) -%}
{% if _isGoBackOnly is not same as(true) %}
{%- set _classNames = [ _styleProps.className, _displayNoneClassName, _displayTabletFlexClassName ] -%}
{% else %}
{%- set _classNames = [ _styleProps.className, _displayTabletNoneClassName ] -%}
{% endif %}

<li {{ mainProps(props) }} {{ styleProp(_styleProps) }} {{ classProp(_classNames) }}>
{% if _isGoBackOnly and _iconNameStart %}
<Icon name={ _iconNameStart } />
{% endif %}
<Link
href={ _href }
color="{{ _isCurrent ? 'secondary' : 'primary' }}"
isUnderlined="{{ _isCurrent is not same as(true) }}"
aria-current="{{ _isCurrent ? 'page' : 'false' }}"
>
{{ _children }}
</Link>
{% if _isCurrent is not same as(true) and _isGoBackOnly is not same as(true) and _iconNameEnd %}
<Icon name={ _iconNameEnd } />
{% endif %}
</li>
40 changes: 35 additions & 5 deletions packages/web-twig/src/Resources/components/Breadcrumbs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Breadcrumbs

This is Twig implementation of the [Breadcrumbs] component.
This is the Twig implementation of the [Breadcrumbs] component.

Basic example usage:

Expand All @@ -25,8 +25,8 @@ Basic example usage:
] %}
```

```html
<Breadcrumbs items="{{ items }}" />
```twig
<Breadcrumbs items={ items } />
```

Without lexer:
Expand Down Expand Up @@ -88,12 +88,12 @@ Without lexer:
{% endembed %}
```

## API
## Breadcrumbs

The Breadcrumbs component works with breadcrumb items passed from parent and renders the content by itself or its
content can be overridden by any custom block content.

## Breadcrumbs
### API

| Name | Type | Default | Required | Description |
| ------------- | -------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand All @@ -105,5 +105,35 @@ You can add `id`, `data-*` or `aria-*` attributes to further extend the componen
descriptiveness and accessibility. Also, UNSAFE styling props are available,
see the [Escape hatches][escape-hatches] section in README to learn how and when to use them.

## BreadcrumbsItem

Use the `BreadcrumbsItem` component for the ordered list as the component's children instead of passing the breadcrumb items array via props:

```twig
<Breadcrumbs>
{% for item in items %}
<BreadcrumbsItem isCurrent={ loop.last } href={ item.url }>
{{ item.title }}
</BreadcrumbsItem>
{% endfor %}
</Breadcrumbs>
```

### API

| Name | Type | Default | Required | Description |
| ------------------ | --------------- | --------------- | -------- | ------------------------------------------- |
| `href` | `string` ||| URL |
| `iconNameEnd` | `string` | `chevron-right` || Icon name at the end of the item |
| `iconNameStart` | `string` | `chevron-left` || Icon name at the start of the item |
| `isCurrent` | `boolean` | `false` || Whether is the item the current page |
| `isGoBackOnly` | `boolean` | `false` || Whether should be displayed in go back mode |
| `UNSAFE_className` | `string` ||| Wrapper custom class name |
| `UNSAFE_style` | `CSSProperties` ||| Wrapper custom style |

You can add `id`, `data-*` or `aria-*` attributes to further extend the component's
descriptiveness and accessibility. Also, UNSAFE styling props are available,
see the [Escape hatches][escape-hatches] section in README to learn how and when to use them.

[breadcrumbs]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web/src/scss/components/Breadcrumbs
[escape-hatches]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web-twig/README.md#escape-hatches
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
},
] %}

<Breadcrumbs items="{{ items }}" goBackTitle="Back" />
<Breadcrumbs items={ items } goBackTitle="Back" />
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,32 @@
<nav class="Breadcrumbs" aria-label="Breadcrumb">
<ol>
<li class="d-none d-tablet-flex">
<a aria-current="false" href="#rootUrl" class="link-primary link-underlined">Root</a>
<a aria-current="false" href="#rootUrl" class="link-primary link-underlined">Root</a> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24" fill="none" id="fa2b65b7e049d1eae33532715c70980f" aria-hidden="true">
<path d="M9.29006 7.05475C8.90006 7.44475 8.90006 8.07475 9.29006 8.46475L13.1701 12.3447L9.29006 16.2247C8.90006 16.6147 8.90006 17.2447 9.29006 17.6347C9.68006 18.0247 10.3101 18.0247 10.7001 17.6347L15.2901 13.0447C15.6801 12.6547 15.6801 12.0247 15.2901 11.6347L10.7001 7.04475C10.3201 6.66475 9.68006 6.66475 9.29006 7.05475Z" fill="currentColor">
</path></svg>
</li>

<li class="d-none d-tablet-flex">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24" fill="none" id="fa2b65b7e049d1eae33532715c70980f" aria-hidden="true">
<path d="M9.29006 7.05475C8.90006 7.44475 8.90006 8.07475 9.29006 8.46475L13.1701 12.3447L9.29006 16.2247C8.90006 16.6147 8.90006 17.2447 9.29006 17.6347C9.68006 18.0247 10.3101 18.0247 10.7001 17.6347L15.2901 13.0447C15.6801 12.6547 15.6801 12.0247 15.2901 11.6347L10.7001 7.04475C10.3201 6.66475 9.68006 6.66475 9.29006 7.05475Z" fill="currentColor">
</path></svg> <a aria-current="false" href="#categoryUrl" class="link-primary link-underlined">Category</a>
<a aria-current="false" href="#categoryUrl" class="link-primary link-underlined">Category</a> <svg width="24" height="24" fill="none" viewbox="0 0 24 24" aria-hidden="true">
<use href="#fa2b65b7e049d1eae33532715c70980f">
</use></svg>
</li>

<li class="d-tablet-none">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24" fill="none" id="421fdea4d7e5f5b250c10b634f7b9366" aria-hidden="true">
<path d="M14.71 7.05471C14.32 6.66471 13.69 6.66471 13.3 7.05471L8.70998 11.6447C8.31998 12.0347 8.31998 12.6647 8.70998 13.0547L13.3 17.6447C13.69 18.0347 14.32 18.0347 14.71 17.6447C15.1 17.2547 15.1 16.6247 14.71 16.2347L10.83 12.3447L14.71 8.46471C15.1 8.07471 15.09 7.43471 14.71 7.05471Z" fill="currentColor">
</path></svg><a href="#subcategoryUrl" class="link-primary link-underlined">Back</a>
</path></svg> <a aria-current="false" href="#subcategoryUrl" class="link-primary link-underlined">Back</a>
</li>

<li class="d-none d-tablet-flex">
<a aria-current="false" href="#subcategoryUrl" class="link-primary link-underlined">Subcategory</a>
<svg width="24" height="24" fill="none" viewbox="0 0 24 24" aria-hidden="true">
<use href="#fa2b65b7e049d1eae33532715c70980f">
</use></svg> <a aria-current="false" href="#subcategoryUrl" class="link-primary link-underlined">Subcategory</a>
</use></svg>
</li>

<li class="d-none d-tablet-flex">
<svg width="24" height="24" fill="none" viewbox="0 0 24 24" aria-hidden="true">
<use href="#fa2b65b7e049d1eae33532715c70980f">
</use></svg> <a aria-current="page" href="#currentUrl" class="link-secondary">Current page</a>
<a aria-current="page" href="#currentUrl" class="link-secondary">Current page</a>
</li>
</ol>
</nav>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
<Link href="#categoryUrl" color="primary" isUnderlined>Category</Link>
</li>
<li class="d-tablet-none">
<Icon name="chevron-right" />
<Link href="#subcategoryUrl" color="primary" isUnderlined>Custom go back link</Link>
<Icon name="chevron-left" />
<Link href="#subcategoryUrl" color="primary" isUnderlined>Back</Link>
</li>
<li class="d-none d-tablet-flex">
<Icon name="chevron-right" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
{% set items = [
{
title: 'Root',
url: '#rootUrl',
},
{
title: 'Category',
url: '#categoryUrl',
},
{
title: 'Subcategory',
url: '#subcategoryUrl',
},
{
title: 'Current page',
url: '#currentUrl',
},
{
title: 'Root',
url: '#rootUrl',
},
{
title: 'Category',
url: '#categoryUrl',
},
{
title: 'Subcategory',
url: '#subcategoryUrl',
},
{
title: 'Current page',
url: '#currentUrl',
},
] %}

<Breadcrumbs items={{ items }} />
<Breadcrumbs goBackTitle="Back" items={{ items }} />
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% extends '@spirit/Breadcrumbs/BreadcrumbsItem.twig' %}

0 comments on commit d80b7cb

Please sign in to comment.