@1024pix/pix-ui 24.0.3 → 24.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 CHANGED
@@ -1,5 +1,12 @@
1
1
  # Pix-UI Changelog
2
2
 
3
+ ## v24.1.0 (24/01/2023)
4
+
5
+
6
+ ### :rocket: Amélioration
7
+ - [#316](https://github.com/1024pix/pix-ui/pull/316) [FEATURE] Création d'un input permettant de chercher/filtrer (PIX-6780)
8
+ - [#320](https://github.com/1024pix/pix-ui/pull/320) [FEATURE] Déplacer le focus sur le champ lorsque le bouton pour masquer/afficher le mot de passe est cliqué sur PixInputPassword (PIX-6855)
9
+
3
10
  ## v24.0.3 (18/01/2023)
4
11
 
5
12
 
@@ -25,5 +25,9 @@ export default class PixInputPassword extends PixInput {
25
25
  @action
26
26
  togglePasswordVisibility() {
27
27
  this.isPasswordVisible = !this.isPasswordVisible;
28
+ const InputElement = document.getElementById(this.args.id);
29
+ if (InputElement) {
30
+ InputElement.focus();
31
+ }
28
32
  }
29
33
  }
@@ -0,0 +1,21 @@
1
+ <div class="pix-search-input">
2
+ {{#if this.label}}
3
+ <label for={{this.searchInputId}} class="pix-search-input__label">{{this.label}}</label>
4
+ {{/if}}
5
+
6
+ <div class="pix-search-input__input-container">
7
+ <FaIcon @icon="magnifying-glass" />
8
+ {{! template-lint-disable require-input-label }}
9
+ <input
10
+ id={{this.searchInputId}}
11
+ class="pix-search-input__input"
12
+ role="searchbox"
13
+ name={{@inputName}}
14
+ placeholder={{@placeholder}}
15
+ aria-label={{this.ariaLabel}}
16
+ value={{@value}}
17
+ oninput={{this.onSearch}}
18
+ ...attributes
19
+ />
20
+ </div>
21
+ </div>
@@ -0,0 +1,42 @@
1
+ import Component from '@glimmer/component';
2
+ import { action } from '@ember/object';
3
+ import { guidFor } from '@ember/object/internals';
4
+ import debounce from 'lodash.debounce';
5
+
6
+ export default class PixSearchInput extends Component {
7
+ constructor() {
8
+ super(...arguments);
9
+
10
+ this.debounceTimeBeforeSearch = parseInt(this.args.debounceTimeInMs);
11
+ if (isNaN(this.debounceTimeBeforeSearch)) {
12
+ throw new Error('ERROR in PixSearchInput component, @debounceTimeInMs param is not provided');
13
+ }
14
+ if (!this.args.triggerFiltering) {
15
+ throw new Error('ERROR in PixSearchInput component, @triggerFiltering param is not provided');
16
+ }
17
+ if (!this.args.label && !this.args.ariaLabel) {
18
+ throw new Error(
19
+ 'ERROR in PixSearchInput component, you must provide @label or @ariaLabel params'
20
+ );
21
+ }
22
+
23
+ this.searchInputId = this.args.id || guidFor(this);
24
+ this.debouncedTriggerFiltering = debounce(
25
+ this.args.triggerFiltering,
26
+ this.debounceTimeBeforeSearch
27
+ );
28
+ }
29
+
30
+ get label() {
31
+ return this.args.label;
32
+ }
33
+
34
+ get ariaLabel() {
35
+ return this.args.label ? null : this.args.ariaLabel;
36
+ }
37
+
38
+ @action
39
+ async onSearch(event) {
40
+ await this.debouncedTriggerFiltering(this.searchInputId, event.target.value);
41
+ }
42
+ }
@@ -38,6 +38,8 @@
38
38
  }
39
39
 
40
40
  &__button {
41
+ margin-right: $spacing-xxs;
42
+
41
43
  &:hover,
42
44
  &:active,
43
45
  &:focus {
@@ -53,7 +55,6 @@
53
55
 
54
56
  svg.pix-input-password__error-icon {
55
57
  position: absolute;
56
- bottom: 10px;
57
58
  right: 6px;
58
59
  color: $pix-neutral-0;
59
60
  background: $pix-error-70;
@@ -25,7 +25,7 @@
25
25
 
26
26
  svg.pix-input__error-icon {
27
27
  position: absolute;
28
- bottom: 10px;
28
+ bottom: 7px;
29
29
  right: 6px;
30
30
  color: $pix-neutral-0;
31
31
  background: $pix-error-70;
@@ -0,0 +1,43 @@
1
+ .pix-search-input {
2
+ display: flex;
3
+ flex-direction: column;
4
+ position: relative;
5
+ }
6
+
7
+ .pix-search-input__label {
8
+ font-family: $font-roboto;
9
+ font-size: 0.875rem;
10
+ color: $pix-neutral-70;
11
+ margin-bottom: 4px;
12
+ }
13
+
14
+ .pix-search-input__input-container {
15
+ position: relative;
16
+
17
+ svg {
18
+ position: absolute;
19
+ bottom: calc(50% - 9px);
20
+ left: 6px;
21
+ color: $pix-neutral-60;
22
+ font-size: 0.6rem;
23
+ padding-left: 2px;
24
+ width: 18px;
25
+ height: 18px;
26
+ }
27
+ }
28
+
29
+ .pix-search-input__input {
30
+ @include input();
31
+ @include hoverFormElement();
32
+ @include focusFormElement();
33
+
34
+ width: 100%;
35
+ height: 36px;
36
+ border: 1px solid $pix-neutral-40;
37
+ padding-left: $spacing-xl;
38
+
39
+ &::placeholder {
40
+ color: $pix-neutral-30;
41
+ }
42
+ }
43
+
@@ -32,6 +32,7 @@
32
32
  @import 'pix-toggle';
33
33
  @import 'pix-indicator-card';
34
34
  @import 'trap-focus';
35
+ @import 'pix-search-input';
35
36
 
36
37
  // at the end so it can override it's children scss
37
- @import 'pix-filterable-and-searchable-select';
38
+ @import 'pix-filterable-and-searchable-select';
@@ -0,0 +1 @@
1
+ export { default } from '@1024pix/pix-ui/components/pix-search-input';
@@ -0,0 +1,80 @@
1
+ import { hbs } from 'ember-cli-htmlbars';
2
+ import { action } from '@storybook/addon-actions';
3
+
4
+ export const Template = (args) => {
5
+ return {
6
+ template: hbs`
7
+ <PixSearchInput
8
+ @id={{this.id}}
9
+ @label={{this.label}}
10
+ @ariaLabel={{this.ariaLabel}}
11
+ @placeholder={{this.placeholder}}
12
+ @debounceTimeInMs={{this.debounceTimeInMs}}
13
+ @triggerFiltering={{this.triggerFiltering}}
14
+ />
15
+ `,
16
+ context: args,
17
+ };
18
+ };
19
+
20
+ export const Default = Template.bind({});
21
+ Default.args = {
22
+ id: null,
23
+ label: 'Filtrer un fruit',
24
+ ariaLabel: null,
25
+ placeholder: 'un placeholder',
26
+ debounceTimeInMs: 500,
27
+ triggerFiltering: action('triggerFiltering'),
28
+ };
29
+
30
+ export const argTypes = {
31
+ id: {
32
+ name: 'id',
33
+ description:
34
+ "Un identifiant unique placé sur le composant. Si l'id n'est pas fourni un id par défaut sera mis.",
35
+ type: { name: 'string', required: false },
36
+ table: {
37
+ type: { summary: 'string' },
38
+ },
39
+ },
40
+ label: {
41
+ name: 'label',
42
+ description:
43
+ "Label du champ. ** ⚠️ Le `label` est obligatoire si l'`ariaLabel` n'est pas donné. ⚠️ **",
44
+ type: { name: 'string', required: false },
45
+ table: {
46
+ type: { summary: 'string' },
47
+ },
48
+ },
49
+ ariaLabel: {
50
+ name: 'ariaLabel',
51
+ description:
52
+ "Label du champ. ** ⚠️ L'`ariaLabel` est obligatoire si le `label` n'est pas donné. ⚠️ **",
53
+ type: { name: 'string', required: false },
54
+ table: {
55
+ type: { summary: 'string' },
56
+ },
57
+ },
58
+ placeholder: {
59
+ name: 'placeholder',
60
+ description: 'Placeholder du champ.',
61
+ type: { name: 'string', required: false },
62
+ table: {
63
+ type: { summary: 'string' },
64
+ },
65
+ },
66
+ debounceTimeInMs: {
67
+ name: 'debounceTimeInMs',
68
+ description: "Temps d'attente en millisecondes entre 2 appels à la fonction triggerFiltering.",
69
+ type: { name: 'string', required: true },
70
+ table: {
71
+ type: { summary: 'string' },
72
+ },
73
+ },
74
+ triggerFiltering: {
75
+ name: 'triggerFiltering',
76
+ description: 'Fonction appelée quand le champ est modifié.',
77
+ type: { required: true },
78
+ control: { disable: true },
79
+ },
80
+ };
@@ -0,0 +1,54 @@
1
+ import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs/blocks';
2
+
3
+ import * as stories from './pix-search-input.stories.js';
4
+
5
+ <Meta
6
+ title='Others/SearchInput'
7
+ component='PixSearchInput'
8
+ argTypes={stories.argTypes}
9
+ />
10
+
11
+ # PixSearchInput
12
+
13
+ Le PixSearchInput est un champ qui permet de filter des résultats. Un cas d'utilisation courant de ce genre de composant est un champ de filtre d'une colonne d'un tableau.
14
+
15
+
16
+ A la différence d'un [PixSelect](?path=/docs/form-select--default#withsearch) searchable, la liste des résultats s'affiche en dehors du composant.
17
+
18
+
19
+ Ce composant permet d'appeler la fonction triggerFiltering passée en paramètre selon un debounce (temps d'attente avant le prochain appel) fournis.
20
+
21
+
22
+
23
+ ⚠️ ⚠️ ⚠️ Pour utiliser ce composant des changements sont nécessaires dans l'application où est installé Pix UI :
24
+
25
+ 1- Rajoutez ceci dans le `ember-cli-build.js` de votre application (mon-pix/pix-orga/pix-certif/pix-admin) :
26
+ ```js
27
+ app.import('node_modules/lodash.debounce/index.js', {
28
+ using: [{ transformation: 'cjs', as: 'lodash.debounce' }],
29
+ });
30
+ ```
31
+
32
+ 2- Installez la dépendance "ember-cli-cjs-transform" : `npm install ember-cli-cjs-transform`
33
+
34
+
35
+ <Canvas>
36
+ <Story name='Default' story={stories.Default} height={80} />
37
+ </Canvas>
38
+
39
+ ## Usage
40
+
41
+ ```html
42
+ <PixSearchInput
43
+ @id={{this.id}}
44
+ @label={{this.label}}
45
+ @ariaLabel={{this.ariaLabel}}
46
+ @placeholder={{this.placeholder}}
47
+ @debounceTimeInMs={{this.debounceTimeInMs}}
48
+ @triggerFiltering={{this.triggerFiltering}}
49
+ />
50
+ ```
51
+
52
+ ## Arguments
53
+
54
+ <ArgsTable story="Default" />
@@ -19,6 +19,8 @@ Les options sont représentées par un tableau d'objet contenant les propriété
19
19
 
20
20
  > Pour aider l'utilisateur, rajoutez un placeholder cohérent !
21
21
 
22
+ > **⚠️** Pour un champ de filtre sur des résultats qui ne s'affichent pas dans une liste déroulante, utilisez plutôt le [PixSearchInput](?path=/story/others-searchinput--default).
23
+
22
24
  ## Default
23
25
 
24
26
  <Canvas>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1024pix/pix-ui",
3
- "version": "24.0.3",
3
+ "version": "24.1.0",
4
4
  "description": "Pix-UI is the implementation of Pix design principles and guidelines for its products.",
5
5
  "keywords": [
6
6
  "ember-addon"
@@ -52,7 +52,9 @@
52
52
  "ember-cli-string-utils": "^1.1.0",
53
53
  "ember-click-outside": "^4.0.0",
54
54
  "ember-prop-modifier": "^1.0.1",
55
- "ember-truth-helpers": "^3.1.1"
55
+ "ember-truth-helpers": "^3.1.1",
56
+ "ember-cli-cjs-transform": "^2.0.0",
57
+ "lodash.debounce": "^4.0.8"
56
58
  },
57
59
  "devDependencies": {
58
60
  "@1024pix/ember-testing-library": "^0.6.0",