allaw-ui 2.3.4 → 2.3.5

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.
@@ -10,6 +10,7 @@
10
10
  .Input-title-container {
11
11
  display: flex;
12
12
  align-items: center;
13
+ min-height: 78px;
13
14
  }
14
15
 
15
16
  .Input-required {
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ export interface VerificationCodeInputProps {
3
+ numInputs: number;
4
+ allowedChars?: "numeric" | "alphabetic" | "alphanumeric";
5
+ size?: "small" | "medium" | "large";
6
+ onChange?: (value: string) => void;
7
+ onError?: (error: string | null) => void;
8
+ onComplete?: (value: string) => void;
9
+ testError?: boolean;
10
+ }
11
+ declare const VerificationCodeInput: React.FC<VerificationCodeInputProps>;
12
+ export default VerificationCodeInput;
@@ -0,0 +1,169 @@
1
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
2
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
3
+ if (ar || !(i in from)) {
4
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
5
+ ar[i] = from[i];
6
+ }
7
+ }
8
+ return to.concat(ar || Array.prototype.slice.call(from));
9
+ };
10
+ import React, { useState, useEffect, useRef } from "react";
11
+ import styles from "./VerificationCodeInput.module.css";
12
+ import TinyInfo from "../typography/TinyInfo";
13
+ var VerificationCodeInput = function (_a) {
14
+ var numInputs = _a.numInputs, _b = _a.allowedChars, allowedChars = _b === void 0 ? "numeric" : _b, _c = _a.size, size = _c === void 0 ? "large" : _c, onChange = _a.onChange, onError = _a.onError, onComplete = _a.onComplete, _d = _a.testError, testError = _d === void 0 ? false : _d;
15
+ var _e = useState(Array(numInputs).fill("")), values = _e[0], setValues = _e[1];
16
+ var _f = useState(""), error = _f[0], setError = _f[1];
17
+ var inputRefs = useRef(Array(numInputs).fill(null));
18
+ useEffect(function () {
19
+ setValues(Array(numInputs).fill(""));
20
+ inputRefs.current = Array(numInputs).fill(null);
21
+ setTimeout(function () {
22
+ var _a;
23
+ (_a = inputRefs.current[0]) === null || _a === void 0 ? void 0 : _a.focus();
24
+ }, 0);
25
+ }, [numInputs]);
26
+ useEffect(function () {
27
+ if (testError) {
28
+ setError("Code de vérification invalide");
29
+ onError === null || onError === void 0 ? void 0 : onError("Code de vérification invalide");
30
+ }
31
+ else {
32
+ setError("");
33
+ onError === null || onError === void 0 ? void 0 : onError(null);
34
+ }
35
+ }, [testError, onError]);
36
+ var validateAllInputs = function () {
37
+ var _a;
38
+ var fullValue = values.join("");
39
+ // console.log("Attempting validation with value:", fullValue);
40
+ if (fullValue.length === numInputs) {
41
+ if (testError) {
42
+ // console.log("Showing error state");
43
+ setError("Code de vérification invalide");
44
+ onError === null || onError === void 0 ? void 0 : onError("Code de vérification invalide");
45
+ return;
46
+ }
47
+ // console.log("Code validation successful:", fullValue);
48
+ setError("");
49
+ onError === null || onError === void 0 ? void 0 : onError(null);
50
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete(fullValue);
51
+ (_a = inputRefs.current[numInputs - 1]) === null || _a === void 0 ? void 0 : _a.blur();
52
+ }
53
+ };
54
+ var handleInputChange = function (index, value) {
55
+ var _a, _b, _c, _d;
56
+ if (value.length > 1) {
57
+ var pastedChars = value.split("");
58
+ var validChars = pastedChars
59
+ .filter(function (char) { return validateInput(char, allowedChars); })
60
+ .slice(0, numInputs - index);
61
+ if (validChars.length > 0) {
62
+ var newValues_1 = __spreadArray([], values, true);
63
+ validChars.forEach(function (char, i) {
64
+ if (index + i < numInputs) {
65
+ newValues_1[index + i] = char;
66
+ }
67
+ });
68
+ setValues(newValues_1);
69
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValues_1.join(""));
70
+ var nextEmptyIndex = newValues_1.findIndex(function (val, i) { return i >= index && !val; });
71
+ var focusIndex = nextEmptyIndex === -1 ? numInputs - 1 : nextEmptyIndex;
72
+ (_a = inputRefs.current[focusIndex]) === null || _a === void 0 ? void 0 : _a.focus();
73
+ if (nextEmptyIndex === -1) {
74
+ validateAllInputs();
75
+ (_b = inputRefs.current[numInputs - 1]) === null || _b === void 0 ? void 0 : _b.blur();
76
+ }
77
+ return;
78
+ }
79
+ }
80
+ if (!validateInput(value, allowedChars)) {
81
+ return;
82
+ }
83
+ var newValues = __spreadArray([], values, true);
84
+ newValues[index] = value;
85
+ setValues(newValues);
86
+ if (value === "")
87
+ return;
88
+ setError("");
89
+ onError === null || onError === void 0 ? void 0 : onError(null);
90
+ var fullValue = newValues.join("");
91
+ onChange === null || onChange === void 0 ? void 0 : onChange(fullValue);
92
+ if (index < numInputs - 1) {
93
+ (_c = inputRefs.current[index + 1]) === null || _c === void 0 ? void 0 : _c.focus();
94
+ }
95
+ else if (index === numInputs - 1 && value !== "") {
96
+ // console.log("Last input filled, triggering validation");
97
+ validateAllInputs();
98
+ (_d = inputRefs.current[index]) === null || _d === void 0 ? void 0 : _d.blur();
99
+ }
100
+ };
101
+ var handleKeyDown = function (index, e) {
102
+ var _a;
103
+ if (e.key === "Backspace" && values[index] === "" && index > 0) {
104
+ (_a = inputRefs.current[index - 1]) === null || _a === void 0 ? void 0 : _a.focus();
105
+ var newValues = __spreadArray([], values, true);
106
+ newValues[index - 1] = "";
107
+ setValues(newValues);
108
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValues.join(""));
109
+ }
110
+ };
111
+ var handleBlur = function () {
112
+ setTimeout(function () {
113
+ var isStillFocused = inputRefs.current.some(function (ref) { return ref === document.activeElement; });
114
+ if (!isStillFocused) {
115
+ // console.log("All inputs lost focus, checking validation");
116
+ validateAllInputs();
117
+ }
118
+ }, 0);
119
+ };
120
+ var handlePaste = function (e) {
121
+ var _a, _b;
122
+ e.preventDefault();
123
+ var pastedText = e.clipboardData.getData("text");
124
+ // console.log("Pasted text:", pastedText);
125
+ var validChars = pastedText
126
+ .split("")
127
+ .filter(function (char) { return validateInput(char, allowedChars); })
128
+ .slice(0, numInputs);
129
+ if (validChars.length > 0) {
130
+ var newValues_2 = Array(numInputs).fill("");
131
+ validChars.forEach(function (char, i) {
132
+ if (i < numInputs) {
133
+ newValues_2[i] = char;
134
+ }
135
+ });
136
+ setValues(newValues_2);
137
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValues_2.join(""));
138
+ if (validChars.length >= numInputs) {
139
+ // console.log("All inputs filled by paste, triggering validation");
140
+ validateAllInputs();
141
+ inputRefs.current.forEach(function (input) { return input === null || input === void 0 ? void 0 : input.blur(); });
142
+ (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.blur();
143
+ }
144
+ else {
145
+ var nextIndex = validChars.length;
146
+ (_b = inputRefs.current[nextIndex]) === null || _b === void 0 ? void 0 : _b.focus();
147
+ }
148
+ }
149
+ };
150
+ var validateInput = function (value, allowedChars) {
151
+ var regex = allowedChars === "numeric"
152
+ ? /^[0-9]*$/
153
+ : allowedChars === "alphabetic"
154
+ ? /^[a-zA-Z]*$/
155
+ : /^[a-zA-Z0-9]*$/;
156
+ return regex.test(value);
157
+ };
158
+ var renderInputs = function () {
159
+ return values.map(function (value, index) { return (React.createElement("input", { key: index, className: "".concat(styles.input, " ").concat(styles[size], " ").concat(value ? styles.filledInput : ""), value: value, onChange: function (e) { return handleInputChange(index, e.target.value); }, onKeyDown: function (e) { return handleKeyDown(index, e); }, onPaste: index === 0 ? handlePaste : undefined, onBlur: handleBlur, maxLength: 1, inputMode: allowedChars === "numeric" ? "numeric" : "text", pattern: allowedChars === "numeric"
160
+ ? "[0-9]*"
161
+ : allowedChars === "alphabetic"
162
+ ? "[a-zA-Z]*"
163
+ : "[a-zA-Z0-9]*", ref: function (input) { return (inputRefs.current[index] = input); } })); });
164
+ };
165
+ return (React.createElement("div", { className: styles.container },
166
+ React.createElement("div", { className: styles.inputsContainer }, renderInputs()),
167
+ error && (React.createElement(TinyInfo, { variant: "medium12", color: "actions-error", text: error }))));
168
+ };
169
+ export default VerificationCodeInput;
@@ -0,0 +1,84 @@
1
+ /* VerificationCodeInput.module.css */
2
+ @import "../../../styles/colors.css";
3
+
4
+ .container {
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: 8px;
8
+ width: fit-content;
9
+ }
10
+
11
+ .inputsContainer {
12
+ display: flex;
13
+ gap: 8px;
14
+ width: fit-content;
15
+ }
16
+
17
+ .input {
18
+ border: 2px solid var(--grey-venom);
19
+ border-radius: 8px;
20
+ text-align: center;
21
+ font-size: 16px;
22
+ outline: none;
23
+ color: var(--noir);
24
+ transition: border-color 0.2s ease;
25
+ }
26
+
27
+ .input:hover {
28
+ border-color: var(--venom-grey-dark);
29
+ }
30
+
31
+ .input:focus-within {
32
+ border-color: var(--mid-grey);
33
+ }
34
+
35
+ .currentInput {
36
+ border-color: #25beeb;
37
+ position: relative;
38
+ }
39
+
40
+ .currentInput::after {
41
+ content: "";
42
+ position: absolute;
43
+ top: 50%;
44
+ left: 50%;
45
+ transform: translate(-50%, -50%);
46
+ width: 2px;
47
+ height: 60%;
48
+ background-color: #25beeb;
49
+ animation: blink 1s infinite;
50
+ }
51
+
52
+ .filledInput {
53
+ border-color: var(--bleu-allaw);
54
+ }
55
+
56
+ @keyframes blink {
57
+ 0% {
58
+ opacity: 1;
59
+ }
60
+ 50% {
61
+ opacity: 0;
62
+ }
63
+ 100% {
64
+ opacity: 1;
65
+ }
66
+ }
67
+
68
+ /* Tailles */
69
+ .small {
70
+ width: 40px;
71
+ height: 40px;
72
+ }
73
+
74
+ .medium {
75
+ width: 48px;
76
+ height: 48px;
77
+ font-size: 18px;
78
+ }
79
+
80
+ .large {
81
+ width: 56px;
82
+ height: 56px;
83
+ font-size: 20px;
84
+ }
@@ -0,0 +1,59 @@
1
+ declare namespace _default {
2
+ export let title: string;
3
+ export { VerificationCodeInput as component };
4
+ export let tags: string[];
5
+ export namespace parameters {
6
+ namespace controls {
7
+ let expanded: boolean;
8
+ }
9
+ }
10
+ export namespace argTypes {
11
+ namespace size {
12
+ let control: string;
13
+ let options: string[];
14
+ let description: string;
15
+ let defaultValue: string;
16
+ }
17
+ namespace allowedChars {
18
+ let control_1: string;
19
+ export { control_1 as control };
20
+ let options_1: string[];
21
+ export { options_1 as options };
22
+ let description_1: string;
23
+ export { description_1 as description };
24
+ let defaultValue_1: string;
25
+ export { defaultValue_1 as defaultValue };
26
+ export namespace table {
27
+ export namespace defaultValue_2 {
28
+ let summary: string;
29
+ }
30
+ export { defaultValue_2 as defaultValue };
31
+ }
32
+ }
33
+ namespace numInputs {
34
+ export namespace control_2 {
35
+ let type: string;
36
+ let min: number;
37
+ let max: number;
38
+ let step: number;
39
+ }
40
+ export { control_2 as control };
41
+ let description_2: string;
42
+ export { description_2 as description };
43
+ let defaultValue_3: number;
44
+ export { defaultValue_3 as defaultValue };
45
+ }
46
+ namespace testError {
47
+ let control_3: string;
48
+ export { control_3 as control };
49
+ let description_3: string;
50
+ export { description_3 as description };
51
+ let defaultValue_4: boolean;
52
+ export { defaultValue_4 as defaultValue };
53
+ }
54
+ }
55
+ }
56
+ export default _default;
57
+ export const Default: any;
58
+ export const WithError: any;
59
+ import VerificationCodeInput from "./VerificationCodeInput";
@@ -0,0 +1,72 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import React from "react";
13
+ import VerificationCodeInput from "./VerificationCodeInput";
14
+ export default {
15
+ title: "Components/Atoms/Inputs/VerificationCodeInput",
16
+ component: VerificationCodeInput,
17
+ tags: ["autodocs"],
18
+ parameters: {
19
+ controls: {
20
+ expanded: true,
21
+ },
22
+ },
23
+ argTypes: {
24
+ size: {
25
+ control: "select",
26
+ options: ["small", "medium", "large"],
27
+ description: "Taille des inputs",
28
+ defaultValue: "large",
29
+ },
30
+ allowedChars: {
31
+ control: "select",
32
+ options: ["numeric", "alphabetic", "alphanumeric"],
33
+ description: "Type de caractères autorisés",
34
+ defaultValue: "numeric",
35
+ table: {
36
+ defaultValue: { summary: "numeric" },
37
+ },
38
+ },
39
+ numInputs: {
40
+ control: {
41
+ type: "number",
42
+ min: 1,
43
+ max: 20,
44
+ step: 1,
45
+ },
46
+ description: "Nombre d'inputs",
47
+ defaultValue: 5,
48
+ },
49
+ testError: {
50
+ control: "boolean",
51
+ description: "Simuler une erreur de validation",
52
+ defaultValue: false,
53
+ },
54
+ },
55
+ };
56
+ var Template = function (args) { return React.createElement(VerificationCodeInput, __assign({}, args)); };
57
+ export var Default = Template.bind({});
58
+ Default.args = {
59
+ numInputs: 5,
60
+ };
61
+ export var WithError = Template.bind({});
62
+ WithError.args = {
63
+ numInputs: 5,
64
+ testError: true,
65
+ };
66
+ WithError.parameters = {
67
+ docs: {
68
+ description: {
69
+ story: "Simule un état d'erreur lors de la validation du code",
70
+ },
71
+ },
72
+ };
@@ -1,6 +1,8 @@
1
1
  export { default as Input } from "./Input";
2
2
  export { default as TextArea } from "./TextArea";
3
3
  export { default as SearchBar } from "./SearchBar";
4
+ export { default as VerificationCodeInput } from "./VerificationCodeInput";
4
5
  export type { InputProps, InputRef } from "./Input";
5
6
  export type { SearchBarProps } from "./SearchBar";
6
7
  export type { TextAreaProps, TextAreaRef } from "./TextArea";
8
+ export type { VerificationCodeInputProps } from "./VerificationCodeInput";
@@ -1,3 +1,4 @@
1
1
  export { default as Input } from "./Input";
2
2
  export { default as TextArea } from "./TextArea";
3
3
  export { default as SearchBar } from "./SearchBar";
4
+ export { default as VerificationCodeInput } from "./VerificationCodeInput";
package/dist/index.d.ts CHANGED
@@ -64,6 +64,8 @@ export { default as Breadcrumb } from "./components/molecules/breadcrumb/Breadcr
64
64
  export { default as ProCard } from "./components/molecules/proCard/ProCard";
65
65
  export { default as Pagination } from "./components/molecules/pagination/Pagination";
66
66
  export type { PaginationProps } from "./components/molecules/pagination/Pagination";
67
+ export { default as VerificationCodeInput } from "./components/atoms/inputs/VerificationCodeInput";
68
+ export type { VerificationCodeInputProps } from "./components/atoms/inputs/VerificationCodeInput";
67
69
  export { default as Banner } from "./components/molecules/banner/Banner";
68
70
  export type { BannerProps } from "./components/molecules/banner/Banner";
69
71
  export { default as FeatureCard } from "./components/atoms/featureCard/featureCard";
package/dist/index.js CHANGED
@@ -80,6 +80,8 @@ export { default as Breadcrumb } from "./components/molecules/breadcrumb/Breadcr
80
80
  export { default as ProCard } from "./components/molecules/proCard/ProCard";
81
81
  // Pagination
82
82
  export { default as Pagination } from "./components/molecules/pagination/Pagination";
83
+ // Verification Code Input
84
+ export { default as VerificationCodeInput } from "./components/atoms/inputs/VerificationCodeInput";
83
85
  // Storyblok component
84
86
  export { default as Banner } from "./components/molecules/banner/Banner";
85
87
  export { default as FeatureCard } from "./components/atoms/featureCard/featureCard";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "allaw-ui",
3
- "version": "2.3.4",
3
+ "version": "2.3.5",
4
4
  "description": "Composants UI pour l'application Allaw",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",