Skip to content

Commit e6f130a

Browse files
committed
feat: add PixNavigationButton and PixNavigationSeparator
1 parent be19980 commit e6f130a

10 files changed

+220
-23
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{{#if @route}}
2+
<LinkTo
3+
@route={{@route}}
4+
@models={{if @model (array @model) this.defaultModel}}
5+
@query={{if @query @query this.defaultParams}}
6+
class="pix-navigation-button"
7+
...attributes
8+
>
9+
{{#if @icon}}
10+
<PixIcon
11+
class="pix-navigation-button__icon"
12+
@ariaHidden={{true}}
13+
@name={{@icon}}
14+
@plainIcon={{@iconPlain}}
15+
/>
16+
{{/if}}
17+
{{yield}}
18+
</LinkTo>
19+
{{else}}
20+
{{! template-lint-disable link-href-attributes }}
21+
<a ...attributes class="pix-navigation-button" target={{if this.isLinkOpenInANewWindow "_blank"}}>
22+
{{#if @icon}}
23+
<PixIcon
24+
class="pix-navigation-button__icon"
25+
@ariaHidden={{true}}
26+
@name={{@icon}}
27+
@plainIcon={{@iconPlain}}
28+
/>
29+
{{/if}}
30+
{{yield}}
31+
{{#if this.isLinkOpenInANewWindow}}
32+
<PixIcon class="pix-navigation-button__external-icon" @ariaHidden={{true}} @name="openNew" />
33+
{{/if}}
34+
</a>
35+
{{/if}}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Component from '@glimmer/component';
2+
3+
export default class PixNavigationButton extends Component {
4+
defaultParams = {};
5+
defaultModel = [];
6+
7+
get isLinkOpenInANewWindow() {
8+
return this.args?.target === '_blank';
9+
}
10+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<hr class="pix-navigation-separator" />
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
.pix-navigation-button {
2+
@extend %pix-body-s;
3+
4+
--pix-navigation-button-bgcolor: var(--pix-neutral-100);
5+
6+
position: relative;
7+
display: flex;
8+
gap: var(--pix-spacing-2x);
9+
align-items: center;
10+
width: max-content;
11+
width: 100%;
12+
padding: var(--pix-spacing-2x) var(--pix-spacing-3x);
13+
fill: var(--pix-navigation-button-bgcolor);
14+
15+
&:focus::before,
16+
&:focus-visible::before,
17+
&.active::before,
18+
&:hover::before {
19+
position: absolute;
20+
top:0;
21+
left: 0;
22+
z-index: -1;
23+
width: 100%;
24+
height: 100%;
25+
background-color: currentcolor;
26+
border-radius: var(--pix-spacing-2x);
27+
content: '';
28+
}
29+
30+
&:hover::before {
31+
opacity: .3;
32+
}
33+
34+
&:focus, &:focus-visible {
35+
border-radius: var(--pix-spacing-2x);
36+
outline: 1px solid currentcolor ;
37+
38+
&::before{
39+
opacity: .3;
40+
}
41+
}
42+
43+
&:active::before {
44+
opacity: .5;
45+
}
46+
47+
&.active::before {
48+
opacity: .2;
49+
}
50+
51+
&.active {
52+
font-weight: var(--pix-font-bold);
53+
}
54+
55+
}
56+
57+
.pix-navigation-button__external-icon {
58+
width: 1rem;
59+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.pix-navigation-separator {
2+
@extend %pix-body-l;
3+
4+
margin: 0;
5+
height: 1.25rem;
6+
color: inherit;
7+
border: none;
8+
line-height: 1.25rem;
9+
&::after {
10+
content: '';
11+
font-weight: var(--pix-font-medium);
12+
}
13+
}

addon/styles/addon.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
@import 'trap-focus';
3737
@import 'pix-search-input';
3838
@import 'pix-navigation';
39+
@import 'pix-navigation-button';
40+
@import 'pix-navigation-separator';
3941
@import 'pix-app-layout';
4042

4143

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from '@1024pix/pix-ui/components/pix-navigation-button';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from '@1024pix/pix-ui/components/pix-navigation-separator';

app/stories/pix-navigation.stories.js

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,33 +29,22 @@ export const AppNavigation = (args) => {
2929
</a>
3030
</:brand>
3131
<:navElements>
32-
<PixButtonLink @variant='tertiary' @route='hello' class='active'><PixIcon
33-
@name='conversionPath'
34-
@ariaHidden={{true}}
35-
/>Campagnes</PixButtonLink>
36-
<PixButtonLink @variant='tertiary' @route='hello'><PixIcon
37-
@name='infoUser'
38-
@ariaHidden={{true}}
39-
/>Participants</PixButtonLink>
40-
<PixButtonLink @variant='tertiary' @route='hello'><PixIcon
41-
@name='users'
42-
@ariaHidden={{true}}
43-
/>Équipe</PixButtonLink>
44-
<PixButtonLink @variant='tertiary' @route='hello'><PixIcon
45-
@name='seat'
46-
@ariaHidden={{true}}
47-
/>Places</PixButtonLink>
48-
<PixButtonLink @variant='tertiary' @href='https://pix.fr'><PixIcon
49-
@name='book'
50-
@ariaHidden={{true}}
51-
/>Documentation</PixButtonLink>
52-
<PixButtonLink
53-
@variant='tertiary'
32+
<PixNavigationButton
33+
@route='hello'
34+
@icon='conversionPath'
35+
class='active'
36+
>Campagnes</PixNavigationButton>
37+
<PixNavigationButton @route='hello' @icon='infoUser'>Participants</PixNavigationButton>
38+
<PixNavigationButton @route='hello' @icon='users'>Équipe</PixNavigationButton>
39+
<PixNavigationButton @route='hello' @icon='seat'> Places</PixNavigationButton>
40+
<PixNavigationButton @href='https://pix.fr' @icon='book'> Documentation</PixNavigationButton>
41+
<PixNavigationButton
5442
@href='https://pix.fr'
43+
@icon='help'
5544
title='Pix.fr'
5645
target='_blank'
5746
@newWindowLabel='ouvre une nouvelle fenêtre'
58-
><PixIcon @name='help' @ariaHidden={{true}} />Centre d'aide</PixButtonLink>
47+
>Centre d'aide</PixNavigationButton>
5948
</:navElements>
6049
<:footer>
6150
<p>
@@ -68,6 +57,7 @@ export const AppNavigation = (args) => {
6857
Organisation Test Pix (UAI003)
6958
</span>
7059
</p>
60+
<PixNavigationSeparator />
7161
<PixButton @variant='primary' @iconBefore='codeNumber' @size='small'>
7262
J'ai un code
7363
</PixButton>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { module, test } from 'qunit';
2+
import { setupRenderingTest } from 'ember-qunit';
3+
import { render, within } from '@1024pix/ember-testing-library';
4+
import { hbs } from 'ember-cli-htmlbars';
5+
6+
module('Integration | Component | pix-navigation-button', function (hooks) {
7+
setupRenderingTest(hooks);
8+
hooks.beforeEach(function () {
9+
this.owner.setupRouter();
10+
});
11+
test('it renders an HTML link', async function (assert) {
12+
// when
13+
const screen = await render(
14+
hbs`<PixNavigationButton @href='https://pix.fr'>content</PixNavigationButton>`,
15+
);
16+
17+
// then
18+
const link = screen.getByRole('link', { name: 'content' });
19+
assert.strictEqual(link.getAttribute('href'), 'https://pix.fr');
20+
});
21+
22+
test('it renders an HTML link in a new window', async function (assert) {
23+
// when
24+
const screen = await render(
25+
hbs`<PixNavigationButton
26+
@href='https://pix.fr'
27+
@title='pix.fr'
28+
@target='_blank'
29+
@newWindowLabel='nouvelle fenêtre'
30+
>content</PixNavigationButton>`,
31+
);
32+
33+
// then
34+
const link = screen.getByRole('link', { name: 'content' });
35+
assert.strictEqual(link.getAttribute('title'), 'pix.fr - nouvelle fenêtre');
36+
});
37+
38+
test('it renders an EmberJS link', async function (assert) {
39+
// when
40+
const screen = await render(
41+
hbs`<PixNavigationButton @route='hello'>content</PixNavigationButton>`,
42+
);
43+
44+
// then
45+
const link = screen.getByRole('link', { name: 'content' });
46+
assert.strictEqual(link.getAttribute('href'), '/hello-world');
47+
});
48+
49+
test('it renders an EmberJS link with model', async function (assert) {
50+
// when
51+
const screen = await render(
52+
hbs`<PixNavigationButton @route='bye' @model='bye'>content</PixNavigationButton>`,
53+
);
54+
55+
// then
56+
const link = screen.getByRole('link', { name: 'content' });
57+
assert.strictEqual(link.getAttribute('href'), '/bye/bye');
58+
});
59+
60+
test('it renders an EmberJS link with model and query params', async function (assert) {
61+
// when
62+
const screen = await render(
63+
hbs`<PixNavigationButton
64+
@route='bye'
65+
@model='bye'
66+
@query={{hash page=3 per_page=20}}
67+
>content</PixNavigationButton>`,
68+
);
69+
70+
// then
71+
const link = screen.getByRole('link', { name: 'content' });
72+
assert.strictEqual(link.getAttribute('href'), '/bye/bye?page=3&per_page=20');
73+
});
74+
75+
test('it renders an icon', async function (assert) {
76+
// when
77+
const screen = await render(
78+
hbs`<PixNavigationButton @route='hello' @icon='coversionPath'>content</PixNavigationButton>`,
79+
);
80+
81+
// then
82+
const link = screen.getByRole('link', { name: 'content' });
83+
assert.ok(within(link).getByRole('img', { hidden: true }));
84+
});
85+
});

0 commit comments

Comments
 (0)