@ouestfrance/sipa-bms-ui 8.0.1 → 8.1.1
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/dist/components/form/BmsInputText.vue.d.ts +7 -1
- package/dist/components/form/BmsSearch.vue.d.ts +10 -2
- package/dist/components/form/RawAutocomplete.vue.d.ts +5 -1
- package/dist/components/form/RawInputText.vue.d.ts +2 -0
- package/dist/components/navigation/UiTenantSwitcher.vue.d.ts +10 -2
- package/dist/components/table/BmsTableFilters.vue.d.ts +10 -2
- package/dist/helpers/form.helper.d.ts +1 -0
- package/dist/helpers/form.helper.spec.d.ts +1 -0
- package/dist/helpers/index.d.ts +1 -0
- package/dist/sipa-bms-ui.css +13 -13
- package/dist/sipa-bms-ui.es.js +11 -7
- package/dist/sipa-bms-ui.es.js.map +1 -1
- package/dist/sipa-bms-ui.umd.js +11 -6
- package/dist/sipa-bms-ui.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/form/BmsInputText.spec.ts +12 -0
- package/src/components/form/BmsInputText.vue +8 -2
- package/src/components/form/RawInputText.vue +2 -0
- package/src/helpers/form.helper.spec.ts +33 -0
- package/src/helpers/form.helper.ts +2 -0
- package/src/helpers/index.ts +1 -0
- package/src/showroom/pages/forms.vue +27 -0
package/package.json
CHANGED
|
@@ -16,6 +16,7 @@ describe('BmsInputText', () => {
|
|
|
16
16
|
|
|
17
17
|
expect(inputElement.element.value).toStrictEqual('toto');
|
|
18
18
|
});
|
|
19
|
+
|
|
19
20
|
it('should react correctly on input', async () => {
|
|
20
21
|
const { wrapper, inputElement } = factory({ modelValue: 'toto' });
|
|
21
22
|
|
|
@@ -34,4 +35,15 @@ describe('BmsInputText', () => {
|
|
|
34
35
|
await nextTick();
|
|
35
36
|
expect(wrapper.emitted()['update:modelValue']).toBeUndefined();
|
|
36
37
|
});
|
|
38
|
+
|
|
39
|
+
it('should emit blur event for form validation', async () => {
|
|
40
|
+
const { wrapper, inputElement } = factory({
|
|
41
|
+
modelValue: 'toto',
|
|
42
|
+
disabled: true,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
inputElement.setValue('titi');
|
|
46
|
+
await nextTick();
|
|
47
|
+
expect(wrapper.emitted()['update:modelValue']).toBeUndefined();
|
|
48
|
+
});
|
|
37
49
|
});
|
|
@@ -17,11 +17,16 @@
|
|
|
17
17
|
:disabled="disabled"
|
|
18
18
|
:errors="errors"
|
|
19
19
|
:hasDate="false"
|
|
20
|
+
@blur="$emits('blur')"
|
|
20
21
|
@input="onInput"
|
|
21
22
|
@keyup="onInput"
|
|
22
23
|
>
|
|
23
|
-
<template #icon-start
|
|
24
|
-
|
|
24
|
+
<template #icon-start>
|
|
25
|
+
<slot name="icon-start"></slot>
|
|
26
|
+
</template>
|
|
27
|
+
<template #icon-end>
|
|
28
|
+
<slot name="icon-end"></slot>
|
|
29
|
+
</template>
|
|
25
30
|
</RawInputText>
|
|
26
31
|
</field>
|
|
27
32
|
</template>
|
|
@@ -60,6 +65,7 @@ const input: Ref<HTMLElement | null> = ref(null);
|
|
|
60
65
|
|
|
61
66
|
const $emits = defineEmits<{
|
|
62
67
|
(e: 'update:modelValue', value: string): void;
|
|
68
|
+
(e: 'blur'): void;
|
|
63
69
|
}>();
|
|
64
70
|
|
|
65
71
|
const setFocus = () => {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
:placeholder="placeholder"
|
|
15
15
|
:required="required"
|
|
16
16
|
:disabled="disabled"
|
|
17
|
+
@blur="$emits('blur')"
|
|
17
18
|
@input="onInput"
|
|
18
19
|
@keydown.up="$emits('keyUp')"
|
|
19
20
|
@keydown.down="$emits('keyDown')"
|
|
@@ -54,6 +55,7 @@ const input: Ref<HTMLElement | null> = ref(null);
|
|
|
54
55
|
const $emits = defineEmits<{
|
|
55
56
|
(e: 'update:modelValue', value: string): void;
|
|
56
57
|
(e: 'update:focus', value: boolean): void;
|
|
58
|
+
(e: 'blur'): void;
|
|
57
59
|
(e: 'keyUp'): void;
|
|
58
60
|
(e: 'keyDown'): void;
|
|
59
61
|
(e: 'keyEnter'): void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { BMS_FORM_VALID_URL_REGEX } from './form.helper';
|
|
2
|
+
import { describe, expect, test } from 'vitest';
|
|
3
|
+
|
|
4
|
+
describe('BMS_FORM_VALID_URL_REGEX', () => {
|
|
5
|
+
test.each([
|
|
6
|
+
// URLs valides
|
|
7
|
+
{ url: 'https://google.com', expected: true },
|
|
8
|
+
{ url: 'http://google.com', expected: true },
|
|
9
|
+
{ url: 'google.com', expected: true },
|
|
10
|
+
{ url: 'sub.domain.com', expected: true },
|
|
11
|
+
{ url: 'domain.com/path', expected: true },
|
|
12
|
+
{ url: 'domain.com/path/to/resource', expected: true },
|
|
13
|
+
{ url: 'domain.com/path-with-dash', expected: true },
|
|
14
|
+
{ url: 'domain.com/', expected: true },
|
|
15
|
+
{ url: 'domaine-avec-tiret.fr', expected: true },
|
|
16
|
+
{ url: 'ouest-france.fr/actualite', expected: true },
|
|
17
|
+
{ url: 'http://UPPERCASE.com', expected: true }, // domaine en majuscules
|
|
18
|
+
|
|
19
|
+
// URLs invalides
|
|
20
|
+
{ url: 'localhost:8080/actualite', expected: true },
|
|
21
|
+
{ url: '', expected: false },
|
|
22
|
+
{ url: 'not an url', expected: false },
|
|
23
|
+
{ url: 'http:/domain.com', expected: false }, // slash manquant
|
|
24
|
+
{ url: 'http://', expected: false }, // domaine manquant
|
|
25
|
+
{ url: 'domain', expected: false }, // pas d'extension
|
|
26
|
+
{ url: '.com', expected: false }, // pas de domaine
|
|
27
|
+
{ url: 'domain.toolongtld', expected: false }, // tld trop long
|
|
28
|
+
{ url: 'ftp://domain.com', expected: false }, // protocole non supporté
|
|
29
|
+
{ url: 'javascript:alert(1)', expected: false }, // injection JavaScript
|
|
30
|
+
])('should validate "$url" as $expected', ({ url, expected }) => {
|
|
31
|
+
expect(BMS_FORM_VALID_URL_REGEX.test(url)).toBe(expected);
|
|
32
|
+
});
|
|
33
|
+
});
|
package/src/helpers/index.ts
CHANGED
|
@@ -225,6 +225,18 @@
|
|
|
225
225
|
|
|
226
226
|
<hr />
|
|
227
227
|
|
|
228
|
+
<BmsInputText
|
|
229
|
+
ref="inputText1"
|
|
230
|
+
label="input whith form validation"
|
|
231
|
+
required
|
|
232
|
+
v-model="text2"
|
|
233
|
+
:captions="captionsText2"
|
|
234
|
+
@blur="onBlurMyInputText"
|
|
235
|
+
placeholder="This is a placeholder in url format"
|
|
236
|
+
/>
|
|
237
|
+
|
|
238
|
+
<hr />
|
|
239
|
+
|
|
228
240
|
<BmsSelect
|
|
229
241
|
label="select"
|
|
230
242
|
required
|
|
@@ -307,6 +319,7 @@ import {
|
|
|
307
319
|
BmsInputText,
|
|
308
320
|
BmsSelect,
|
|
309
321
|
BmsTextArea,
|
|
322
|
+
StatusType,
|
|
310
323
|
} from '@/index';
|
|
311
324
|
import BmsInputToggle from '@/components/form/BmsInputToggle.vue';
|
|
312
325
|
import BmsInputRadio from '@/components/form/BmsInputRadio.vue';
|
|
@@ -319,9 +332,12 @@ import BmsInputCheckboxCaption from '@/components/form/BmsInputCheckboxCaption.v
|
|
|
319
332
|
import BmsInputCheckboxCaptionGroup from '@/components/form/BmsInputCheckboxCaptionGroup.vue';
|
|
320
333
|
import { Copy } from 'lucide-vue-next';
|
|
321
334
|
import BmsIconButton from '@/components/button/BmsIconButton.vue';
|
|
335
|
+
import { BMS_FORM_VALID_URL_REGEX } from '@/helpers/form.helper';
|
|
322
336
|
|
|
323
337
|
const { success } = useNotifications();
|
|
324
338
|
const text = ref('');
|
|
339
|
+
const text2 = ref('');
|
|
340
|
+
const captionsText2 = ref();
|
|
325
341
|
const selected = ref('value1');
|
|
326
342
|
const selected2 = ref('');
|
|
327
343
|
const files: Ref<File[]> = ref([]);
|
|
@@ -366,6 +382,16 @@ const onSubmit = (e: any) => {
|
|
|
366
382
|
e.preventDefault();
|
|
367
383
|
success(text.value + ' ' + selected.value);
|
|
368
384
|
};
|
|
385
|
+
|
|
386
|
+
const onBlurMyInputText = () => {
|
|
387
|
+
if (!text2.value || BMS_FORM_VALID_URL_REGEX.test(text2.value)) {
|
|
388
|
+
captionsText2.value = [];
|
|
389
|
+
} else {
|
|
390
|
+
captionsText2.value = [
|
|
391
|
+
{ label: 'Veuillez entrer une URL valide', mode: StatusType.Warning },
|
|
392
|
+
];
|
|
393
|
+
}
|
|
394
|
+
};
|
|
369
395
|
</script>
|
|
370
396
|
|
|
371
397
|
<style lang="scss" scoped>
|
|
@@ -378,6 +404,7 @@ const onSubmit = (e: any) => {
|
|
|
378
404
|
display: flex;
|
|
379
405
|
gap: 8px;
|
|
380
406
|
}
|
|
407
|
+
|
|
381
408
|
hr {
|
|
382
409
|
border: none;
|
|
383
410
|
border-top: 3px double #333;
|