@1024pix/pix-ui 16.0.0 → 17.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/addon/components/pix-banner.hbs +30 -13
- package/addon/components/pix-banner.js +16 -0
- package/addon/components/pix-checkbox.hbs +14 -0
- package/addon/components/pix-checkbox.js +30 -0
- package/addon/components/pix-modal.hbs +8 -2
- package/addon/components/pix-modal.js +13 -0
- package/addon/styles/_colors.scss +6 -6
- package/addon/styles/_pix-banner.scss +45 -24
- package/addon/styles/_pix-checkbox.scss +77 -0
- package/addon/styles/_pix-message.scss +6 -6
- package/addon/styles/addon.scss +1 -0
- package/app/components/pix-checkbox.js +1 -0
- package/app/modifiers/on-escape-action.js +19 -0
- package/app/modifiers/trap-focus.js +52 -0
- package/app/stories/form.stories.js +4 -0
- package/app/stories/pix-banner.stories.js +16 -0
- package/app/stories/pix-banner.stories.mdx +15 -0
- package/app/stories/pix-checkbox.stories.js +88 -0
- package/app/stories/pix-checkbox.stories.mdx +50 -0
- package/app/stories/pix-modal.stories.js +13 -5
- package/app/stories/pix-modal.stories.mdx +4 -3
- package/docs/colors-palette.stories.mdx +2 -2
- package/docs/design-tokens.stories.mdx +5 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Pix-UI Changelog
|
|
2
2
|
|
|
3
|
+
## v17.1.0 (22/08/2022)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### :rocket: Amélioration
|
|
7
|
+
- [#243](https://github.com/1024pix/pix-ui/pull/243) [FEATURE] Ajout d'un icone pour fermer Pix-Banner (PIX-5379)
|
|
8
|
+
- [#244](https://github.com/1024pix/pix-ui/pull/244) [FEATURE] PixModal : ajouter des modifiers trap-focus et action au echap (PIX-5157)
|
|
9
|
+
|
|
10
|
+
## v17.0.0 (09/08/2022)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### :coffee: Autre
|
|
14
|
+
- [#239](https://github.com/1024pix/pix-ui/pull/239) [BREAKING_CHANGES][BUGFIX] Correction des couleurs du design system par rapport à Figma (PIX-5331).
|
|
15
|
+
|
|
16
|
+
## v16.1.0 (03/08/2022)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### :rocket: Amélioration
|
|
20
|
+
- [#232](https://github.com/1024pix/pix-ui/pull/232) [FEATURE] Ajout du composant checkbox (PIX-3030)
|
|
21
|
+
|
|
3
22
|
## v16.0.0 (13/07/2022)
|
|
4
23
|
|
|
5
24
|
|
|
@@ -1,16 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
{{#if this.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
{{#if this.displayBanner}}
|
|
2
|
+
<div class="pix-banner pix-banner--{{this.type}}" role="alert" ...attributes>
|
|
3
|
+
<FaIcon @icon={{this.icon}} class="pix-banner__icon" />
|
|
4
|
+
<div>
|
|
5
|
+
{{yield}}
|
|
6
|
+
{{#if this.displayAction}}
|
|
7
|
+
{{#if this.isExternalLink}}
|
|
8
|
+
<a
|
|
9
|
+
class="pix-banner__action"
|
|
10
|
+
href={{@actionUrl}}
|
|
11
|
+
target="_blank"
|
|
12
|
+
rel="noopener noreferrer"
|
|
13
|
+
>
|
|
14
|
+
{{@actionLabel}}
|
|
15
|
+
<FaIcon class="external-link" @icon="up-right-from-square" />
|
|
16
|
+
</a>
|
|
17
|
+
{{else}}
|
|
18
|
+
<LinkTo class="pix-banner__action" @route={{@actionUrl}}>{{@actionLabel}}</LinkTo>
|
|
19
|
+
{{/if}}
|
|
13
20
|
{{/if}}
|
|
21
|
+
</div>
|
|
22
|
+
{{#if this.canCloseBanner}}
|
|
23
|
+
<div class="pix-banner__close">
|
|
24
|
+
<PixIconButton
|
|
25
|
+
@ariaLabel="Fermer"
|
|
26
|
+
@icon="xmark"
|
|
27
|
+
@size="small"
|
|
28
|
+
@triggerAction={{this.closeBanner}}
|
|
29
|
+
/>
|
|
30
|
+
</div>
|
|
14
31
|
{{/if}}
|
|
15
32
|
</div>
|
|
16
|
-
|
|
33
|
+
{{/if}}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import Component from '@glimmer/component';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { action } from '@ember/object';
|
|
2
4
|
const TYPE_INFO = 'information';
|
|
3
5
|
const TYPE_ERROR = 'error';
|
|
4
6
|
const TYPE_WARNING = 'warning';
|
|
@@ -25,6 +27,7 @@ const icons = {
|
|
|
25
27
|
};
|
|
26
28
|
|
|
27
29
|
export default class PixBanner extends Component {
|
|
30
|
+
@tracked isBannerVisible = true;
|
|
28
31
|
get type() {
|
|
29
32
|
return types.includes(this.args.type) ? this.args.type : TYPE_INFO;
|
|
30
33
|
}
|
|
@@ -40,4 +43,17 @@ export default class PixBanner extends Component {
|
|
|
40
43
|
get isExternalLink() {
|
|
41
44
|
return this.args.actionUrl.includes('/');
|
|
42
45
|
}
|
|
46
|
+
|
|
47
|
+
get canCloseBanner() {
|
|
48
|
+
return this.args.canCloseBanner;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
get displayBanner() {
|
|
52
|
+
return this.isBannerVisible;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@action
|
|
56
|
+
closeBanner() {
|
|
57
|
+
this.isBannerVisible = false;
|
|
58
|
+
}
|
|
43
59
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<div class="pix-checkbox">
|
|
2
|
+
<label
|
|
3
|
+
class="pix-checkbox__label {{this.labelSizeClass}} {{if @screenReaderOnly 'sr-only'}}"
|
|
4
|
+
for={{this.id}}
|
|
5
|
+
>
|
|
6
|
+
{{this.label}}
|
|
7
|
+
</label>
|
|
8
|
+
<input
|
|
9
|
+
id={{this.id}}
|
|
10
|
+
type="checkbox"
|
|
11
|
+
class="pix-checkbox__input {{if @isIndeterminate ' pix-checkbox__input--indeterminate'}}"
|
|
12
|
+
...attributes
|
|
13
|
+
/>
|
|
14
|
+
</div>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { htmlSafe } from '@ember/string';
|
|
3
|
+
|
|
4
|
+
const labelSizeToClass = new Map([
|
|
5
|
+
['small', 'pix-checkbox__label--small'],
|
|
6
|
+
['default', 'pix-checkbox__label--default'],
|
|
7
|
+
['large', 'pix-checkbox__label--large'],
|
|
8
|
+
]);
|
|
9
|
+
|
|
10
|
+
export default class PixCheckbox extends Component {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
|
|
14
|
+
if (!this.args.label) {
|
|
15
|
+
throw new Error('ERROR in PixCheckbox component, you must provide @label params');
|
|
16
|
+
}
|
|
17
|
+
this.label = htmlSafe(this.args.label);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get id() {
|
|
21
|
+
if (!this.args.id || !this.args.id.toString().trim()) {
|
|
22
|
+
throw new Error('ERROR in PixCheckbox component, @id param is not provided');
|
|
23
|
+
}
|
|
24
|
+
return this.args.id;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get labelSizeClass() {
|
|
28
|
+
return labelSizeToClass.get(this.args.labelSize);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -1,17 +1,23 @@
|
|
|
1
|
-
<div
|
|
1
|
+
<div
|
|
2
|
+
class="pix-modal__overlay"
|
|
3
|
+
{{on "click" this.closeAction}}
|
|
4
|
+
{{trap-focus}}
|
|
5
|
+
{{on-escape-action this.closeAction}}
|
|
6
|
+
>
|
|
2
7
|
<div
|
|
3
8
|
class="pix-modal"
|
|
4
9
|
role="dialog"
|
|
5
10
|
aria-labelledby="modal-title"
|
|
6
11
|
aria-describedby="modal-content"
|
|
7
12
|
aria-modal="true"
|
|
13
|
+
{{on "click" this.stopPropagation}}
|
|
8
14
|
...attributes
|
|
9
15
|
>
|
|
10
16
|
<header class="pix-modal__header">
|
|
11
17
|
<h1 id="modal-title" class="pix-modal__title">{{@title}}</h1>
|
|
12
18
|
<PixIconButton
|
|
13
19
|
@icon="xmark"
|
|
14
|
-
@triggerAction={{
|
|
20
|
+
@triggerAction={{this.closeAction}}
|
|
15
21
|
@ariaLabel="Fermer"
|
|
16
22
|
@size="small"
|
|
17
23
|
@withBackground={{true}}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Component from '@glimmer/component';
|
|
2
|
+
import { action } from '@ember/object';
|
|
2
3
|
|
|
3
4
|
export default class PixModal extends Component {
|
|
4
5
|
constructor(...args) {
|
|
@@ -8,4 +9,16 @@ export default class PixModal extends Component {
|
|
|
8
9
|
throw new Error('ERROR in PixModal component: @title argument is required.');
|
|
9
10
|
}
|
|
10
11
|
}
|
|
12
|
+
|
|
13
|
+
@action
|
|
14
|
+
stopPropagation(event) {
|
|
15
|
+
event.stopPropagation();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@action
|
|
19
|
+
closeAction(params) {
|
|
20
|
+
if (this.args.onCloseButtonClick) {
|
|
21
|
+
this.args.onCloseButtonClick(params);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
11
24
|
}
|
|
@@ -14,7 +14,7 @@ $pix-primary-80: #000e87;
|
|
|
14
14
|
|
|
15
15
|
// Secondary
|
|
16
16
|
$pix-secondary-5: #fff9e6;
|
|
17
|
-
$pix-secondary-10: #
|
|
17
|
+
$pix-secondary-10: #fff1c5;
|
|
18
18
|
$pix-secondary-20: #ffe381;
|
|
19
19
|
$pix-secondary: #ffd235;
|
|
20
20
|
$pix-secondary-40: #ffbe00;
|
|
@@ -75,7 +75,7 @@ $pix-warning-30: #ffd235;
|
|
|
75
75
|
$pix-warning-40: #ffbe00;
|
|
76
76
|
$pix-warning-50: #eaa600;
|
|
77
77
|
$pix-warning-60: #ce8900;
|
|
78
|
-
$pix-warning-70: #
|
|
78
|
+
$pix-warning-70: #a95800;
|
|
79
79
|
$pix-warning-80: #874d00;
|
|
80
80
|
|
|
81
81
|
// Error
|
|
@@ -489,20 +489,20 @@ $yellow-alert-dark: #a95800;
|
|
|
489
489
|
/**
|
|
490
490
|
* @deprecated
|
|
491
491
|
*-To style text or border : $pix-error-70
|
|
492
|
-
*-To style background : $pix-error-
|
|
492
|
+
*-To style background : $pix-error-5
|
|
493
493
|
*/
|
|
494
494
|
$error: #ff4b00;
|
|
495
495
|
|
|
496
496
|
/**
|
|
497
497
|
* @deprecated
|
|
498
498
|
*-To style text or border : $pix-success-70
|
|
499
|
-
*-To style background : $pix-success-
|
|
499
|
+
*-To style background : $pix-success-5
|
|
500
500
|
*/
|
|
501
501
|
$success: #57c884;
|
|
502
502
|
|
|
503
503
|
/**
|
|
504
504
|
* @deprecated
|
|
505
|
-
*-To style text or border : $pix-warning-
|
|
506
|
-
*-To style background : $pix-warning-
|
|
505
|
+
*-To style text or border : $pix-warning-70
|
|
506
|
+
*-To style background : $pix-warning-5
|
|
507
507
|
*/
|
|
508
508
|
$warning: #ffbe00;
|
|
@@ -2,52 +2,73 @@
|
|
|
2
2
|
@import 'reset-css';
|
|
3
3
|
font-family: $font-roboto;
|
|
4
4
|
font-weight: $font-normal;
|
|
5
|
-
padding:
|
|
5
|
+
padding: 16px 24px;
|
|
6
6
|
display: flex;
|
|
7
7
|
align-items: center;
|
|
8
|
-
font-size: 0.
|
|
9
|
-
|
|
10
|
-
@include device-is('tablet') {
|
|
11
|
-
padding: 20px 60px;
|
|
12
|
-
font-size: 0.875rem;
|
|
13
|
-
}
|
|
8
|
+
font-size: 0.875rem;
|
|
9
|
+
box-shadow: 0px 4px 8px rgba(7, 20, 46, 0.08);
|
|
14
10
|
|
|
15
11
|
&__action {
|
|
16
12
|
text-decoration: underline;
|
|
17
|
-
letter-spacing: 0.028rem;
|
|
18
13
|
color: inherit;
|
|
19
14
|
.external-link {
|
|
20
|
-
margin-left:
|
|
21
|
-
font-size: 0.
|
|
22
|
-
|
|
23
|
-
@include device-is('tablet') {
|
|
24
|
-
font-size: 0.875rem;
|
|
25
|
-
}
|
|
15
|
+
margin-left: 4px;
|
|
16
|
+
font-size: 0.875rem;
|
|
26
17
|
}
|
|
27
18
|
}
|
|
28
|
-
|
|
19
|
+
&__close {
|
|
20
|
+
display: flex;
|
|
21
|
+
margin-left: auto;
|
|
22
|
+
padding-left: 8px;
|
|
23
|
+
}
|
|
29
24
|
&__icon {
|
|
30
|
-
font-size:
|
|
25
|
+
font-size: 1.125rem;
|
|
31
26
|
margin-right: $spacing-xs;
|
|
32
|
-
|
|
33
|
-
@include device-is('tablet') {
|
|
34
|
-
font-size: 1rem;
|
|
35
|
-
}
|
|
36
27
|
}
|
|
37
28
|
|
|
38
29
|
&--information {
|
|
39
|
-
background-color: $pix-primary-
|
|
30
|
+
background-color: $pix-primary-5;
|
|
40
31
|
color: $pix-primary-70;
|
|
32
|
+
.pix-icon-button {
|
|
33
|
+
background-color: $pix-primary-5;
|
|
34
|
+
color: $pix-primary-70;
|
|
35
|
+
&:hover,
|
|
36
|
+
&:focus,
|
|
37
|
+
&:active {
|
|
38
|
+
background-color: $pix-primary-10;
|
|
39
|
+
color: $pix-primary-70;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
&--warning {
|
|
44
|
-
background-color: $pix-warning-
|
|
45
|
-
color: $pix-warning-
|
|
45
|
+
background-color: $pix-warning-5;
|
|
46
|
+
color: $pix-warning-70;
|
|
47
|
+
.pix-icon-button {
|
|
48
|
+
background-color: $pix-warning-5;
|
|
49
|
+
color: $pix-warning-70;
|
|
50
|
+
&:hover,
|
|
51
|
+
&:focus,
|
|
52
|
+
&:active {
|
|
53
|
+
background-color: $pix-warning-10;
|
|
54
|
+
color: $pix-warning-70;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
46
57
|
}
|
|
47
58
|
|
|
48
59
|
&--error {
|
|
49
|
-
background-color: $pix-error-
|
|
60
|
+
background-color: $pix-error-5;
|
|
50
61
|
color: $pix-error-70;
|
|
62
|
+
.pix-icon-button {
|
|
63
|
+
background-color: $pix-error-5;
|
|
64
|
+
color: $pix-error-70;
|
|
65
|
+
&:hover,
|
|
66
|
+
&:focus,
|
|
67
|
+
&:active {
|
|
68
|
+
background-color: $pix-error-10;
|
|
69
|
+
color: $pix-error-70;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
51
72
|
}
|
|
52
73
|
|
|
53
74
|
&--communication {
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
.pix-checkbox {
|
|
2
|
+
@import 'reset-css';
|
|
3
|
+
display: flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: row-reverse;
|
|
7
|
+
|
|
8
|
+
label, input {
|
|
9
|
+
cursor: pointer;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
&__label {
|
|
13
|
+
color: $pix-neutral-70;
|
|
14
|
+
@include text;
|
|
15
|
+
|
|
16
|
+
&--small {
|
|
17
|
+
@include text-small;
|
|
18
|
+
}
|
|
19
|
+
&--default {
|
|
20
|
+
@include text;
|
|
21
|
+
}
|
|
22
|
+
&--large {
|
|
23
|
+
@include text-large;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&__input {
|
|
28
|
+
appearance: none;
|
|
29
|
+
margin: 0 10px;
|
|
30
|
+
min-width: 18px;
|
|
31
|
+
min-height: 18px;
|
|
32
|
+
border: 1.2px solid $pix-neutral-90;
|
|
33
|
+
border-radius: 2px;
|
|
34
|
+
display: flex;
|
|
35
|
+
justify-content: center;
|
|
36
|
+
align-items: center;
|
|
37
|
+
|
|
38
|
+
&:hover, &:focus {
|
|
39
|
+
box-shadow: inset 0 1px 3px rgba(0,0,0, .1), 0 0 0 6px $pix-neutral-15;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&:active {
|
|
43
|
+
box-shadow: inset 0 1px 3px rgba(0,0,0, .1), 0 0 0 6px $pix-neutral-22;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&:checked {
|
|
47
|
+
background: $pix-primary border-box;
|
|
48
|
+
border-color: $pix-primary;
|
|
49
|
+
|
|
50
|
+
&::after {
|
|
51
|
+
content: '';
|
|
52
|
+
background-image: url("data:image/svg+xml,%3Csvg width='13' height='10' viewBox='0 0 13 10' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1.5 3L0 4.5L5 9.5L13 1.5L11.5 0L5 6.5L1.5 3Z' fill='white'/%3E%3C/svg%3E%0A");
|
|
53
|
+
background-repeat: no-repeat;
|
|
54
|
+
background-position: center;
|
|
55
|
+
width: 16px;
|
|
56
|
+
height: 16px;
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
&.pix-checkbox__input--indeterminate {
|
|
62
|
+
&:checked {
|
|
63
|
+
background: $pix-neutral-60 border-box;
|
|
64
|
+
border-color: $pix-neutral-60;
|
|
65
|
+
|
|
66
|
+
&::after {
|
|
67
|
+
content: '';
|
|
68
|
+
background-image: url("data:image/svg+xml,%3Csvg width='10' height='2' viewBox='0 0 10 2' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='10' height='2' fill='white'/%3E%3C/svg%3E%0A");
|
|
69
|
+
background-repeat: no-repeat;
|
|
70
|
+
background-position: center;
|
|
71
|
+
width: 16px;
|
|
72
|
+
height: 16px;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -10,23 +10,23 @@
|
|
|
10
10
|
|
|
11
11
|
&.pix-message--info {
|
|
12
12
|
color: $pix-primary-70;
|
|
13
|
-
background-color: $pix-primary-
|
|
13
|
+
background-color: $pix-primary-5;
|
|
14
14
|
}
|
|
15
15
|
&.pix-message--alert {
|
|
16
16
|
color: $pix-error-70;
|
|
17
|
-
background-color: $pix-error-
|
|
17
|
+
background-color: $pix-error-5;
|
|
18
18
|
}
|
|
19
19
|
&.pix-message--error {
|
|
20
20
|
color: $pix-error-70;
|
|
21
|
-
background-color: $pix-error-
|
|
21
|
+
background-color: $pix-error-5;
|
|
22
22
|
}
|
|
23
23
|
&.pix-message--success {
|
|
24
24
|
color: $pix-success-70;
|
|
25
|
-
background-color: $pix-success-
|
|
25
|
+
background-color: $pix-success-5;
|
|
26
26
|
}
|
|
27
27
|
&.pix-message--warning {
|
|
28
|
-
color: $pix-warning-
|
|
29
|
-
background-color: $pix-warning-
|
|
28
|
+
color: $pix-warning-70;
|
|
29
|
+
background-color: $pix-warning-5;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
svg {
|
package/addon/styles/addon.scss
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@1024pix/pix-ui/components/pix-checkbox';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { modifier } from 'ember-modifier';
|
|
2
|
+
|
|
3
|
+
export default modifier((element, [callback]) => {
|
|
4
|
+
function handleKeyUp(event) {
|
|
5
|
+
const TAB_KEY = 'Escape';
|
|
6
|
+
|
|
7
|
+
if (event.key !== TAB_KEY) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
callback(event);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
element.addEventListener('keyup', handleKeyUp);
|
|
15
|
+
|
|
16
|
+
return () => {
|
|
17
|
+
element.removeEventListener('keyup', handleKeyUp);
|
|
18
|
+
};
|
|
19
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { modifier } from 'ember-modifier';
|
|
2
|
+
|
|
3
|
+
export default modifier(function trapFocus(element) {
|
|
4
|
+
const [firstFocusableElement] = findFocusableElements(element);
|
|
5
|
+
|
|
6
|
+
firstFocusableElement.focus();
|
|
7
|
+
|
|
8
|
+
function handleKeyDown(event) {
|
|
9
|
+
const TAB_KEY = 9;
|
|
10
|
+
const focusableElements = findFocusableElements(element);
|
|
11
|
+
const [firstFocusableElement] = focusableElements;
|
|
12
|
+
const lastFocusableElement = focusableElements[focusableElements.length - 1];
|
|
13
|
+
|
|
14
|
+
if (event.keyCode !== TAB_KEY) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function handleBackwardTab() {
|
|
19
|
+
if (document.activeElement === firstFocusableElement) {
|
|
20
|
+
event.preventDefault();
|
|
21
|
+
lastFocusableElement.focus();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function handleForwardTab() {
|
|
26
|
+
if (document.activeElement === lastFocusableElement) {
|
|
27
|
+
event.preventDefault();
|
|
28
|
+
firstFocusableElement.focus();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (event.shiftKey) {
|
|
33
|
+
handleBackwardTab();
|
|
34
|
+
} else {
|
|
35
|
+
handleForwardTab();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
element.addEventListener('keydown', handleKeyDown);
|
|
40
|
+
|
|
41
|
+
return () => {
|
|
42
|
+
element.removeEventListener('keydown', handleKeyDown);
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
function findFocusableElements(element) {
|
|
47
|
+
return [
|
|
48
|
+
...element.querySelectorAll(
|
|
49
|
+
'a[href], button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])'
|
|
50
|
+
),
|
|
51
|
+
].filter((el) => !el.hasAttribute('disabled') && !el.getAttribute('aria-hidden'));
|
|
52
|
+
}
|
|
@@ -67,6 +67,10 @@ export const form = (args) => {
|
|
|
67
67
|
/>
|
|
68
68
|
<br>
|
|
69
69
|
|
|
70
|
+
<PixCheckbox @id="spam-pub" @labelSize="small" @label="Acceptez-vous de vous faire spammer de PUB ?" />
|
|
71
|
+
|
|
72
|
+
<br><br>
|
|
73
|
+
|
|
70
74
|
<div class="pix-form__actions">
|
|
71
75
|
<PixButton @triggerAction={{cancel}} @backgroundColor="transparent-light" @isBorderVisible={{true}}>
|
|
72
76
|
Annuler
|
|
@@ -7,6 +7,7 @@ const Template = (args) => {
|
|
|
7
7
|
@type={{type}}
|
|
8
8
|
@actionLabel={{actionLabel}}
|
|
9
9
|
@actionUrl={{actionUrl}}
|
|
10
|
+
@canCloseBanner={{canCloseBanner}}
|
|
10
11
|
>
|
|
11
12
|
Parcours de rentrée 2020 : les codes sont disponibles dans l'onglet campagne. N’oubliez pas de les diffuser aux élèves avant la Toussaint.
|
|
12
13
|
</PixBanner>
|
|
@@ -56,6 +57,12 @@ withInternalLink.args = {
|
|
|
56
57
|
actionUrl: 'campaign.list',
|
|
57
58
|
};
|
|
58
59
|
|
|
60
|
+
export const withCloseIcon = Template.bind({});
|
|
61
|
+
withCloseIcon.args = {
|
|
62
|
+
type: 'info',
|
|
63
|
+
canCloseBanner: true,
|
|
64
|
+
};
|
|
65
|
+
|
|
59
66
|
export const argsTypes = {
|
|
60
67
|
actionLabel: {
|
|
61
68
|
name: 'actionLabel',
|
|
@@ -86,4 +93,13 @@ export const argsTypes = {
|
|
|
86
93
|
],
|
|
87
94
|
},
|
|
88
95
|
},
|
|
96
|
+
canCloseBanner: {
|
|
97
|
+
name: 'canCloseBanner',
|
|
98
|
+
description: 'Afficher la croix pour fermer la bannière',
|
|
99
|
+
type: { name: 'boolean', required: false },
|
|
100
|
+
table: {
|
|
101
|
+
type: { summary: 'boolean' },
|
|
102
|
+
defaultValue: { summary: false },
|
|
103
|
+
},
|
|
104
|
+
},
|
|
89
105
|
};
|
|
@@ -67,6 +67,14 @@ Bannière contenant un lien externe.
|
|
|
67
67
|
<Story name="With external link" story={stories.withExternalLink} height={100} />
|
|
68
68
|
</Canvas>
|
|
69
69
|
|
|
70
|
+
## With Close Icon
|
|
71
|
+
|
|
72
|
+
Bannière contenant un bouton qui permet de fermer la bannière.
|
|
73
|
+
|
|
74
|
+
<Canvas>
|
|
75
|
+
<Story name="With close icon" story={stories.withCloseIcon} height={100} />
|
|
76
|
+
</Canvas>
|
|
77
|
+
|
|
70
78
|
## Usage
|
|
71
79
|
|
|
72
80
|
```html
|
|
@@ -100,6 +108,13 @@ Bannière Info par défaut
|
|
|
100
108
|
Bannière avec une route externe
|
|
101
109
|
</PixBanner>
|
|
102
110
|
|
|
111
|
+
<PixBanner
|
|
112
|
+
@type='warning'
|
|
113
|
+
@canCloseBanner=true
|
|
114
|
+
>
|
|
115
|
+
Bannière posséndant un bouton de fermeture
|
|
116
|
+
</PixBanner>
|
|
117
|
+
|
|
103
118
|
```
|
|
104
119
|
|
|
105
120
|
## Arguments
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { hbs } from 'ember-cli-htmlbars';
|
|
2
|
+
|
|
3
|
+
export const Template = (args) => {
|
|
4
|
+
return {
|
|
5
|
+
template: hbs`
|
|
6
|
+
<PixCheckbox
|
|
7
|
+
@id={{id}}
|
|
8
|
+
@label={{label}}
|
|
9
|
+
@screenReaderOnly={{screenReaderOnly}}
|
|
10
|
+
@isIndeterminate={{isIndeterminate}}
|
|
11
|
+
@labelSize={{labelSize}}
|
|
12
|
+
/>
|
|
13
|
+
`,
|
|
14
|
+
context: args,
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const Default = Template.bind({});
|
|
19
|
+
Default.args = {
|
|
20
|
+
id: 'acceptNewsletter',
|
|
21
|
+
label: 'Recevoir la newsletter',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const indeterminateCheckbox = Template.bind({});
|
|
25
|
+
indeterminateCheckbox.args = {
|
|
26
|
+
id: 'acceptNewsletter2',
|
|
27
|
+
label: 'Recevoir la newsletter',
|
|
28
|
+
isIndeterminate: true,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const checkboxWithSmallLabel = Template.bind({});
|
|
32
|
+
checkboxWithSmallLabel.args = {
|
|
33
|
+
id: 'acceptNewsletter2',
|
|
34
|
+
label: 'Recevoir la newsletter',
|
|
35
|
+
labelSize: 'small',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const checkboxWithLargeLabel = Template.bind({});
|
|
39
|
+
checkboxWithLargeLabel.args = {
|
|
40
|
+
id: 'acceptNewsletter2',
|
|
41
|
+
label: 'Recevoir la newsletter',
|
|
42
|
+
labelSize: 'large',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const argTypes = {
|
|
46
|
+
id: {
|
|
47
|
+
name: 'id',
|
|
48
|
+
description: 'Identifiant du champ permettant de lui attacher un label',
|
|
49
|
+
type: { name: 'string', required: true },
|
|
50
|
+
defaultValue: null,
|
|
51
|
+
},
|
|
52
|
+
label: {
|
|
53
|
+
name: 'label',
|
|
54
|
+
description: "Le label de l'input",
|
|
55
|
+
type: { name: 'string', required: false },
|
|
56
|
+
defaultValue: null,
|
|
57
|
+
},
|
|
58
|
+
screenReaderOnly: {
|
|
59
|
+
name: 'screenReaderOnly',
|
|
60
|
+
description:
|
|
61
|
+
"Permet de ne pas afficher le label à l'écran. Sert à garder un label qui sera lisible par les lecteurs d'écran.",
|
|
62
|
+
type: { name: 'boolean', required: true },
|
|
63
|
+
table: {
|
|
64
|
+
type: { summary: 'boolean' },
|
|
65
|
+
defaultValue: { summary: false },
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
isIndeterminate: {
|
|
69
|
+
name: 'isIndeterminate',
|
|
70
|
+
description:
|
|
71
|
+
"Rendre la checkbox indéterminée, état indiquant que la/les case(s) n'est/ne sont ni cochée(s) ni décochée(s) (exemple: une checkbox parente indiquant la sélection partielle de plusieurs checkbox enfants)",
|
|
72
|
+
type: { name: 'boolean', required: true },
|
|
73
|
+
table: {
|
|
74
|
+
type: { summary: 'boolean' },
|
|
75
|
+
defaultValue: { summary: false },
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
labelSize: {
|
|
79
|
+
name: 'labelSize',
|
|
80
|
+
description: 'Correspond à la taille de la police du label.',
|
|
81
|
+
type: { name: 'string', required: false },
|
|
82
|
+
defaultValue: { summary: 'default' },
|
|
83
|
+
control: {
|
|
84
|
+
type: 'select',
|
|
85
|
+
options: ['small', 'default', 'large'],
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import centered from '@storybook/addon-centered/ember';
|
|
3
|
+
|
|
4
|
+
import * as stories from './pix-checkbox.stories.js';
|
|
5
|
+
|
|
6
|
+
<Meta
|
|
7
|
+
title='Form/Checkbox'
|
|
8
|
+
component='PixCheckbox'
|
|
9
|
+
decorators={[centered]}
|
|
10
|
+
argTypes={stories.argTypes}
|
|
11
|
+
/>
|
|
12
|
+
|
|
13
|
+
# PixCheckbox
|
|
14
|
+
|
|
15
|
+
La PixCheckbox permet de créer des checkbox basiques ou des checkbox mixées (checkbox servant d'indicateur lors d'une sélection multiple).
|
|
16
|
+
|
|
17
|
+
<Canvas>
|
|
18
|
+
<Story name='Default' story={stories.Default} height={60} />
|
|
19
|
+
</Canvas>
|
|
20
|
+
|
|
21
|
+
## Checkbox indéterminée
|
|
22
|
+
<Canvas>
|
|
23
|
+
<Story name='Indeterminate' story={stories.indeterminateCheckbox} height={60} />
|
|
24
|
+
</Canvas>
|
|
25
|
+
|
|
26
|
+
## Checkbox avec un petit label
|
|
27
|
+
<Canvas>
|
|
28
|
+
<Story name='SmallLabel' story={stories.checkboxWithSmallLabel} height={60} />
|
|
29
|
+
</Canvas>
|
|
30
|
+
|
|
31
|
+
## Checkbox avec un grand label
|
|
32
|
+
<Canvas>
|
|
33
|
+
<Story name='LargeLabel' story={stories.checkboxWithLargeLabel} height={60} />
|
|
34
|
+
</Canvas>
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
```html
|
|
39
|
+
<PixCheckbox
|
|
40
|
+
@id="superId"
|
|
41
|
+
@label="Recevoir la newsletter"
|
|
42
|
+
@screenReaderOnly={{false}}
|
|
43
|
+
@isIndeterminate={{false}}
|
|
44
|
+
@labelSize="small"
|
|
45
|
+
/>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Arguments
|
|
49
|
+
|
|
50
|
+
<ArgsTable story="Default" />
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { hbs } from 'ember-cli-htmlbars';
|
|
2
2
|
|
|
3
|
-
export const
|
|
3
|
+
export const Template = (args) => {
|
|
4
4
|
return {
|
|
5
5
|
template: hbs`
|
|
6
|
-
<PixModal @title={{this.title}}>
|
|
6
|
+
<PixModal @title={{this.title}} @onCloseButtonClick={{onCloseButtonClick}}>
|
|
7
7
|
<:content>
|
|
8
8
|
<p>
|
|
9
9
|
Une fenêtre modale est, dans une interface graphique, une fenêtre qui prend le contrôle total du clavier et
|
|
@@ -24,16 +24,24 @@ export const modal = (args) => {
|
|
|
24
24
|
};
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
+
export const Default = Template.bind({});
|
|
28
|
+
Default.args = {
|
|
29
|
+
title: "Qu'est-ce qu'une modale ?",
|
|
30
|
+
onCloseButtonClick: () => {
|
|
31
|
+
alert('Action : fermer modale');
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
27
35
|
export const argTypes = {
|
|
28
36
|
title: {
|
|
29
37
|
name: 'title',
|
|
30
38
|
description: 'Titre de la modale',
|
|
31
|
-
type: { name: 'string', required:
|
|
32
|
-
defaultValue:
|
|
39
|
+
type: { name: 'string', required: true },
|
|
40
|
+
defaultValue: null,
|
|
33
41
|
},
|
|
34
42
|
onCloseButtonClick: {
|
|
35
43
|
name: 'onCloseButtonClick',
|
|
36
|
-
description: 'Fonction à
|
|
44
|
+
description: 'Fonction à exécuter à la fermeture de la modale',
|
|
37
45
|
type: { name: 'function', required: true },
|
|
38
46
|
defaultValue: null,
|
|
39
47
|
},
|
|
@@ -4,8 +4,8 @@ import centered from '@storybook/addon-centered/ember';
|
|
|
4
4
|
import * as stories from './pix-modal.stories.js';
|
|
5
5
|
|
|
6
6
|
<Meta
|
|
7
|
-
title=
|
|
8
|
-
component=
|
|
7
|
+
title="Basics/Modal"
|
|
8
|
+
component="PixModal"
|
|
9
9
|
decorators={[centered]}
|
|
10
10
|
argTypes={stories.argTypes}
|
|
11
11
|
/>
|
|
@@ -15,13 +15,14 @@ import * as stories from './pix-modal.stories.js';
|
|
|
15
15
|
Une fenêtre modale responsive et scrollable avec un overlay.
|
|
16
16
|
|
|
17
17
|
Ce composant possède deux `yield` :
|
|
18
|
+
|
|
18
19
|
- `:content` est destiné à accueillir le contenu principal de la fenêtre modale. Il peut accueillir tout type de
|
|
19
20
|
contenu HTML (simple texte, image, formulaire, etc.)
|
|
20
21
|
- `:footer` peut également accueillir tout type de contenu HTML, mais est destiné aux boutons permettant d'interagir
|
|
21
22
|
avec la modale, ce qui permettra de les positionner correctement dans tous les cas de figure.
|
|
22
23
|
|
|
23
24
|
<Canvas>
|
|
24
|
-
<Story name=
|
|
25
|
+
<Story name="Default" story={stories.Default} height={500} />
|
|
25
26
|
</Canvas>
|
|
26
27
|
|
|
27
28
|
## Usage
|
|
@@ -33,7 +33,7 @@ import { Meta, ColorPalette, ColorItem } from '@storybook/addon-docs';
|
|
|
33
33
|
title="Pix Secondary"
|
|
34
34
|
subtitle="$pix-secondary-"
|
|
35
35
|
colors={{ 5: '#fff9e6',
|
|
36
|
-
10: '#
|
|
36
|
+
10: '#fff1c5',
|
|
37
37
|
20: '#ffe381',
|
|
38
38
|
Secondary: '#ffd235',
|
|
39
39
|
40: '#ffbe00',
|
|
@@ -104,7 +104,7 @@ import { Meta, ColorPalette, ColorItem } from '@storybook/addon-docs';
|
|
|
104
104
|
40: '#ffbe00',
|
|
105
105
|
50: '#eaa600',
|
|
106
106
|
60: '#ce8900',
|
|
107
|
-
70: '#
|
|
107
|
+
70: '#a95800',
|
|
108
108
|
80: '#874d00'}}
|
|
109
109
|
/>
|
|
110
110
|
<ColorItem
|
|
@@ -38,23 +38,23 @@ Les couleurs pour définir un état d'une alerte ont été attribuées pour unif
|
|
|
38
38
|
### Success
|
|
39
39
|
```
|
|
40
40
|
Texte ou bordure : $pix-success-70
|
|
41
|
-
Background : $pix-success-
|
|
41
|
+
Background : $pix-success-5
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
### Warning
|
|
45
45
|
```
|
|
46
|
-
Texte ou bordure : $pix-warning-
|
|
47
|
-
Background : $pix-warning-
|
|
46
|
+
Texte ou bordure : $pix-warning-70
|
|
47
|
+
Background : $pix-warning-5
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
### Error
|
|
51
51
|
```
|
|
52
52
|
Texte ou bordure : $pix-error-70
|
|
53
|
-
Background : $pix-error-
|
|
53
|
+
Background : $pix-error-5
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
### Information
|
|
57
57
|
```
|
|
58
58
|
Texte ou bordure : $pix-primary-70
|
|
59
|
-
Background : $pix-primary-
|
|
59
|
+
Background : $pix-primary-5
|
|
60
60
|
```
|