@ouestfrance/sipa-bms-ui 8.6.0 → 8.8.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.
Files changed (62) hide show
  1. package/dist/components/form/BmsAutocomplete.vue.d.ts +2 -0
  2. package/dist/components/form/BmsInputBooleanCheckbox.vue.d.ts +1 -1
  3. package/dist/components/form/BmsInputCheckboxGroup.vue.d.ts +2 -2
  4. package/dist/components/form/BmsInputCode.vue.d.ts +2 -2
  5. package/dist/components/form/BmsInputNumber.vue.d.ts +2 -2
  6. package/dist/components/form/BmsInputRadio.vue.d.ts +2 -2
  7. package/dist/components/form/BmsInputText.vue.d.ts +24 -22
  8. package/dist/components/form/BmsMultiSelect.vue.d.ts +3 -1
  9. package/dist/components/form/BmsSearch.vue.d.ts +28 -24
  10. package/dist/components/form/BmsSelect.vue.d.ts +7 -17
  11. package/dist/components/form/RawAutocomplete.vue.d.ts +17 -21
  12. package/dist/components/form/RawInputText.vue.d.ts +9 -9
  13. package/dist/components/form/RawSelect.vue.d.ts +30 -0
  14. package/dist/components/navigation/UiTenantSwitcher.vue.d.ts +28 -24
  15. package/dist/components/table/BmsServerTable.vue.d.ts +18 -0
  16. package/dist/components/table/BmsTable.vue.d.ts +18 -1
  17. package/dist/components/table/BmsTableFilters.vue.d.ts +47 -25
  18. package/dist/composables/search.composable.d.ts +1 -0
  19. package/dist/mockServiceWorker.js +16 -12
  20. package/dist/plugins/field/FieldDatalist.vue.d.ts +2 -0
  21. package/dist/plugins/field/field-component.model.d.ts +2 -2
  22. package/dist/sipa-bms-ui.css +220 -168
  23. package/dist/sipa-bms-ui.es.js +729 -524
  24. package/dist/sipa-bms-ui.es.js.map +1 -1
  25. package/dist/sipa-bms-ui.umd.js +734 -529
  26. package/dist/sipa-bms-ui.umd.js.map +1 -1
  27. package/package.json +11 -11
  28. package/src/assets/scss/global-variables.scss +6 -0
  29. package/src/components/feedback/UiTooltip.vue +1 -1
  30. package/src/components/form/BmsAutocomplete.vue +3 -0
  31. package/src/components/form/BmsInputNumber.spec.ts +26 -0
  32. package/src/components/form/BmsInputNumber.stories.js +20 -3
  33. package/src/components/form/BmsInputNumber.vue +36 -4
  34. package/src/components/form/BmsInputRadio.vue +1 -1
  35. package/src/components/form/BmsInputText.spec.ts +25 -0
  36. package/src/components/form/BmsInputText.stories.js +28 -3
  37. package/src/components/form/BmsInputText.vue +73 -12
  38. package/src/components/form/BmsMultiSelect.vue +66 -28
  39. package/src/components/form/BmsSelect.vue +60 -57
  40. package/src/components/form/RawAutocomplete.spec.ts +0 -8
  41. package/src/components/form/RawAutocomplete.vue +42 -24
  42. package/src/components/form/RawInputText.vue +14 -21
  43. package/src/components/form/RawSelect.vue +111 -0
  44. package/src/components/layout/BmsOverlay.vue +2 -2
  45. package/src/components/layout/UiPopoverMenu.vue +1 -1
  46. package/src/components/navigation/BmsMenu.vue +1 -1
  47. package/src/components/table/BmsServerTable.vue +18 -3
  48. package/src/components/table/BmsTable.vue +15 -2
  49. package/src/components/table/BmsTableFilters.vue +19 -7
  50. package/src/composables/search.composable.spec.ts +75 -0
  51. package/src/composables/search.composable.ts +54 -11
  52. package/src/plugins/field/FieldComponent.vue +7 -5
  53. package/src/plugins/field/FieldDatalist.stories.js +0 -9
  54. package/src/plugins/field/FieldDatalist.vue +16 -13
  55. package/src/plugins/field/field-component.model.ts +2 -2
  56. package/src/plugins/notifications/NotificationWidget.vue +1 -1
  57. package/src/showroom/pages/autocomplete.vue +22 -1
  58. package/src/showroom/pages/server-table.vue +53 -22
  59. package/src/showroom/pages/table.vue +42 -3
  60. package/src/showroom/pages/zindex.vue +39 -0
  61. package/dist/plugins/field/FieldDatalist.spec.d.ts +0 -1
  62. package/src/plugins/field/FieldDatalist.spec.ts +0 -35
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouestfrance/sipa-bms-ui",
3
- "version": "8.6.0",
3
+ "version": "8.8.0",
4
4
  "author": "Ouest-France BMS",
5
5
  "license": "ISC",
6
6
  "scripts": {
@@ -36,9 +36,9 @@
36
36
  "@commitlint/config-conventional": "19.8.1",
37
37
  "@formkit/vue": "1.6.9",
38
38
  "@mdx-js/react": "3.1.1",
39
- "@storybook/addon-docs": "9.1.5",
40
- "@storybook/addon-links": "9.1.5",
41
- "@storybook/vue3-vite": "9.1.5",
39
+ "@storybook/addon-docs": "9.1.7",
40
+ "@storybook/addon-links": "9.1.7",
41
+ "@storybook/vue3-vite": "9.1.7",
42
42
  "@types/lodash": "4.17.20",
43
43
  "@types/uuid": "11.0.0",
44
44
  "@vitejs/plugin-vue": "6.0.1",
@@ -47,7 +47,7 @@
47
47
  "@vueuse/motion": "^3.0.0",
48
48
  "axios": "1.12.2",
49
49
  "blob-util": "^2.0.2",
50
- "chromatic": "13.1.4",
50
+ "chromatic": "13.2.0",
51
51
  "codemirror": "6.0.2",
52
52
  "cors": "^2.8.5",
53
53
  "cross-env": "^10.0.0",
@@ -64,15 +64,15 @@
64
64
  "normalize.css": "8.0.1",
65
65
  "path": "0.12.7",
66
66
  "prettier": "3.6.2",
67
- "sass": "1.92.1",
68
- "semantic-release": "24.2.8",
69
- "start-server-and-test": "2.1.0",
70
- "storybook": "9.1.5",
71
- "storybook-addon-pseudo-states": "9.1.5",
67
+ "sass": "1.93.0",
68
+ "semantic-release": "24.2.9",
69
+ "start-server-and-test": "2.1.2",
70
+ "storybook": "9.1.7",
71
+ "storybook-addon-pseudo-states": "9.1.7",
72
72
  "storybook-vue3-router": "^6.0.2",
73
73
  "typescript": "5.2.2",
74
74
  "uuid": "13.0.0",
75
- "vite": "7.1.5",
75
+ "vite": "7.1.6",
76
76
  "vite-plugin-dts": "^4.1.0",
77
77
  "vite-plugin-mkcert": "1.17.8",
78
78
  "vite-plugin-pages": "0.33.1",
@@ -52,5 +52,11 @@
52
52
 
53
53
  --bms-disabled-color: var(--bms-grey-50);
54
54
  --bms-font-color: var(--bms-grey-100);
55
+
56
+ --bms-z-index-below: -10;
57
+ --bms-z-index-base: 0;
58
+ --bms-z-index-fixed: 10;
59
+ --bms-z-index-tooltip: 20;
60
+ --bms-z-index-modal: 30;
55
61
  }
56
62
  }
@@ -130,7 +130,7 @@ const style = computed(() => {
130
130
  max-height: 30rem;
131
131
  position: absolute;
132
132
  overflow: hidden;
133
- z-index: 20;
133
+ z-index: var(--bms-z-index-tooltip);
134
134
  filter: drop-shadow(0 0 0.8rem var(--bms-shadow-color));
135
135
  color: var(--bms-font-color);
136
136
  transform: var(--bms-tooltip-transform);
@@ -15,6 +15,7 @@
15
15
  :small="small"
16
16
  @select="(option: any) => emits('select', option)"
17
17
  @add-new-option="(newOption: string) => emits('addNewOption', newOption)"
18
+ @input="(e: InputEvent) => emits('input', e)"
18
19
  >
19
20
  <template #icon-start v-if="currentOptionIcon">
20
21
  <span
@@ -60,9 +61,11 @@ const props = withDefaults(defineProps<Props>(), {
60
61
  const modelValue = defineModel<string>('modelValue', {
61
62
  default: null,
62
63
  });
64
+
63
65
  const emits = defineEmits<{
64
66
  addNewOption: [newOption: string];
65
67
  select: [option: InputOption];
68
+ input: [e: InputEvent];
66
69
  }>();
67
70
 
68
71
  const currentOptionIcon = computed(() => {
@@ -37,4 +37,30 @@ describe('BmsInputNumber', () => {
37
37
  await nextTick();
38
38
  expect(wrapper.emitted()['update:modelValue']).toBeUndefined();
39
39
  });
40
+
41
+ it('should try limit of the input when value change', async () => {
42
+ const { wrapper, inputElement } = factory({
43
+ modelValue: 8,
44
+ disabled: true,
45
+ max: 10,
46
+ min: 5,
47
+ });
48
+
49
+ expect((wrapper.vm as any).internalErrors.length).toBe(0);
50
+ await wrapper.setProps({ modelValue: 2 });
51
+ await nextTick();
52
+
53
+ expect((wrapper.vm as any).internalErrors.length).toBe(1);
54
+ expect((wrapper.vm as any).internalErrors[0]).toBe(
55
+ 'Valeur inférieure au minimum autorisé (min : 5)',
56
+ );
57
+
58
+ await wrapper.setProps({ modelValue: 15 });
59
+ await nextTick();
60
+
61
+ expect((wrapper.vm as any).internalErrors.length).toBe(1);
62
+ expect((wrapper.vm as any).internalErrors[0]).toBe(
63
+ 'Valeur supérieure au maximum autorisé (max : 10)',
64
+ );
65
+ });
40
66
  });
@@ -3,6 +3,7 @@ import { within } from 'storybook/test';
3
3
  import { BookOpen, CloudLightning } from 'lucide-vue-next';
4
4
 
5
5
  import template from '@/documentation/template_field_dependency.mdx';
6
+ import { ref } from 'vue';
6
7
 
7
8
  export default {
8
9
  parameters: {
@@ -16,7 +17,9 @@ export default {
16
17
 
17
18
  const Template = (args) => ({
18
19
  setup() {
19
- return { args };
20
+ const modelValue = ref(args.modelValue);
21
+ const modelValueSmall = ref(args.modelValueSmall);
22
+ return { args, modelValue, modelValueSmall };
20
23
  },
21
24
  components: {
22
25
  BmsInputNumber,
@@ -24,12 +27,12 @@ const Template = (args) => ({
24
27
  CloudLightning,
25
28
  },
26
29
  template: `
27
- <BmsInputNumber v-bind="args">
30
+ <BmsInputNumber v-bind="args" v-model="modelValue">
28
31
  <template v-if="args.iconStart" #icon-start><BookOpen/></template>
29
32
  <template v-if="args.iconEnd" #icon-end><CloudLightning/></template>
30
33
  </BmsInputNumber>
31
34
  <br/>
32
- <BmsInputNumber v-bind="{...args, small:true}">
35
+ <BmsInputNumber v-bind="{...args, small:true}" v-model="modelValueSmall">
33
36
  <template v-if="args.iconStart" #icon-start><BookOpen/></template>
34
37
  <template v-if="args.iconEnd" #icon-end><CloudLightning/></template>
35
38
  </BmsInputNumber>
@@ -47,12 +50,14 @@ export const WithValue = Template.bind({});
47
50
  WithValue.args = {
48
51
  label: 'My label',
49
52
  modelValue: 10,
53
+ modelValueSmall: 10,
50
54
  };
51
55
 
52
56
  export const Disabled = Template.bind({});
53
57
  Disabled.args = {
54
58
  label: 'My label',
55
59
  modelValue: 10,
60
+ modelValueSmall: 10,
56
61
  disabled: true,
57
62
  };
58
63
 
@@ -60,14 +65,26 @@ export const WithIcons = Template.bind({});
60
65
  WithIcons.args = {
61
66
  label: 'My label',
62
67
  modelValue: 10,
68
+ modelValueSmall: 10,
63
69
  iconStart: true,
64
70
  iconEnd: true,
65
71
  };
66
72
 
73
+ export const WithLimitExceeded = Template.bind({});
74
+ WithLimitExceeded.args = {
75
+ label: 'My label',
76
+ modelValue: 10,
77
+ modelValueSmall: 2,
78
+ min: 5,
79
+ max: 8,
80
+ errors: [{ label: 'Error 1' }],
81
+ };
82
+
67
83
  export const WithErrors = Template.bind({});
68
84
  WithErrors.args = {
69
85
  label: 'My label',
70
86
  modelValue: 10,
87
+ modelValueSmall: 10,
71
88
  errors: ['Error 1', 'Error 2'],
72
89
  };
73
90
 
@@ -8,14 +8,16 @@
8
8
  :helperText="helperText"
9
9
  :placeholder="placeholder"
10
10
  :captions="captions"
11
- :errors="errors"
11
+ :errors="computedErrors"
12
12
  :inputType="InputType.NUMBER"
13
+ :min="min"
14
+ :max="max"
13
15
  @input="onInput"
14
16
  />
15
17
  </template>
16
18
 
17
19
  <script lang="ts" setup>
18
- import { Ref, computed, ref } from 'vue';
20
+ import { Ref, computed, ref, watch, onMounted } from 'vue';
19
21
  import { Caption } from '@/models/caption.model';
20
22
  import BmsInputText from '@/components/form/BmsInputText.vue';
21
23
  import { InputType } from '@/models';
@@ -28,8 +30,8 @@ export interface Props {
28
30
  disabled?: boolean;
29
31
  helperText?: string;
30
32
  placeholder?: string;
31
- captions?: string[] | Caption[];
32
- errors?: string[] | Caption[];
33
+ captions?: (string | Caption)[];
34
+ errors?: (string | Caption)[];
33
35
  max?: number;
34
36
  min?: number;
35
37
  }
@@ -42,6 +44,17 @@ const props = withDefaults(defineProps<Props>(), {
42
44
 
43
45
  const input: Ref<HTMLElement | null> = ref(null);
44
46
 
47
+ const internalErrors: Ref<(string | Caption)[]> = ref([]);
48
+ const computedErrors: Ref<(string | Caption)[]> = computed(() => {
49
+ return props.errors
50
+ ? internalErrors.value.concat(props.errors)
51
+ : internalErrors.value;
52
+ });
53
+
54
+ onMounted(() => {
55
+ checkLimit();
56
+ });
57
+
45
58
  const $emits = defineEmits<{
46
59
  (e: 'update:modelValue', value: number): void;
47
60
  }>();
@@ -55,6 +68,20 @@ const classes = computed(() => {
55
68
  return { 'is-error': props.errors?.length, 'is-disabled': props.disabled };
56
69
  });
57
70
 
71
+ const checkLimit = () => {
72
+ internalErrors.value = [];
73
+ if (props.min !== undefined && props.modelValue < props.min) {
74
+ internalErrors.value = [
75
+ 'Valeur inférieure au minimum autorisé (min : ' + props.min + ')',
76
+ ];
77
+ }
78
+ if (props.max !== undefined && props.modelValue > props.max) {
79
+ internalErrors.value = [
80
+ 'Valeur supérieure au maximum autorisé (max : ' + props.max + ')',
81
+ ];
82
+ }
83
+ };
84
+
58
85
  const setFocus = () => {
59
86
  if (input.value) {
60
87
  input.value.focus();
@@ -64,4 +91,9 @@ const setFocus = () => {
64
91
  defineExpose({
65
92
  setFocus,
66
93
  });
94
+
95
+ watch(
96
+ () => props.modelValue,
97
+ () => checkLimit(),
98
+ );
67
99
  </script>
@@ -26,7 +26,7 @@ export interface Props {
26
26
  name: string;
27
27
  label?: string;
28
28
  disabled?: boolean;
29
- errors?: string[] | Caption[];
29
+ errors?: (string | Caption)[];
30
30
  required?: boolean;
31
31
  }
32
32
 
@@ -36,6 +36,31 @@ describe('BmsInputText', () => {
36
36
  expect(wrapper.emitted()['update:modelValue']).toBeUndefined();
37
37
  });
38
38
 
39
+ it('should try limit of the input when value change', async () => {
40
+ const { wrapper, inputElement } = factory({
41
+ modelValue: 'toto',
42
+ disabled: true,
43
+ maxlength: 5,
44
+ minlength: 2,
45
+ });
46
+
47
+ expect((wrapper.vm as any).internalErrors.length).toBe(0);
48
+ await wrapper.setProps({ modelValue: 'superToto' });
49
+ await nextTick();
50
+
51
+ expect((wrapper.vm as any).internalErrors.length).toBe(1);
52
+ expect((wrapper.vm as any).internalErrors[0]).toBe(
53
+ 'Longueur supérieure au maximum autorisé (max:5)',
54
+ );
55
+ await wrapper.setProps({ modelValue: 't' });
56
+ await nextTick();
57
+
58
+ expect((wrapper.vm as any).internalErrors.length).toBe(1);
59
+ expect((wrapper.vm as any).internalErrors[0]).toBe(
60
+ 'Longueur inférieur au minimum autorisé (min:2)',
61
+ );
62
+ });
63
+
39
64
  it('should emit blur event for form validation', async () => {
40
65
  const { wrapper, inputElement } = factory({
41
66
  modelValue: 'toto',
@@ -2,6 +2,7 @@ import BmsInputText from '@/components/form/BmsInputText.vue';
2
2
  import { within } from 'storybook/test';
3
3
  import { BookOpen, CloudLightning } from 'lucide-vue-next';
4
4
  import template from '@/documentation/template_field_dependency.mdx';
5
+ import { ref } from 'vue';
5
6
 
6
7
  export default {
7
8
  title: 'Composants/form/InputText',
@@ -15,7 +16,9 @@ export default {
15
16
 
16
17
  const Template = (args) => ({
17
18
  setup() {
18
- return { args };
19
+ const modelValue = ref(args.modelValue);
20
+ const modelValueSmall = ref(args.modelValueSmall);
21
+ return { args, modelValue, modelValueSmall };
19
22
  },
20
23
  components: {
21
24
  BmsInputText,
@@ -23,12 +26,12 @@ const Template = (args) => ({
23
26
  CloudLightning,
24
27
  },
25
28
  template: `
26
- <BmsInputText v-bind="args">
29
+ <BmsInputText v-bind="args" v-model="modelValue">
27
30
  <template v-if="args.iconStart" #icon-start><BookOpen/></template>
28
31
  <template v-if="args.iconEnd" #icon-end><CloudLightning/></template>
29
32
  </BmsInputText>
30
33
  <br/>
31
- <BmsInputText v-bind="{...args, small:true}">
34
+ <BmsInputText v-bind="{...args, small:true}" v-model="modelValueSmall">
32
35
  <template v-if="args.iconStart" #icon-start><BookOpen/></template>
33
36
  <template v-if="args.iconEnd" #icon-end><CloudLightning/></template>
34
37
  </BmsInputText>
@@ -46,12 +49,14 @@ export const WithValue = Template.bind({});
46
49
  WithValue.args = {
47
50
  label: 'My label',
48
51
  modelValue: 'Une valeur',
52
+ modelValueSmall: 'Une valeur',
49
53
  };
50
54
 
51
55
  export const Disabled = Template.bind({});
52
56
  Disabled.args = {
53
57
  label: 'My label',
54
58
  modelValue: 'Une valeur',
59
+ modelValueSmall: 'Une valeur',
55
60
  disabled: true,
56
61
  };
57
62
 
@@ -59,20 +64,40 @@ export const WithIcons = Template.bind({});
59
64
  WithIcons.args = {
60
65
  label: 'My label',
61
66
  modelValue: 'Une valeur',
67
+ modelValueSmall: 'Une valeur',
62
68
  iconStart: true,
63
69
  iconEnd: true,
64
70
  };
65
71
 
72
+ export const WithLimitEqual = Template.bind({});
73
+ WithLimitEqual.args = {
74
+ label: 'My label',
75
+ modelValue: 'Un texte pilpoil',
76
+ modelValueSmall: 'too short',
77
+ maxlength: 16,
78
+ };
79
+
80
+ export const WithLimitExceeded = Template.bind({});
81
+ WithLimitExceeded.args = {
82
+ label: 'My label',
83
+ modelValue: 'Une texte trop long pour la borne max',
84
+ modelValueSmall: 'too short',
85
+ maxlength: 15,
86
+ minlength: 10,
87
+ };
88
+
66
89
  export const WithErrors = Template.bind({});
67
90
  WithErrors.args = {
68
91
  label: 'My label',
69
92
  modelValue: 'Une valeur',
93
+ modelValueSmall: 'Une valeur',
70
94
  errors: ['Error 1', 'Error 2'],
71
95
  };
72
96
 
73
97
  export const WithFocusState = {
74
98
  args: {
75
99
  modelValue: '',
100
+ modelValueSmall: '',
76
101
  },
77
102
 
78
103
  play: async ({ canvasElement }) => {
@@ -1,18 +1,22 @@
1
1
  <template>
2
- <field v-bind="$props">
2
+ <field v-bind="$props" :captions="computedCaptions" :errors="computedErrors">
3
3
  <RawInputText
4
4
  ref="input"
5
5
  :type="inputType"
6
6
  :modelValue="modelValue"
7
+ @update:model-value="(val) => $emits('update:modelValue', val)"
7
8
  :required="required"
8
9
  :placeholder="placeholder"
9
10
  :disabled="disabled"
10
- :errors="errors"
11
+ :errors="computedErrors"
11
12
  :hasDate="false"
12
13
  :small="small"
14
+ :min="min"
15
+ :max="max"
16
+ :minlength="minlength"
17
+ :maxlength="maxlength"
13
18
  @blur="$emits('blur')"
14
- @input="onInput"
15
- @keyup="onInput"
19
+ @focus="$emits('focus')"
16
20
  >
17
21
  <template #icon-start>
18
22
  <slot name="icon-start"></slot>
@@ -25,9 +29,9 @@
25
29
  </template>
26
30
 
27
31
  <script lang="ts" setup>
28
- import { type Ref, ref } from 'vue';
32
+ import { computed, onMounted, type Ref, ref, watch } from 'vue';
29
33
  import RawInputText from '@/components/form/RawInputText.vue';
30
- import { InputType } from '@/models';
34
+ import { Caption, InputType, StatusType } from '@/models';
31
35
  import type { FieldComponentProps } from '@/plugins/field/field-component.model';
32
36
 
33
37
  export interface Props extends FieldComponentProps {
@@ -38,6 +42,10 @@ export interface Props extends FieldComponentProps {
38
42
  | InputType.DATETIME;
39
43
  modelValue: string | number;
40
44
  placeholder?: string;
45
+ min?: number;
46
+ max?: number;
47
+ minlength?: number;
48
+ maxlength?: number;
41
49
  }
42
50
 
43
51
  const props = withDefaults(defineProps<Props>(), {
@@ -48,12 +56,65 @@ const props = withDefaults(defineProps<Props>(), {
48
56
  });
49
57
 
50
58
  const input: Ref<HTMLElement | null> = ref(null);
59
+ const internalErrors: Ref<(string | Caption)[]> = ref([]);
60
+ const computedErrors: Ref<(string | Caption)[]> = computed(() => {
61
+ return props.errors
62
+ ? internalErrors.value.concat(props.errors)
63
+ : internalErrors.value;
64
+ });
65
+ const internalCaptions: Ref<(string | Caption)[]> = ref([]);
66
+ const computedCaptions: Ref<(string | Caption)[]> = computed(() => {
67
+ return props.captions
68
+ ? internalCaptions.value.concat(props.captions)
69
+ : internalCaptions.value;
70
+ });
71
+
72
+ onMounted(() => {
73
+ checkLimit();
74
+ });
51
75
 
52
76
  const $emits = defineEmits<{
53
- (e: 'update:modelValue', value: string): void;
54
- (e: 'blur'): void;
77
+ 'update:modelValue': [value: string];
78
+ blur: [];
79
+ focus: [];
55
80
  }>();
56
81
 
82
+ const onInput = (e: Event) => {
83
+ if (!props.disabled)
84
+ $emits('update:modelValue', (e?.target as HTMLInputElement).value);
85
+ };
86
+
87
+ const checkLimit = () => {
88
+ internalErrors.value = [];
89
+ internalCaptions.value = [];
90
+ if (
91
+ props.inputType === InputType.TEXT &&
92
+ typeof props.modelValue === 'string'
93
+ ) {
94
+ if (
95
+ props.minlength !== undefined &&
96
+ props.modelValue.length < props.minlength
97
+ ) {
98
+ internalErrors.value = [
99
+ 'Longueur inférieur au minimum autorisé (min:' + props.minlength + ')',
100
+ ];
101
+ }
102
+ if (props.maxlength !== undefined) {
103
+ if (props.modelValue.length > props.maxlength) {
104
+ internalErrors.value = [
105
+ `Longueur supérieure au maximum autorisé (max:${props.maxlength})`,
106
+ ];
107
+ } else if (props.modelValue.length === props.maxlength) {
108
+ internalCaptions.value = [
109
+ {
110
+ label: `Attention, vous avez atteint la limite de ${props.maxlength} caractères.`,
111
+ mode: StatusType.Warning,
112
+ },
113
+ ];
114
+ }
115
+ }
116
+ }
117
+ };
57
118
  const setFocus = () => {
58
119
  if (input.value) {
59
120
  (input.value as any).setFocus();
@@ -64,8 +125,8 @@ defineExpose({
64
125
  setFocus,
65
126
  });
66
127
 
67
- const onInput = (e: Event) => {
68
- if (!props.disabled)
69
- $emits('update:modelValue', (e?.target as HTMLInputElement).value);
70
- };
128
+ watch(
129
+ () => props.modelValue,
130
+ () => checkLimit(),
131
+ );
71
132
  </script>