@1024pix/pix-ui 11.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/.buildpacks +2 -0
- package/.circleci/config.yml +22 -0
- package/.gitattributes +7 -0
- package/.github/workflows/auto-merge.yml +26 -0
- package/.github/workflows/deploy-storybook.yml +21 -0
- package/.github/workflows/npm-publish.yml +23 -0
- package/.github/workflows/on-dev-merge.yml +33 -0
- package/.nvmrc +1 -0
- package/.prettierignore +1 -0
- package/.prettierrc.json +12 -0
- package/.storybook/fonts.css +1 -0
- package/.storybook/main.js +10 -0
- package/.storybook/manager.js +6 -0
- package/.storybook/preview.js +37 -0
- package/.storybook/storybook-custom-theme.js +37 -0
- package/CHANGELOG.md +469 -0
- package/CNAME +1 -0
- package/LICENSE.md +9 -0
- package/README.md +58 -0
- package/addon/components/pix-background-header.hbs +7 -0
- package/addon/components/pix-background-header.js +5 -0
- package/addon/components/pix-banner.hbs +16 -0
- package/addon/components/pix-banner.js +43 -0
- package/addon/components/pix-block.hbs +5 -0
- package/addon/components/pix-block.js +11 -0
- package/addon/components/pix-button-base.js +27 -0
- package/addon/components/pix-button-link.hbs +16 -0
- package/addon/components/pix-button-link.js +10 -0
- package/addon/components/pix-button-upload.hbs +11 -0
- package/addon/components/pix-button-upload.js +20 -0
- package/addon/components/pix-button.hbs +43 -0
- package/addon/components/pix-button.js +54 -0
- package/addon/components/pix-collapsible.hbs +29 -0
- package/addon/components/pix-collapsible.js +27 -0
- package/addon/components/pix-filter-banner.hbs +28 -0
- package/addon/components/pix-filter-banner.js +13 -0
- package/addon/components/pix-icon-button.hbs +11 -0
- package/addon/components/pix-icon-button.js +33 -0
- package/addon/components/pix-input-code.hbs +24 -0
- package/addon/components/pix-input-code.js +133 -0
- package/addon/components/pix-input-password.hbs +43 -0
- package/addon/components/pix-input-password.js +34 -0
- package/addon/components/pix-input.hbs +30 -0
- package/addon/components/pix-input.js +26 -0
- package/addon/components/pix-message.hbs +8 -0
- package/addon/components/pix-message.js +30 -0
- package/addon/components/pix-multi-select.hbs +70 -0
- package/addon/components/pix-multi-select.js +162 -0
- package/addon/components/pix-progress-gauge.hbs +19 -0
- package/addon/components/pix-progress-gauge.js +29 -0
- package/addon/components/pix-radio-button.hbs +12 -0
- package/addon/components/pix-radio-button.js +5 -0
- package/addon/components/pix-return-to.hbs +15 -0
- package/addon/components/pix-return-to.js +20 -0
- package/addon/components/pix-select.hbs +55 -0
- package/addon/components/pix-select.js +58 -0
- package/addon/components/pix-selectable-tag.hbs +10 -0
- package/addon/components/pix-selectable-tag.js +13 -0
- package/addon/components/pix-stars.hbs +16 -0
- package/addon/components/pix-stars.js +27 -0
- package/addon/components/pix-tag.hbs +3 -0
- package/addon/components/pix-tag.js +11 -0
- package/addon/components/pix-textarea.hbs +21 -0
- package/addon/components/pix-textarea.js +17 -0
- package/addon/components/pix-tooltip-deprecated.hbs +18 -0
- package/addon/components/pix-tooltip-deprecated.js +26 -0
- package/addon/components/pix-tooltip.hbs +18 -0
- package/addon/components/pix-tooltip.js +17 -0
- package/addon/styles/_breakpoints.scss +17 -0
- package/addon/styles/_colors.scss +87 -0
- package/addon/styles/_fonts.scss +10 -0
- package/addon/styles/_form.scss +68 -0
- package/addon/styles/_pix-background-header.scss +20 -0
- package/addon/styles/_pix-banner.scss +67 -0
- package/addon/styles/_pix-block.scss +29 -0
- package/addon/styles/_pix-button-base.scss +137 -0
- package/addon/styles/_pix-button-link.scss +4 -0
- package/addon/styles/_pix-button-upload.scss +5 -0
- package/addon/styles/_pix-button.scss +40 -0
- package/addon/styles/_pix-collapsible.scss +82 -0
- package/addon/styles/_pix-filter-banner.scss +74 -0
- package/addon/styles/_pix-icon-button.scss +60 -0
- package/addon/styles/_pix-input-code.scss +71 -0
- package/addon/styles/_pix-input-password.scss +68 -0
- package/addon/styles/_pix-input.scss +93 -0
- package/addon/styles/_pix-message.scss +35 -0
- package/addon/styles/_pix-multi-select.scss +182 -0
- package/addon/styles/_pix-progress-gauge.scss +119 -0
- package/addon/styles/_pix-radio-button.scss +72 -0
- package/addon/styles/_pix-return-to.scss +64 -0
- package/addon/styles/_pix-select.scss +71 -0
- package/addon/styles/_pix-selectable-tag.scss +86 -0
- package/addon/styles/_pix-stars.scss +43 -0
- package/addon/styles/_pix-tag.scss +69 -0
- package/addon/styles/_pix-textarea.scss +39 -0
- package/addon/styles/_pix-tooltip.scss +196 -0
- package/addon/styles/_reset-css.scss +36 -0
- package/addon/styles/_spacing.scss +9 -0
- package/addon/styles/addon.scss +41 -0
- package/app/components/pix-background-header.js +1 -0
- package/app/components/pix-banner.js +1 -0
- package/app/components/pix-block.js +1 -0
- package/app/components/pix-button-link.js +1 -0
- package/app/components/pix-button-upload.js +1 -0
- package/app/components/pix-button.js +1 -0
- package/app/components/pix-collapsible.js +1 -0
- package/app/components/pix-filter-banner.js +1 -0
- package/app/components/pix-icon-button.js +1 -0
- package/app/components/pix-input-code.js +1 -0
- package/app/components/pix-input-password.js +1 -0
- package/app/components/pix-input.js +1 -0
- package/app/components/pix-message.js +1 -0
- package/app/components/pix-multi-select.js +1 -0
- package/app/components/pix-progress-gauge.js +1 -0
- package/app/components/pix-radio-button.js +1 -0
- package/app/components/pix-return-to.js +1 -0
- package/app/components/pix-select.js +1 -0
- package/app/components/pix-selectable-tag.js +1 -0
- package/app/components/pix-stars.js +1 -0
- package/app/components/pix-tag.js +1 -0
- package/app/components/pix-textarea.js +1 -0
- package/app/components/pix-tooltip-deprecated.js +1 -0
- package/app/components/pix-tooltip.js +1 -0
- package/app/stories/form.stories.js +91 -0
- package/app/stories/form.stories.mdx +16 -0
- package/app/stories/pix-background-header.stories.js +19 -0
- package/app/stories/pix-background-header.stories.mdx +36 -0
- package/app/stories/pix-banner.stories.js +89 -0
- package/app/stories/pix-banner.stories.mdx +107 -0
- package/app/stories/pix-block.stories.js +20 -0
- package/app/stories/pix-block.stories.mdx +44 -0
- package/app/stories/pix-button-link.stories.js +125 -0
- package/app/stories/pix-button-link.stories.mdx +57 -0
- package/app/stories/pix-button-upload.stories.js +85 -0
- package/app/stories/pix-button-upload.stories.mdx +39 -0
- package/app/stories/pix-button.stories.js +253 -0
- package/app/stories/pix-button.stories.mdx +99 -0
- package/app/stories/pix-collapsible.stories.js +56 -0
- package/app/stories/pix-collapsible.stories.mdx +39 -0
- package/app/stories/pix-filter-banner.stories.js +51 -0
- package/app/stories/pix-filter-banner.stories.mdx +33 -0
- package/app/stories/pix-icon-button.stories.js +95 -0
- package/app/stories/pix-icon-button.stories.mdx +90 -0
- package/app/stories/pix-input-code.stories.js +74 -0
- package/app/stories/pix-input-code.stories.mdx +46 -0
- package/app/stories/pix-input-password.stories.js +89 -0
- package/app/stories/pix-input-password.stories.mdx +69 -0
- package/app/stories/pix-input.stories.js +94 -0
- package/app/stories/pix-input.stories.mdx +57 -0
- package/app/stories/pix-message.stories.js +57 -0
- package/app/stories/pix-message.stories.mdx +71 -0
- package/app/stories/pix-multi-select.stories.js +199 -0
- package/app/stories/pix-multi-select.stories.mdx +55 -0
- package/app/stories/pix-progress-gauge.stories.js +78 -0
- package/app/stories/pix-progress-gauge.stories.mdx +43 -0
- package/app/stories/pix-radio-button.stories.js +71 -0
- package/app/stories/pix-radio-button.stories.mdx +49 -0
- package/app/stories/pix-return-to.stories.js +45 -0
- package/app/stories/pix-return-to.stories.mdx +41 -0
- package/app/stories/pix-select.stories.js +140 -0
- package/app/stories/pix-select.stories.mdx +57 -0
- package/app/stories/pix-selectable-tag.stories.js +91 -0
- package/app/stories/pix-selectable-tag.stories.mdx +55 -0
- package/app/stories/pix-stars.stories.js +43 -0
- package/app/stories/pix-stars.stories.mdx +35 -0
- package/app/stories/pix-tag.stories.js +56 -0
- package/app/stories/pix-tag.stories.mdx +46 -0
- package/app/stories/pix-textarea.stories.js +59 -0
- package/app/stories/pix-textarea.stories.mdx +36 -0
- package/app/stories/pix-tooltip-deprecated.stories.js +136 -0
- package/app/stories/pix-tooltip-deprecated.stories.mdx +143 -0
- package/app/stories/pix-tooltip.stories.js +157 -0
- package/app/stories/pix-tooltip.stories.mdx +183 -0
- package/app/styles/app.scss +0 -0
- package/config/environment.js +5 -0
- package/docs/architecture.stories.mdx +106 -0
- package/docs/assets/accessibility-storybook.png +0 -0
- package/docs/assets/screen-pix-storybook.png +0 -0
- package/docs/breaking-changes.stories.mdx +90 -0
- package/docs/changelog.stories.mdx +6 -0
- package/docs/create-component.stories.mdx +118 -0
- package/docs/design-system.stories.mdx +20 -0
- package/docs/good-practices-a11y.stories.mdx +48 -0
- package/docs/good-practices-design.stories.mdx +71 -0
- package/docs/good-practices-responsive.stories.mdx +51 -0
- package/docs/good-practices-style-css.stories.mdx +40 -0
- package/docs/good-practices-tests.stories.mdx +9 -0
- package/docs/make-a-release.stories.mdx +66 -0
- package/docs/pull_request_template.md +14 -0
- package/docs/storybook.stories.mdx +44 -0
- package/docs/use-component.stories.mdx +89 -0
- package/docs/use-install.stories.mdx +37 -0
- package/index.js +5 -0
- package/package.json +121 -0
- package/scalingo.json +17 -0
- package/servers.conf.erb +30 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<div class="pix-multi-select" ...attributes {{on-click-outside this.hideDropDown capture=true}}>
|
|
2
|
+
|
|
3
|
+
{{#if this.label}}
|
|
4
|
+
<label for={{@id}} class="pix-multi-select__label">{{this.label}}</label>
|
|
5
|
+
{{/if}}
|
|
6
|
+
|
|
7
|
+
{{#if @isSearchable}}
|
|
8
|
+
<label class="pix-multi-select-header {{if this.isBig "pix-multi-select-header--big"}}">
|
|
9
|
+
|
|
10
|
+
<span class="pix-multi-select-header__title">{{@title}}</span>
|
|
11
|
+
<FaIcon @icon="search" class="pix-multi-select-header__search-icon" />
|
|
12
|
+
|
|
13
|
+
<input
|
|
14
|
+
id={{@id}}
|
|
15
|
+
type="text"
|
|
16
|
+
name={{@id}}
|
|
17
|
+
placeholder={{this.placeholder}}
|
|
18
|
+
autocomplete="off"
|
|
19
|
+
{{on "input" this.updateSearch}}
|
|
20
|
+
{{on "focus" this.focusDropdown}}
|
|
21
|
+
class="pix-multi-select-header__search-input"
|
|
22
|
+
/>
|
|
23
|
+
|
|
24
|
+
</label>
|
|
25
|
+
{{else}}
|
|
26
|
+
<button
|
|
27
|
+
id={{@id}}
|
|
28
|
+
type="button"
|
|
29
|
+
class="pix-multi-select-header {{if this.isBig "pix-multi-select-header--big"}}"
|
|
30
|
+
{{on "click" this.toggleDropDown}}
|
|
31
|
+
>
|
|
32
|
+
{{@title}}
|
|
33
|
+
<FaIcon
|
|
34
|
+
class="pix-multi-select-header__dropdown-icon
|
|
35
|
+
{{if this.isExpanded " pix-multi-select-header__dropdown-icon--expand"}}"
|
|
36
|
+
@icon={{if this.isExpanded "chevron-up" "chevron-down"}}
|
|
37
|
+
/>
|
|
38
|
+
</button>
|
|
39
|
+
{{/if}}
|
|
40
|
+
|
|
41
|
+
<ul class="pix-multi-select-list {{unless this.isExpanded "pix-multi-select-list--hidden"}}">
|
|
42
|
+
{{#if (gt this.results.length 0)}}
|
|
43
|
+
{{#each this.results as |option|}}
|
|
44
|
+
<li class="pix-multi-select-list__item">
|
|
45
|
+
<input
|
|
46
|
+
class="pix-multi-select-list__checkbox
|
|
47
|
+
{{if @isSearchable " pix-multi-select-list__checkbox--searchable"}}"
|
|
48
|
+
type="checkbox"
|
|
49
|
+
checked={{option.checked}}
|
|
50
|
+
id={{concat @id "-" option.value}}
|
|
51
|
+
name={{option.label}}
|
|
52
|
+
value={{option.value}}
|
|
53
|
+
{{on "change" this.onSelect}}
|
|
54
|
+
/>
|
|
55
|
+
<label for={{concat @id "-" option.value}}>
|
|
56
|
+
{{yield option}}
|
|
57
|
+
</label>
|
|
58
|
+
</li>
|
|
59
|
+
{{/each}}
|
|
60
|
+
{{else if this.isLoadingOptions}}
|
|
61
|
+
<li
|
|
62
|
+
class="pix-multi-select-list__item pix-multi-select-list__item--no-result"
|
|
63
|
+
>{{@loadingMessage}}</li>
|
|
64
|
+
{{else}}
|
|
65
|
+
<li
|
|
66
|
+
class="pix-multi-select-list__item pix-multi-select-list__item--no-result"
|
|
67
|
+
>{{@emptyMessage}}</li>
|
|
68
|
+
{{/if}}
|
|
69
|
+
</ul>
|
|
70
|
+
</div>
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
|
|
3
|
+
import { action } from '@ember/object';
|
|
4
|
+
import { tracked } from '@glimmer/tracking';
|
|
5
|
+
|
|
6
|
+
function sortOptionsByCheckedFirst(a, b) {
|
|
7
|
+
if (a.checked && b.checked) return 0;
|
|
8
|
+
if (a.checked) return -1;
|
|
9
|
+
if (b.checked) return 1;
|
|
10
|
+
return 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function removeCapitalizeAndDiacritics(string) {
|
|
14
|
+
return string
|
|
15
|
+
.normalize('NFD')
|
|
16
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
17
|
+
.toLowerCase();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default class PixMultiSelect extends Component {
|
|
21
|
+
@tracked isExpanded = false;
|
|
22
|
+
@tracked searchData;
|
|
23
|
+
|
|
24
|
+
@tracked options = [];
|
|
25
|
+
@tracked isLoadingOptions = false;
|
|
26
|
+
|
|
27
|
+
constructor(...args) {
|
|
28
|
+
super(...args);
|
|
29
|
+
const { onLoadOptions, selected } = this.args;
|
|
30
|
+
|
|
31
|
+
if (onLoadOptions) {
|
|
32
|
+
this.isLoadingOptions = true;
|
|
33
|
+
onLoadOptions().then((options = []) => {
|
|
34
|
+
this.options = options;
|
|
35
|
+
this._setDisplayedOptions(selected, true);
|
|
36
|
+
this.isLoadingOptions = false;
|
|
37
|
+
});
|
|
38
|
+
} else {
|
|
39
|
+
this.options = [...(this.args.options || [])];
|
|
40
|
+
this._setDisplayedOptions(selected, true);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
get label() {
|
|
45
|
+
const labelIsDefined = this.args.label && this.args.label.trim();
|
|
46
|
+
const idIsNotDefined = this.args.id && !this.args.id.trim();
|
|
47
|
+
|
|
48
|
+
if (labelIsDefined && idIsNotDefined) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
'ERROR in PixMultiSelect component, @id param is necessary when giving @label'
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
return this.args.label || null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get isBig() {
|
|
57
|
+
return this.args.size === 'big';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get results() {
|
|
61
|
+
if (this.args.isSearchable && this.searchData) {
|
|
62
|
+
return this.options.filter(({ label }) => this._search(label));
|
|
63
|
+
}
|
|
64
|
+
return this.options;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
get placeholder() {
|
|
68
|
+
const { selected, placeholder } = this.args;
|
|
69
|
+
if (selected?.length > 0) {
|
|
70
|
+
const selectedOptionLabels = this.options
|
|
71
|
+
.filter(({ value, label }) => {
|
|
72
|
+
const hasOption = selected.includes(value);
|
|
73
|
+
return hasOption && Boolean(label);
|
|
74
|
+
})
|
|
75
|
+
.map(({ label }) => label)
|
|
76
|
+
.join(', ');
|
|
77
|
+
return selectedOptionLabels;
|
|
78
|
+
}
|
|
79
|
+
return placeholder;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
_setDisplayedOptions(selected, shouldSort) {
|
|
83
|
+
const options = this.options.map((option) => ({
|
|
84
|
+
...option,
|
|
85
|
+
checked: selected ? selected.includes(option.value) : false,
|
|
86
|
+
}));
|
|
87
|
+
|
|
88
|
+
if (shouldSort && this.args.isSearchable) {
|
|
89
|
+
options.sort(sortOptionsByCheckedFirst);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
this.options = options;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
_search(label) {
|
|
96
|
+
if (this.args.strictSearch) {
|
|
97
|
+
return label.includes(this.searchData);
|
|
98
|
+
}
|
|
99
|
+
return removeCapitalizeAndDiacritics(label).includes(this.searchData);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@action
|
|
103
|
+
onSelect(event) {
|
|
104
|
+
let selected = [...(this.args.selected || [])];
|
|
105
|
+
if (event.target.checked) {
|
|
106
|
+
selected.push(event.target.value);
|
|
107
|
+
} else {
|
|
108
|
+
selected = selected.filter((value) => value !== event.target.value);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
this._setDisplayedOptions(selected, false);
|
|
112
|
+
|
|
113
|
+
if (this.args.onSelect) {
|
|
114
|
+
this.args.onSelect(selected);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@action
|
|
119
|
+
toggleDropDown() {
|
|
120
|
+
if (this.isExpanded) {
|
|
121
|
+
this.hideDropDown();
|
|
122
|
+
} else {
|
|
123
|
+
this.showDropDown();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@action
|
|
128
|
+
showDropDown() {
|
|
129
|
+
if (this.isExpanded) return;
|
|
130
|
+
this.isExpanded = true;
|
|
131
|
+
this._setDisplayedOptions(this.args.selected, true);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@action
|
|
135
|
+
hideDropDown(event) {
|
|
136
|
+
if (!this.isExpanded) return;
|
|
137
|
+
|
|
138
|
+
if (event) {
|
|
139
|
+
event.stopPropagation();
|
|
140
|
+
event.preventDefault();
|
|
141
|
+
}
|
|
142
|
+
this.isExpanded = false;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@action
|
|
146
|
+
focusDropdown() {
|
|
147
|
+
if (this.args.isSearchable && this.args.showOptionsOnInput) {
|
|
148
|
+
this.showDropDown();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@action
|
|
153
|
+
updateSearch(event) {
|
|
154
|
+
this.searchData = this.args.strictSearch
|
|
155
|
+
? event.target.value
|
|
156
|
+
: removeCapitalizeAndDiacritics(event.target.value);
|
|
157
|
+
this.isExpanded = true;
|
|
158
|
+
if (!event.target.value) {
|
|
159
|
+
this._setDisplayedOptions(this.args.selected, true);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<div
|
|
2
|
+
class="progress-gauge
|
|
3
|
+
{{this.progressGaugeClass}}
|
|
4
|
+
{{if @isArrowLeft "progress-gauge--tooltip-left"}}"
|
|
5
|
+
...attributes
|
|
6
|
+
>
|
|
7
|
+
<div class="progress-gauge__referrer"></div>
|
|
8
|
+
<div class="progress-gauge__marker" aria-hidden="true" style={{this.valueGaugeStyle}}></div>
|
|
9
|
+
|
|
10
|
+
{{#if @tooltipText}}
|
|
11
|
+
<div class="progress-gauge__tooltip-wrapper" style={{this.valueGaugeStyle}}>
|
|
12
|
+
<span class="progress-gauge__tooltip">{{@tooltipText}}</span>
|
|
13
|
+
</div>
|
|
14
|
+
{{/if}}
|
|
15
|
+
|
|
16
|
+
{{#if this.hasSubtitle}}
|
|
17
|
+
<p class="progress-gauge__sub-title">{{@subtitle}}</p>
|
|
18
|
+
{{/if}}
|
|
19
|
+
</div>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { htmlSafe } from '@ember/string';
|
|
3
|
+
|
|
4
|
+
export default class PixProgressGauge extends Component {
|
|
5
|
+
get progressValue() {
|
|
6
|
+
if (!this.args.value || this.args.value < 0) {
|
|
7
|
+
return 0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return this.args.value > 100 ? 100 : this.args.value;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
get valueGaugeStyle() {
|
|
14
|
+
return htmlSafe(`width: ${this.progressValue}%`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get hasSubtitle() {
|
|
18
|
+
return !!this.args.subtitle;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get progressGaugeClass() {
|
|
22
|
+
const availableColor = ['yellow', 'white'];
|
|
23
|
+
|
|
24
|
+
const color =
|
|
25
|
+
this.args.color && availableColor.includes(this.args.color) ? this.args.color : `yellow`;
|
|
26
|
+
|
|
27
|
+
return `progress-gauge--${color}`;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<div class="pix-radio-button">
|
|
2
|
+
<label class="{{if @isDisabled " pix-radio-button--disabled"}}">
|
|
3
|
+
<input
|
|
4
|
+
disabled={{@isDisabled}}
|
|
5
|
+
aria-disabled="{{@isDisabled}}"
|
|
6
|
+
type="radio"
|
|
7
|
+
value={{@value}}
|
|
8
|
+
...attributes
|
|
9
|
+
/>
|
|
10
|
+
{{@label}}
|
|
11
|
+
</label>
|
|
12
|
+
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<LinkTo
|
|
2
|
+
@route={{this.route}}
|
|
3
|
+
@models={{if @model (array @model) this.defaultModel}}
|
|
4
|
+
class="pix-return-to pix-return-to--{{this.shade}}"
|
|
5
|
+
...attributes
|
|
6
|
+
>
|
|
7
|
+
|
|
8
|
+
{{#if (has-block)}}
|
|
9
|
+
<span aria-hidden="true" class="pix-return-to__icon"><FaIcon @icon="arrow-left" /></span>
|
|
10
|
+
<span class="pix-return-to__text"> {{yield}} </span>
|
|
11
|
+
{{else}}
|
|
12
|
+
<span title="Flèche de retour" class="pix-return-to__icon"><FaIcon @icon="arrow-left" /></span>
|
|
13
|
+
{{/if}}
|
|
14
|
+
|
|
15
|
+
</LinkTo>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
|
|
3
|
+
export default class PixReturnTo extends Component {
|
|
4
|
+
text = 'pix-return-to';
|
|
5
|
+
availableShade = ['black', 'white', 'blue'];
|
|
6
|
+
defaultModel = [];
|
|
7
|
+
|
|
8
|
+
get route() {
|
|
9
|
+
const routeParam = this.args.route;
|
|
10
|
+
if (routeParam == undefined || routeParam.trim() == '') {
|
|
11
|
+
throw new Error('ERROR in PixReturnTo component, @route param is not provided');
|
|
12
|
+
}
|
|
13
|
+
return routeParam;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
get shade() {
|
|
17
|
+
const shadeParam = this.args.shade;
|
|
18
|
+
return this.availableShade.includes(shadeParam) ? shadeParam : this.availableShade[0];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<div class="pix-select">
|
|
2
|
+
|
|
3
|
+
{{#if this.label}}
|
|
4
|
+
<label for={{@id}} class="pix-select__label">{{this.label}}</label>
|
|
5
|
+
{{/if}}
|
|
6
|
+
|
|
7
|
+
{{#if @isSearchable}}
|
|
8
|
+
|
|
9
|
+
<input
|
|
10
|
+
id={{@id}}
|
|
11
|
+
list="{{this.datalistId}}"
|
|
12
|
+
{{on "input" this.onChange}}
|
|
13
|
+
class="{{if this.isValid "pix-select--is-valid"}} {{if this.isBig "pix-select--big"}}"
|
|
14
|
+
...attributes
|
|
15
|
+
/>
|
|
16
|
+
|
|
17
|
+
<datalist id={{this.datalistId}}>
|
|
18
|
+
{{#each @options as |opt|}}
|
|
19
|
+
<option label={{opt.label}}>{{opt.label}}</option>
|
|
20
|
+
{{/each}}
|
|
21
|
+
</datalist>
|
|
22
|
+
|
|
23
|
+
{{else}}
|
|
24
|
+
|
|
25
|
+
<select
|
|
26
|
+
id={{@id}}
|
|
27
|
+
class="{{if this.isBig "pix-select--big"}}"
|
|
28
|
+
{{on "change" this.onChange}}
|
|
29
|
+
...attributes
|
|
30
|
+
>
|
|
31
|
+
{{#if (not-eq @emptyOptionLabel undefined)}}
|
|
32
|
+
{{#if @emptyOptionNotSelectable}}
|
|
33
|
+
<option value="" hidden>{{@emptyOptionLabel}}</option>
|
|
34
|
+
{{else}}
|
|
35
|
+
<option value="">{{@emptyOptionLabel}}</option>
|
|
36
|
+
{{/if}}
|
|
37
|
+
{{/if}}
|
|
38
|
+
{{#each @options as |opt|}}
|
|
39
|
+
{{#if (eq @selectedOption opt.value)}}
|
|
40
|
+
{{! https://github.com/emberjs/ember.js/issues/15484
|
|
41
|
+
ember-prop-modifier let us fix a bug about selected attribute in FireFox }}
|
|
42
|
+
<option value={{opt.value}} {{prop selected="true"}}>
|
|
43
|
+
{{opt.label}}
|
|
44
|
+
</option>
|
|
45
|
+
{{else}}
|
|
46
|
+
<option value={{opt.value}}>
|
|
47
|
+
{{opt.label}}
|
|
48
|
+
</option>
|
|
49
|
+
{{/if}}
|
|
50
|
+
{{/each}}
|
|
51
|
+
</select>
|
|
52
|
+
<FaIcon class="pix-select__icon" @icon="chevron-down" />
|
|
53
|
+
|
|
54
|
+
{{/if}}
|
|
55
|
+
</div>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { guidFor } from '@ember/object/internals';
|
|
3
|
+
import { tracked } from '@glimmer/tracking';
|
|
4
|
+
import { action } from '@ember/object';
|
|
5
|
+
|
|
6
|
+
export default class PixSelect extends Component {
|
|
7
|
+
@tracked isValueAValidOption = false;
|
|
8
|
+
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
|
|
12
|
+
if (this.args.isSearchable) {
|
|
13
|
+
this.datalistId = 'pix-select-list-' + guidFor(this);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get label() {
|
|
18
|
+
const labelIsDefined = this.args.label?.trim();
|
|
19
|
+
const idIsNotDefined = !this.args.id?.trim();
|
|
20
|
+
|
|
21
|
+
if (labelIsDefined && idIsNotDefined) {
|
|
22
|
+
throw new Error('ERROR in PixSelect component, @id param is necessary when giving @label');
|
|
23
|
+
}
|
|
24
|
+
return this.args.label || null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get isBig() {
|
|
28
|
+
return this.args.size === 'big';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get isValid() {
|
|
32
|
+
return this.args.isValidationActive && this.isValueAValidOption;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@action
|
|
36
|
+
onChange(event) {
|
|
37
|
+
if (this.args.onChange) {
|
|
38
|
+
this.args.onChange(event);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!this.args.isSearchable || !this.args.options) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (this.args.isValidationActive) {
|
|
46
|
+
this.isValueAValidOption = _checkIfValueIsAValidOption({
|
|
47
|
+
value: event.target.value,
|
|
48
|
+
options: this.args.options,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function _checkIfValueIsAValidOption({ value, options }) {
|
|
55
|
+
return value
|
|
56
|
+
? options.some((option) => option.label.toLowerCase() === value.toLowerCase())
|
|
57
|
+
: false;
|
|
58
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<div class="pix-selectable-tag {{if this.isChecked " pix-selectable-tag--checked"}}">
|
|
2
|
+
<input
|
|
3
|
+
type="checkbox"
|
|
4
|
+
id={{@id}}
|
|
5
|
+
onChange={{this.toggleIsChecked}}
|
|
6
|
+
checked={{this.isChecked}}
|
|
7
|
+
...attributes
|
|
8
|
+
/>
|
|
9
|
+
<label for={{@id}}>{{@label}}</label>
|
|
10
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { action } from '@ember/object';
|
|
4
|
+
|
|
5
|
+
export default class PixSelectableTag extends Component {
|
|
6
|
+
@tracked isChecked = this.args.checked;
|
|
7
|
+
|
|
8
|
+
@action
|
|
9
|
+
toggleIsChecked() {
|
|
10
|
+
this.isChecked = !this.isChecked;
|
|
11
|
+
return this.args.onChange(this.isChecked);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<div class={{this.pixStarsClass}} ...attributes>
|
|
2
|
+
<span class="sr-only">{{@alt}}</span>
|
|
3
|
+
{{#each this.stars as |star|}}
|
|
4
|
+
<svg class="pix-stars__{{star}}" data-test-status={{star}} viewBox="0 0 36 36">
|
|
5
|
+
<defs>
|
|
6
|
+
<linearGradient id="pix-stars-default" x1="68.643%" y1="0%" x2="68.643%" y2="100%">
|
|
7
|
+
<stop stop-color="#FEDC41" offset="0%"></stop>
|
|
8
|
+
<stop stop-color="#FF9F00" offset="100%"></stop>
|
|
9
|
+
</linearGradient>
|
|
10
|
+
</defs>
|
|
11
|
+
<path
|
|
12
|
+
d="M8.423 35.82c-.761.507-1.765-.125-1.635-1.03l1.619-11.335L.311 15.36a1.059 1.059 0 01.6-1.796l11.268-1.61L17.027.642c.367-.856 1.58-.856 1.946 0l4.848 11.31 11.269 1.61a1.059 1.059 0 01.599 1.797l-8.096 8.096 1.62 11.334c.129.906-.875 1.538-1.636 1.03L18 29.436 8.423 35.82z"
|
|
13
|
+
></path>
|
|
14
|
+
</svg>
|
|
15
|
+
{{/each}}
|
|
16
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
|
|
3
|
+
const STAR_ACQUIRED = 'acquired';
|
|
4
|
+
const STAR_UNACQUIRED = 'unacquired';
|
|
5
|
+
|
|
6
|
+
export default class PixStars extends Component {
|
|
7
|
+
get pixStarsClass() {
|
|
8
|
+
if (!this.args.color) return 'pix-stars';
|
|
9
|
+
return `pix-stars pix-stars--${this.args.color}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
get stars() {
|
|
13
|
+
const { count = 0, total = 0 } = this.args;
|
|
14
|
+
|
|
15
|
+
const starsTotal = total || count;
|
|
16
|
+
|
|
17
|
+
const stars = [];
|
|
18
|
+
for (let index = 0; index < starsTotal; index++) {
|
|
19
|
+
if (index < count) {
|
|
20
|
+
stars[index] = STAR_ACQUIRED;
|
|
21
|
+
} else {
|
|
22
|
+
stars[index] = STAR_UNACQUIRED;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return stars;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
|
|
3
|
+
export default class PixTag extends Component {
|
|
4
|
+
get classes() {
|
|
5
|
+
const { color, compact } = this.args;
|
|
6
|
+
const classes = [];
|
|
7
|
+
if (color) classes.push(`pix-tag--${color}`);
|
|
8
|
+
if (compact) classes.push(`pix-tag--compact`);
|
|
9
|
+
return classes.join(' ');
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<div class="pix-textarea">
|
|
2
|
+
|
|
3
|
+
{{#if this.label}}
|
|
4
|
+
<label for={{@id}} class="pix-textarea__label">{{this.label}}</label>
|
|
5
|
+
{{/if}}
|
|
6
|
+
|
|
7
|
+
<Textarea
|
|
8
|
+
id={{@id}}
|
|
9
|
+
@value={{@value}}
|
|
10
|
+
maxlength={{if @maxlength @maxlength}}
|
|
11
|
+
class="{{if @errorMessage "pix-textarea--error"}}"
|
|
12
|
+
...attributes
|
|
13
|
+
/>
|
|
14
|
+
{{#if @maxlength}}
|
|
15
|
+
<p>{{this.textLengthIndicator}} / {{@maxlength}}</p>
|
|
16
|
+
{{/if}}
|
|
17
|
+
|
|
18
|
+
{{#if @errorMessage}}
|
|
19
|
+
<label for={{this.id}} class="pix-textarea__error-message">{{@errorMessage}}</label>
|
|
20
|
+
{{/if}}
|
|
21
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
|
|
3
|
+
export default class PixTextarea extends Component {
|
|
4
|
+
get textLengthIndicator() {
|
|
5
|
+
return this.args.value ? this.args.value.length : 0;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
get label() {
|
|
9
|
+
const labelIsDefined = this.args.label?.trim();
|
|
10
|
+
const idIsNotDefined = !this.args.id?.trim();
|
|
11
|
+
|
|
12
|
+
if (labelIsDefined && idIsNotDefined) {
|
|
13
|
+
throw new Error('ERROR in PixTextarea component, @id param is necessary when giving @label');
|
|
14
|
+
}
|
|
15
|
+
return this.args.label || null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<span class="pix-tooltip" ...attributes>
|
|
2
|
+
|
|
3
|
+
{{yield}}
|
|
4
|
+
|
|
5
|
+
{{#if @text}}
|
|
6
|
+
<span
|
|
7
|
+
id={{@id}}
|
|
8
|
+
role="tooltip"
|
|
9
|
+
class="pix-tooltip__content pix-tooltip__content--{{this.position}}
|
|
10
|
+
{{if @isInline "pix-tooltip__content--inline"}}
|
|
11
|
+
{{if @isLight "pix-tooltip__content--light"}}
|
|
12
|
+
{{if @isWide "pix-tooltip__content--wide"}}"
|
|
13
|
+
>
|
|
14
|
+
{{this.text}}
|
|
15
|
+
</span>
|
|
16
|
+
{{/if}}
|
|
17
|
+
|
|
18
|
+
</span>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { htmlSafe } from '@ember/template';
|
|
3
|
+
|
|
4
|
+
export default class PixTooltipDeprecated extends Component {
|
|
5
|
+
get position() {
|
|
6
|
+
const correctsPosition = [
|
|
7
|
+
'top',
|
|
8
|
+
'right',
|
|
9
|
+
'bottom',
|
|
10
|
+
'bottom-left',
|
|
11
|
+
'bottom-right',
|
|
12
|
+
'left',
|
|
13
|
+
'top-left',
|
|
14
|
+
'top-right',
|
|
15
|
+
];
|
|
16
|
+
return correctsPosition.includes(this.args.position) ? this.args.position : 'top';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get text() {
|
|
20
|
+
if (this.args.unescapeHtml) {
|
|
21
|
+
return htmlSafe(this.args.text);
|
|
22
|
+
} else {
|
|
23
|
+
return this.args.text;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<span class="pix-tooltip" ...attributes>
|
|
2
|
+
{{#if (has-block "triggerElement")}}
|
|
3
|
+
{{yield to="triggerElement"}}
|
|
4
|
+
{{/if}}
|
|
5
|
+
|
|
6
|
+
{{#if (has-block "tooltip")}}
|
|
7
|
+
<span
|
|
8
|
+
id={{@id}}
|
|
9
|
+
role="tooltip"
|
|
10
|
+
class="pix-tooltip__content pix-tooltip__content--{{this.position}}
|
|
11
|
+
{{if @isInline "pix-tooltip__content--inline"}}
|
|
12
|
+
{{if @isLight "pix-tooltip__content--light"}}
|
|
13
|
+
{{if @isWide "pix-tooltip__content--wide"}}"
|
|
14
|
+
>
|
|
15
|
+
{{yield to="tooltip"}}
|
|
16
|
+
</span>
|
|
17
|
+
{{/if}}
|
|
18
|
+
</span>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
|
|
3
|
+
export default class PixTooltip extends Component {
|
|
4
|
+
get position() {
|
|
5
|
+
const correctsPosition = [
|
|
6
|
+
'top',
|
|
7
|
+
'right',
|
|
8
|
+
'bottom',
|
|
9
|
+
'bottom-left',
|
|
10
|
+
'bottom-right',
|
|
11
|
+
'left',
|
|
12
|
+
'top-left',
|
|
13
|
+
'top-right',
|
|
14
|
+
];
|
|
15
|
+
return correctsPosition.includes(this.args.position) ? this.args.position : 'top';
|
|
16
|
+
}
|
|
17
|
+
}
|