@1024pix/pix-ui 25.0.1 → 26.0.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,11 @@
1
1
  # Pix-UI Changelog
2
2
 
3
+ ## v26.0.0 (06/02/2023)
4
+
5
+
6
+ ### :rocket: Amélioration
7
+ - [#328](https://github.com/1024pix/pix-ui/pull/328) [FEATURE] Ajout de l'état de succès pour les composants pixInput et pixInputPassword
8
+
3
9
  ## v25.0.1 (06/02/2023)
4
10
 
5
11
 
@@ -14,7 +14,7 @@
14
14
  {{/if}}
15
15
  <div
16
16
  class="pix-input-password__container
17
- {{if @errorMessage 'pix-input-password__error-container'}}
17
+ {{this.validationStatusClassName}}
18
18
  {{if @prefix 'pix-input-password__with-prefix'}}"
19
19
  >
20
20
 
@@ -29,24 +29,29 @@
29
29
  aria-label={{this.ariaLabel}}
30
30
  aria-required="{{if @requiredLabel true false}}"
31
31
  required={{if @requiredLabel true false}}
32
- aria-describedby={{if @errorMessage "text-input-password-error"}}
32
+ aria-describedby={{if (eq @validationStatus "error") "text-input-password-error"}}
33
33
  ...attributes
34
34
  />
35
35
 
36
36
  <PixIconButton
37
- class="pix-input-password__button {{if @errorMessage ' pix-input-password__error-button'}}"
37
+ class="pix-input-password__button"
38
38
  @icon={{if this.isPasswordVisible "eye" "eye-slash"}}
39
39
  @ariaLabel={{if this.isPasswordVisible "Masquer le mot de passe" "Afficher le mot de passe"}}
40
40
  @triggerAction={{this.togglePasswordVisibility}}
41
41
  @size="small"
42
42
  />
43
43
 
44
- {{#if @errorMessage}}
45
- <FaIcon @icon="xmark" class="pix-input-password__error-icon" />
44
+ {{#if (eq @validationStatus "error")}}
45
+ <FaIcon @icon="xmark" class="pix-input-password__icon pix-input-password__error-icon" />
46
+ {{/if}}
47
+ {{#if (eq @validationStatus "success")}}
48
+ <FaIcon @icon="check" class="pix-input-password__icon pix-input-password__success-icon" />
46
49
  {{/if}}
47
50
  </div>
48
51
 
49
- {{#if @errorMessage}}
50
- <p id="text-input-password-error" class="pix-input__error-message">{{@errorMessage}}</p>
52
+ {{#if (and (eq @validationStatus "error") @errorMessage)}}
53
+ <p id="text-input-password-error" class="pix-input-password__error-message">
54
+ {{@errorMessage}}
55
+ </p>
51
56
  {{/if}}
52
57
  </div>
@@ -5,6 +5,12 @@ import { tracked } from '@glimmer/tracking';
5
5
  const ERROR_MESSAGE =
6
6
  'ERROR in PixInputPassword component, you must provide @label or @ariaLabel params';
7
7
 
8
+ const INPUT_VALIDATION_STATUS_MAP = {
9
+ default: '',
10
+ error: 'pix-input-password__error-container',
11
+ success: 'pix-input-password__success-container',
12
+ };
13
+
8
14
  export default class PixInputPassword extends PixInput {
9
15
  @tracked isPasswordVisible = false;
10
16
 
@@ -30,4 +36,8 @@ export default class PixInputPassword extends PixInput {
30
36
  InputElement.focus();
31
37
  }
32
38
  }
39
+
40
+ get validationStatusClassName() {
41
+ return INPUT_VALIDATION_STATUS_MAP[this.args.validationStatus] || '';
42
+ }
33
43
  }
@@ -16,21 +16,24 @@
16
16
  <div class="pix-input__container">
17
17
  <input
18
18
  id={{this.id}}
19
- class={{if @errorMessage "pix-input__input--error"}}
19
+ class="pix-input__input--default {{this.validationStatusClassName}}"
20
20
  value={{@value}}
21
21
  aria-label={{this.ariaLabel}}
22
22
  aria-required="{{if @requiredLabel true false}}"
23
23
  required={{if @requiredLabel true false}}
24
- aria-describedby={{if @errorMessage "text-input-error"}}
24
+ aria-describedby={{if (eq @validationStatus "error") "text-input-error"}}
25
25
  ...attributes
26
26
  />
27
27
 
28
- {{#if @errorMessage}}
28
+ {{#if (eq @validationStatus "error")}}
29
29
  <FaIcon @icon="xmark" class="pix-input__error-icon" />
30
30
  {{/if}}
31
+ {{#if (eq @validationStatus "success")}}
32
+ <FaIcon @icon="check" class="pix-input__success-icon" />
33
+ {{/if}}
31
34
  </div>
32
35
 
33
- {{#if @errorMessage}}
36
+ {{#if (and (eq @validationStatus "error") @errorMessage)}}
34
37
  <p id="text-input-error" class="pix-input__error-message">{{@errorMessage}}</p>
35
38
  {{/if}}
36
39
  </div>
@@ -2,6 +2,12 @@ import Component from '@glimmer/component';
2
2
 
3
3
  const ERROR_MESSAGE = 'ERROR in PixInput component, you must provide @label or @ariaLabel params';
4
4
 
5
+ const INPUT_VALIDATION_STATUS_MAP = {
6
+ default: '',
7
+ error: 'pix-input__input--error',
8
+ success: 'pix-input__input--success',
9
+ };
10
+
5
11
  export default class PixInput extends Component {
6
12
  get id() {
7
13
  if (!this.args.id || !this.args.id.toString().trim()) {
@@ -23,4 +29,8 @@ export default class PixInput extends Component {
23
29
  }
24
30
  return this.args.label ? null : this.args.ariaLabel;
25
31
  }
32
+
33
+ get validationStatusClassName() {
34
+ return INPUT_VALIDATION_STATUS_MAP[this.args.validationStatus] || '';
35
+ }
26
36
  }
@@ -53,15 +53,31 @@
53
53
  @include formElementInError();
54
54
  }
55
55
 
56
- svg.pix-input-password__error-icon {
56
+ &__success-container {
57
+ padding-right: $spacing-m;
58
+ @include formElementInSuccess();
59
+ }
60
+
61
+ &__icon {
57
62
  position: absolute;
58
- right: 6px;
59
63
  color: $pix-neutral-0;
60
- background: $pix-error-70;
61
64
  border-radius: 50%;
62
65
  font-size: 0.6rem;
63
66
  padding: 2px;
64
- width: 18px;
65
- height: 18px;
67
+ right: 12px;
68
+ width: 10px;
69
+ height: 10px
70
+ }
71
+
72
+ &__error-icon {
73
+ background: $pix-error-70;
74
+ }
75
+
76
+ &__success-icon {
77
+ background: $pix-success-60;
78
+ }
79
+
80
+ &__error-message {
81
+ @include errorMessage();
66
82
  }
67
83
  }
@@ -23,30 +23,31 @@
23
23
  position: relative;
24
24
  }
25
25
 
26
- svg.pix-input__error-icon {
26
+ svg {
27
27
  position: absolute;
28
- bottom: 7px;
29
- right: 6px;
30
28
  color: $pix-neutral-0;
31
- background: $pix-error-70;
32
29
  border-radius: 50%;
33
30
  font-size: 0.6rem;
34
31
  padding: 2px;
35
- width: 18px;
36
- height: 18px;
32
+ bottom: 11px;
33
+ right: 12px;
34
+ width: 10px;
35
+ height: 10px;
36
+
37
+ &.pix-input__error-icon {
38
+ background: $pix-error-70;
39
+ }
40
+
41
+ &.pix-input__success-icon {
42
+ background: $pix-success-60;
43
+ }
37
44
  }
38
45
 
39
46
  &__error-message {
40
47
  @include errorMessage();
41
- margin-bottom: 0;
42
- bottom: calc(-4px - 1px - 0.75rem);
43
-
44
- &.pix-input__error-message {
45
- margin-top: 4px;
46
- }
47
48
  }
48
49
 
49
- input {
50
+ &__input--default {
50
51
  width: 100%;
51
52
  height: 36px;
52
53
  border: 1px solid $pix-neutral-40;
@@ -58,10 +59,15 @@
58
59
  &::placeholder {
59
60
  color: $pix-neutral-30;
60
61
  }
62
+ }
61
63
 
62
- &.pix-input__input--error {
63
- padding-right: 32px;
64
- @include formElementInError();
65
- }
64
+ &__input--error {
65
+ padding-right: $spacing-l;
66
+ @include formElementInError();
67
+ }
68
+
69
+ &__input--success {
70
+ padding-right: $spacing-l;
71
+ @include formElementInSuccess();
66
72
  }
67
73
  }
@@ -12,7 +12,7 @@
12
12
  }
13
13
  }
14
14
 
15
- @mixin formElementDisabled() {
15
+ @mixin formElementDisabled() {
16
16
  background-color: $pix-neutral-20;
17
17
  }
18
18
 
@@ -63,6 +63,11 @@
63
63
  box-shadow: inset 0px 0px 0px 0.6px $pix-error-70;
64
64
  }
65
65
 
66
+ @mixin formElementInSuccess() {
67
+ border-color: $pix-success-60;
68
+ box-shadow: inset 0px 0px 0px 0.6px $pix-success-60;
69
+ }
70
+
66
71
  @mixin input() {
67
72
  font-family: $font-roboto;
68
73
  font-size: 0.875rem;
@@ -9,6 +9,7 @@ export const form = (args) => {
9
9
  @label='Prénom'
10
10
  @errorMessage={{this.genericErrorMessage}}
11
11
  @requiredLabel='champ obligatoire'
12
+ @validationStatus={{this.validationStatus}}
12
13
  />
13
14
  <br />
14
15
  <PixInputPassword @id='password' @label='Mot de passe' @errorMessage={{this.genericErrorMessage}} />
@@ -16,8 +17,8 @@ export const form = (args) => {
16
17
 
17
18
  <PixMultiSelect
18
19
  @innerText='Votre notation en étoiles...'
19
- @id='form__pix-mutli-select'
20
- @label='A quel point aimez vous Pix UI ?'
20
+ @id='form__pix-multi-select'
21
+ @label='A quel point aimez-vous Pix UI ?'
21
22
  @onSelect={{this.onSelect}}
22
23
  @selected={{this.selected}}
23
24
  @options={{this.options}}
@@ -28,8 +29,8 @@ export const form = (args) => {
28
29
  <br /><br />
29
30
 
30
31
  <PixMultiSelect
31
- @innerText='Mes condiements'
32
- @id='form__pix-mutli-select-searchable'
32
+ @innerText='Mes condiments'
33
+ @id='form__pix-multi-select-searchable'
33
34
  @label='Choississez vos condiments'
34
35
  @onSelect={{this.onSelect}}
35
36
  @selected={{this.selected}}
@@ -82,8 +83,9 @@ export const form = (args) => {
82
83
  <PixCheckbox
83
84
  @id='spam-pub'
84
85
  @labelSize='small'
85
- @label='Acceptez-vous de vous faire spammer de PUB ?'
86
- />
86
+ >
87
+ Acceptez-vous de vous faire spammer de PUB ?
88
+ </PixCheckbox>
87
89
 
88
90
  <br /><br />
89
91
 
@@ -10,6 +10,7 @@ export const Template = (args) => {
10
10
  @errorMessage={{this.errorMessage}}
11
11
  @prefix={{this.prefix}}
12
12
  @requiredLabel={{this.requiredLabel}}
13
+ @validationStatus={{this.validationStatus}}
13
14
  />`,
14
15
  context: args,
15
16
  };
@@ -28,11 +29,19 @@ withLabelAndInformation.args = {
28
29
  information: 'Une brève information',
29
30
  };
30
31
 
31
- export const withErrorMessage = Template.bind({});
32
- withErrorMessage.args = {
32
+ export const errorState = Template.bind({});
33
+ errorState.args = {
33
34
  id: 'password',
34
35
  label: 'Mot de passe',
35
- errorMessage: "Un message d'erreur.",
36
+ errorMessage: "un message d'erreur",
37
+ validationStatus: 'error',
38
+ };
39
+
40
+ export const successState = Template.bind({});
41
+ successState.args = {
42
+ id: 'password',
43
+ label: 'Mot de passe',
44
+ validationStatus: 'success',
36
45
  };
37
46
 
38
47
  export const withPrefix = Template.bind({});
@@ -75,9 +84,18 @@ export const argTypes = {
75
84
  description: 'Un descriptif complétant le label',
76
85
  type: { name: 'string', required: false },
77
86
  },
87
+ validationStatus: {
88
+ name: 'validationStatus',
89
+ description:
90
+ "Définit l'état du champ, neutre par défaut, en succès ou erreur selon l'action de l'utilisateur",
91
+ type: { name: 'string', required: false },
92
+ options: ['default', 'success', 'error'],
93
+ control: { type: 'select' },
94
+ },
78
95
  errorMessage: {
79
96
  name: 'errorMessage',
80
- description: "Affiche le message d'erreur donné et encadre en rouge le champ",
97
+ description:
98
+ "Affiche le message d'erreur donné. Doit s'accompagner du paramètre validationStatus en 'error'",
81
99
  type: { name: 'string', required: false },
82
100
  },
83
101
  prefix: {
@@ -29,13 +29,19 @@ Si vous utilisez le `PixInputPassword` sans label alors il faut renseigner le pa
29
29
  ## With label and information
30
30
 
31
31
  <Canvas>
32
- <Story story={stories.withLabelAndInformation} height={100} />
32
+ <Story story={stories.withLabelAndInformation} height={110} />
33
33
  </Canvas>
34
34
 
35
- ## With error message
35
+ ## Error state (with error message)
36
36
 
37
37
  <Canvas>
38
- <Story story={stories.withErrorMessage} height={100} />
38
+ <Story story={stories.errorState} height={110} />
39
+ </Canvas>
40
+
41
+ ## Success state
42
+
43
+ <Canvas>
44
+ <Story story={stories.successState} height={100} />
39
45
  </Canvas>
40
46
 
41
47
  ## With prefix
@@ -59,6 +65,7 @@ Si vous utilisez le `PixInputPassword` sans label alors il faut renseigner le pa
59
65
  @information="8 caractères dont une majuscule..."
60
66
  @value="pix123"
61
67
  @errorMessage="Le mot de passe est erroné"
68
+ @validationStatus="default"
62
69
  @prefix="C-"
63
70
  @requiredLabel="Champ obligatoire"
64
71
  />
@@ -10,6 +10,7 @@ export const Template = (args) => {
10
10
  placeholder='Jeanne, Pierre ...'
11
11
  @requiredLabel={{this.requiredLabel}}
12
12
  @ariaLabel={{this.ariaLabel}}
13
+ @validationStatus={{this.validationStatus}}
13
14
  />`,
14
15
  context: args,
15
16
  };
@@ -28,12 +29,19 @@ withLabel.args = {
28
29
  information: 'a small information',
29
30
  };
30
31
 
31
- export const withErrorMessage = Template.bind({});
32
- withErrorMessage.args = {
32
+ export const errorState = Template.bind({});
33
+ errorState.args = {
33
34
  id: 'first-name',
34
35
  label: 'Prénom',
35
- information: 'a small information',
36
36
  errorMessage: "un message d'erreur",
37
+ validationStatus: 'error',
38
+ };
39
+
40
+ export const successState = Template.bind({});
41
+ successState.args = {
42
+ id: 'first-name',
43
+ label: 'Prénom',
44
+ validationStatus: 'success',
37
45
  };
38
46
 
39
47
  export const withRequiredLabel = Template.bind({});
@@ -69,9 +77,18 @@ export const argTypes = {
69
77
  description: 'Un descriptif complétant le label',
70
78
  type: { name: 'string', required: false },
71
79
  },
80
+ validationStatus: {
81
+ name: 'validationStatus',
82
+ description:
83
+ "Définit l'état du champ, neutre par défaut, en succès ou erreur selon l'action de l'utilisateur",
84
+ type: { name: 'string', required: false },
85
+ options: ['default', 'success', 'error'],
86
+ control: { type: 'select' },
87
+ },
72
88
  errorMessage: {
73
89
  name: 'errorMessage',
74
- description: "Affiche le message d'erreur donné et encadre en rouge le champ",
90
+ description:
91
+ "Affiche le message d'erreur donné. Doit s'accompagner du paramètre validationStatus en 'error'",
75
92
  type: { name: 'string', required: false },
76
93
  },
77
94
  requiredLabel: {
@@ -43,19 +43,25 @@ screen.getByLabelText('Prénom exemple: Barry');
43
43
  ## With label and information
44
44
 
45
45
  <Canvas>
46
- <Story story={stories.withLabel} height={100} />
46
+ <Story story={stories.withLabel} height={110} />
47
47
  </Canvas>
48
48
 
49
- ## With error message
49
+ ## Error state (with error message)
50
50
 
51
51
  <Canvas>
52
- <Story story={stories.withErrorMessage} height={130} />
52
+ <Story story={stories.errorState} height={110} />
53
+ </Canvas>
54
+
55
+ ## Success state
56
+
57
+ <Canvas>
58
+ <Story story={stories.successState} height={100} />
53
59
  </Canvas>
54
60
 
55
61
  ## With required label
56
62
 
57
63
  <Canvas>
58
- <Story story={stories.withRequiredLabel} height={130} />
64
+ <Story story={stories.withRequiredLabel} height={100} />
59
65
  </Canvas>
60
66
 
61
67
  ## Usage
@@ -66,6 +72,7 @@ screen.getByLabelText('Prénom exemple: Barry');
66
72
  @label="Prénom"
67
73
  @information="Complément du label"
68
74
  @errorMessage="Un message d`erreur"
75
+ @validationStatus="default"
69
76
  @requiredLabel="Champ obligatoire"
70
77
  />
71
78
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1024pix/pix-ui",
3
- "version": "25.0.1",
3
+ "version": "26.0.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"