5htp-core 0.4.2 → 0.4.3
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/package.json +4 -12
- package/src/client/app/component.tsx +11 -2
- package/src/client/assets/css/components/button.less +10 -10
- package/src/client/assets/css/components/other.less +0 -1
- package/src/client/assets/css/core.less +0 -4
- package/src/client/assets/css/text/text.less +1 -2
- package/src/client/assets/css/text/titres.less +0 -5
- package/src/client/assets/css/utils/layouts.less +5 -5
- package/src/client/assets/css/utils/sizing.less +6 -6
- package/src/client/components/Dialog/card.tsx +1 -1
- package/src/client/components/button.tsx +1 -1
- package/src/client/components/containers/Popover/index.tsx +2 -2
- package/src/client/components/index.ts +5 -16
- package/src/client/components/inputv3/index.tsx +2 -5
- package/src/client/services/router/components/Page.tsx +1 -2
- package/src/client/services/router/components/router.tsx +4 -8
- package/src/client/services/router/request/api.ts +31 -52
- package/src/client/services/router/response/index.tsx +2 -0
- package/src/common/data/dates.ts +50 -6
- package/src/common/router/layouts.ts +14 -5
- package/src/common/router/response/page.ts +12 -6
- package/src/common/validation/validators.ts +0 -4
- package/src/server/app/container/config.ts +2 -1
- package/src/server/services/router/http/index.ts +16 -22
- package/src/server/services/router/response/page/index.tsx +0 -0
- package/src/client/assets/fonts/Inter/index.less +0 -77
- package/src/client/assets/fonts/Inter/latin-500.woff2 +0 -0
- package/src/client/assets/fonts/Inter/latin-600.woff2 +0 -0
- package/src/client/assets/fonts/Inter/latin-800.woff2 +0 -0
- package/src/client/assets/fonts/Inter/latin-ext-500.woff2 +0 -0
- package/src/client/assets/fonts/Inter/latin-ext-600.woff2 +0 -0
- package/src/client/assets/fonts/Inter/latin-ext-800.woff2 +0 -0
- package/src/client/assets/fonts/Rubik/cyrillic-ext.woff2 +0 -0
- package/src/client/assets/fonts/Rubik/cyrillic.woff2 +0 -0
- package/src/client/assets/fonts/Rubik/hebrew.woff2 +0 -0
- package/src/client/assets/fonts/Rubik/index.less +0 -30
- package/src/client/assets/fonts/Rubik/latin-ext.woff2 +0 -0
- package/src/client/assets/fonts/Rubik/latin.woff2 +0 -0
- package/src/client/components/Amount.tsx +0 -38
- package/src/client/components/Form_old/index.tsx +0 -450
- package/src/client/components/Form_old/index.tsx.old +0 -436
- package/src/client/components/dropdown.old/Manager.tsx +0 -164
- package/src/client/components/dropdown.old/getPosition.ts +0 -137
- package/src/client/components/dropdown.old/index.tsx +0 -99
- package/src/client/components/dropdown.old/popover.less +0 -56
- package/src/client/components/input/Base/Choix.ts +0 -48
- package/src/client/components/input/Base/index.tsx +0 -432
- package/src/client/components/input/BaseV2/index.tsx +0 -72
|
@@ -1,432 +0,0 @@
|
|
|
1
|
-
/*----------------------------------
|
|
2
|
-
- DEPENDANCES
|
|
3
|
-
----------------------------------*/
|
|
4
|
-
|
|
5
|
-
// Npm
|
|
6
|
-
import React from 'react';
|
|
7
|
-
import { ComponentChild, ComponentProps } from 'preact';
|
|
8
|
-
//import { RefObject } from 'preact';
|
|
9
|
-
|
|
10
|
-
// Composants généaux
|
|
11
|
-
import Bouton, { Props as TPropsBouton } from '@client/components/button';
|
|
12
|
-
|
|
13
|
-
/*----------------------------------
|
|
14
|
-
- TYPES PROPS
|
|
15
|
-
----------------------------------*/
|
|
16
|
-
|
|
17
|
-
// Egalement utilisé pour les infos des schémas de formulaire
|
|
18
|
-
export type TOptsChamp<TValeur> = {
|
|
19
|
-
|
|
20
|
-
titre?: ComponentChild,
|
|
21
|
-
label?: boolean, // false pour masquer le label
|
|
22
|
-
suffixeLabel?: ComponentChild,
|
|
23
|
-
aide?: string,
|
|
24
|
-
|
|
25
|
-
icone?: TIcons,
|
|
26
|
-
prefixe?: ComponentChild,
|
|
27
|
-
suffixe?: ComponentChild,
|
|
28
|
-
|
|
29
|
-
// Attributs
|
|
30
|
-
attrsChamp?: { [cle: string]: any },
|
|
31
|
-
attrsContChamp?: ComponentProps<"div">,
|
|
32
|
-
|
|
33
|
-
// Traitement valeur
|
|
34
|
-
opt?: true,
|
|
35
|
-
as?: string[], // Mapping personnalisé
|
|
36
|
-
// Executé après le validateur propre au type
|
|
37
|
-
valider?: (val: TValeur, formData?: unknown) => Promise<TValeur>,
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export type TBasePropsChamp<TValeur, TValeurDefaut, TValeurOut> = TOptsChamp<TValeur> & {
|
|
41
|
-
|
|
42
|
-
// onChange est async car les validateurs le sont aussi
|
|
43
|
-
onChange?: (valeur: TValeurOut) => Promise<void>,
|
|
44
|
-
valeur: TValeur | TValeurDefaut,
|
|
45
|
-
readOnly?: boolean,
|
|
46
|
-
// Si on doit afficher un indicateur de chargement à chaque modif de valeur
|
|
47
|
-
// ex: lorsque le onOhange lance une requete api, comme c'est le cas pour les switch de status
|
|
48
|
-
async?: boolean,
|
|
49
|
-
|
|
50
|
-
// Présentation
|
|
51
|
-
pur?: boolean,
|
|
52
|
-
autoFocus?: boolean,
|
|
53
|
-
size?: TComponentSize,
|
|
54
|
-
className?: string,
|
|
55
|
-
|
|
56
|
-
pied?: ComponentChild,
|
|
57
|
-
boutons?: TPropsBouton[] | false, // False = on désactive même les boutons par défaut (ex: <Number />)
|
|
58
|
-
erreurs?: string[], // sera converti en status
|
|
59
|
-
status?: ComponentChild | false,
|
|
60
|
-
vide?: string, // Erreur quand vide et requis
|
|
61
|
-
|
|
62
|
-
// A implémenter ?
|
|
63
|
-
/*refChamp?: RefObject<HTMLInputElement>,
|
|
64
|
-
disabled?: boolean,*/
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/*----------------------------------
|
|
68
|
-
- AUTRES TYPES
|
|
69
|
-
----------------------------------*/
|
|
70
|
-
|
|
71
|
-
export const propsDefautChampForm = {
|
|
72
|
-
label: true
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
type TBaseState<TValeur> = {
|
|
76
|
-
valeur: TValeur,
|
|
77
|
-
erreurs: string[],
|
|
78
|
-
focus: boolean,
|
|
79
|
-
chargement: boolean
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
type TOptsRendu = {
|
|
83
|
-
ecraser?: true | 'corpsChamp'
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
type TFuncRendu<TBasePropsChamp> = (composant: ComponentChild, propsRendu: Partial<TBasePropsChamp> & TOptsRendu) => React.JSX.Element
|
|
87
|
-
|
|
88
|
-
/*----------------------------------
|
|
89
|
-
- COMPOSANT
|
|
90
|
-
----------------------------------*/
|
|
91
|
-
// NOTE: Certaines configurations ont été retirées, car elles sont maitnenant déterminées automatiquement
|
|
92
|
-
// TValeur est déterminé via TPropsChamp
|
|
93
|
-
// config.valeurDefaut est déterminé via le state initial du champ
|
|
94
|
-
export default <TPropsChamp extends { valeur: unknown }, TValeurDefaut, TValeurOut>(
|
|
95
|
-
type: string,
|
|
96
|
-
config: {
|
|
97
|
-
saisieManuelle?: boolean,
|
|
98
|
-
valeurDefaut: TValeur,
|
|
99
|
-
transformer?: {
|
|
100
|
-
in: (val: TValeurOut) => TValeur,
|
|
101
|
-
out: (val: TValeur) => TValeurOut
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
// Met à disposition, au sein du composant du champ, les outils nécessaires au rendu du champ
|
|
105
|
-
build: (
|
|
106
|
-
props: TPropsChamp & TBasePropsChamp<TPropsChamp["valeur"], TValeurDefaut, TValeurOut>,
|
|
107
|
-
{ valeur, state, setState }: {
|
|
108
|
-
valeur: TPropsChamp["valeur"],
|
|
109
|
-
state: TBaseState,
|
|
110
|
-
setState: (state: TBaseState) => void
|
|
111
|
-
},
|
|
112
|
-
rendre: TFuncRendu<TBasePropsChamp<TPropsChamp["valeur"], TValeurDefaut, TValeurOut>>
|
|
113
|
-
) => React.JSX.Element
|
|
114
|
-
) => (
|
|
115
|
-
// Props initiales passées à l'instanciation du composant du champ
|
|
116
|
-
propsInit: TPropsChamp & TBasePropsChamp<TPropsChamp["valeur"], TValeurDefaut, TValeurOut>
|
|
117
|
-
) => {
|
|
118
|
-
|
|
119
|
-
// Empêche problèmes de référence
|
|
120
|
-
// Exemple: doublons className quand changement state
|
|
121
|
-
const { ...props } = propsInit;
|
|
122
|
-
|
|
123
|
-
const refChamp = React.useRef<HTMLInputElement>(null);
|
|
124
|
-
//const onglet = React.useContext(ContexteOnglets);
|
|
125
|
-
|
|
126
|
-
type TValeur = TPropsChamp["valeur"];
|
|
127
|
-
type TPropsCompletes = TPropsChamp & TBasePropsChamp<TPropsChamp["valeur"], TValeurDefaut, TValeurOut>
|
|
128
|
-
|
|
129
|
-
/*----------------------------------
|
|
130
|
-
- COMPLETION ATTRIBUTS
|
|
131
|
-
----------------------------------*/
|
|
132
|
-
|
|
133
|
-
// -------- Conteneur Champ --------
|
|
134
|
-
if (props.attrsContChamp === undefined) props.attrsContChamp = {}
|
|
135
|
-
const classeContChamp: string[] = ['contChamp col'];
|
|
136
|
-
|
|
137
|
-
if (props.attrsContChamp.className !== undefined)
|
|
138
|
-
classeContChamp.push(props.attrsContChamp.className);
|
|
139
|
-
|
|
140
|
-
if (props.className !== undefined)
|
|
141
|
-
classeContChamp.push(props.className);
|
|
142
|
-
|
|
143
|
-
// Indicateurs d'état
|
|
144
|
-
classeContChamp.push(type);
|
|
145
|
-
|
|
146
|
-
if (props.size !== undefined)
|
|
147
|
-
classeContChamp.push(props.size);
|
|
148
|
-
|
|
149
|
-
if (props.opt === true)
|
|
150
|
-
classeContChamp.push('opt');
|
|
151
|
-
if (props.erreurs !== undefined && props.erreurs.length !== 0)
|
|
152
|
-
classeContChamp.push('erreur');
|
|
153
|
-
|
|
154
|
-
// ------------- Champ -------------
|
|
155
|
-
if (props.attrsChamp === undefined) props.attrsChamp = {}
|
|
156
|
-
const classeChamp: string[] = ['champ'];
|
|
157
|
-
|
|
158
|
-
if (props.attrsChamp.className !== undefined)
|
|
159
|
-
classeChamp.push(props.attrsChamp.className);
|
|
160
|
-
|
|
161
|
-
if (props.pur === true)
|
|
162
|
-
classeChamp.push('pur');
|
|
163
|
-
|
|
164
|
-
// Placeholder
|
|
165
|
-
if (!props.attrsChamp.placeholder) {
|
|
166
|
-
if (props.aide && typeof props.aide === 'string')
|
|
167
|
-
props.attrsChamp.placeholder = props.aide;
|
|
168
|
-
else if (props.titre && typeof props.titre === 'string')
|
|
169
|
-
props.attrsChamp.placeholder = props.titre;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/*----------------------------------
|
|
173
|
-
- ETAT
|
|
174
|
-
----------------------------------*/
|
|
175
|
-
// - Initialise le state
|
|
176
|
-
// - Complète les props selon le state
|
|
177
|
-
// - Ajoute les events
|
|
178
|
-
|
|
179
|
-
// Le type de la valeur est spécifié via TBasePropsChamp["valeur"]
|
|
180
|
-
type TState = {
|
|
181
|
-
valeur: TValeur,
|
|
182
|
-
erreurs: string[],
|
|
183
|
-
focus: boolean,
|
|
184
|
-
chargement: boolean // Lorsque onChange est async
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
const valeurInit = ('valeur' in props)
|
|
188
|
-
? (config.transformer ? config.transformer.in(props.valeur) : props.valeur)
|
|
189
|
-
: config.valeurDefaut
|
|
190
|
-
|
|
191
|
-
const lastCommitedValue = React.useRef(valeurInit);
|
|
192
|
-
|
|
193
|
-
const [state, setWholeState] = React.useState<TState>({
|
|
194
|
-
erreurs: [],
|
|
195
|
-
focus: false,
|
|
196
|
-
chargement: false,
|
|
197
|
-
|
|
198
|
-
// Valeur initiale = via props si disponible, sinon valeur par défaut
|
|
199
|
-
valeur: valeurInit
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
// Propagation valeur controlée => state
|
|
203
|
-
React.useEffect(() => {
|
|
204
|
-
|
|
205
|
-
if (props.valeur !== state.valeur)
|
|
206
|
-
setState({ valeur: props.valeur });
|
|
207
|
-
|
|
208
|
-
}, [props.valeur]);
|
|
209
|
-
|
|
210
|
-
const setState = async (newState: Partial<TState> | ((sA: TState) => Partial<TState>), commitNow: boolean = false) => {
|
|
211
|
-
|
|
212
|
-
// Via fonction
|
|
213
|
-
if (typeof newState === 'function')
|
|
214
|
-
newState = newState(state);
|
|
215
|
-
|
|
216
|
-
// Màj valeur
|
|
217
|
-
if ('valeur' in newState) {
|
|
218
|
-
|
|
219
|
-
// Transformation en entrée
|
|
220
|
-
if (config.transformer !== undefined)
|
|
221
|
-
newState.valeur = config.transformer.in(newState.valeur);
|
|
222
|
-
|
|
223
|
-
// Pas de saisie manuelle = validation immédiate
|
|
224
|
-
if (commitNow || config.saisieManuelle !== true) {
|
|
225
|
-
|
|
226
|
-
// Etat de chargement pour la validation
|
|
227
|
-
if (props.async)
|
|
228
|
-
setWholeState((stateA) => ({ ...stateA, chargement: true }))
|
|
229
|
-
|
|
230
|
-
newState = {
|
|
231
|
-
...newState,
|
|
232
|
-
...(await commitValue(newState.valeur))
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
newState.chargement = false;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// Màj state
|
|
241
|
-
setWholeState((stateA) => ({
|
|
242
|
-
...stateA,
|
|
243
|
-
...newState
|
|
244
|
-
}))
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
// Champ indépendant = valeur reposant sur le state
|
|
248
|
-
const valeurControlee = 'valeur' in props;
|
|
249
|
-
if (!valeurControlee) {
|
|
250
|
-
|
|
251
|
-
props.erreurs = [
|
|
252
|
-
...(state.erreurs || []),
|
|
253
|
-
...(props.erreurs || [])
|
|
254
|
-
]
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// Actions lorsque la aisie est terminée
|
|
258
|
-
// - Validation & correction
|
|
259
|
-
// - Onchange (ex: màj données form)
|
|
260
|
-
async function commitValue(valeur: TValeur): Promise<Partial<TState>> {
|
|
261
|
-
|
|
262
|
-
if (valeur === lastCommitedValue.current) {
|
|
263
|
-
console.log('[form][commit] Inchangé');
|
|
264
|
-
return {};
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
let erreurs: string[] = []
|
|
268
|
-
|
|
269
|
-
console.log('[form] Commit changes');
|
|
270
|
-
|
|
271
|
-
// Validation si des validateurs son spécifiés et qu'on demande leur execution
|
|
272
|
-
// ATTTENTION: Lorsque le champ appartient à un form, valider = undefined et sa validation a lieue VIA LE FORM
|
|
273
|
-
if (props.valider !== undefined) {
|
|
274
|
-
try {
|
|
275
|
-
valeur = await props.valider(valeur);
|
|
276
|
-
} catch (error) {
|
|
277
|
-
erreurs.push(error.message)
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// onChange spécifique au composant
|
|
282
|
-
// Ex: passage des données au form
|
|
283
|
-
if (props.onChange !== undefined)
|
|
284
|
-
try {
|
|
285
|
-
const valeurSortie = config.transformer ? config.transformer.out(valeur) : valeur;
|
|
286
|
-
// Si valeur saisie au clavier on ne valide pas à chaque frappe (performances + correction frustrante)
|
|
287
|
-
await props.onChange(valeurSortie);
|
|
288
|
-
} catch (e) {
|
|
289
|
-
erreurs.push(e.message)
|
|
290
|
-
console.error("Erreur via onChange", e.message);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
lastCommitedValue.current = valeur;
|
|
294
|
-
|
|
295
|
-
return { erreurs, valeur }
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/*----------------------------------
|
|
299
|
-
- COMPLETION ATTRIBUTS
|
|
300
|
-
----------------------------------*/
|
|
301
|
-
/*if (state.focus === true)
|
|
302
|
-
classeContChamp.push('focus');*/
|
|
303
|
-
|
|
304
|
-
props.attrsChamp.ref = refChamp;
|
|
305
|
-
|
|
306
|
-
const commitCurrentValue = async () => {
|
|
307
|
-
|
|
308
|
-
// Si on ne valide & corrige pas après chaque onchange, on le fait uniquement après onBlur
|
|
309
|
-
const newState = await commitValue(state.valeur);
|
|
310
|
-
setWholeState((stateA) => ({
|
|
311
|
-
...stateA,
|
|
312
|
-
...newState
|
|
313
|
-
}))
|
|
314
|
-
|
|
315
|
-
return newState.valeur;
|
|
316
|
-
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// Events
|
|
320
|
-
/*if (config.saisieManuelle === true)
|
|
321
|
-
props.attrsChamp.onBlur = commitCurrentValue*/
|
|
322
|
-
|
|
323
|
-
/*----------------------------------
|
|
324
|
-
- PREPARATION RENDU
|
|
325
|
-
----------------------------------*/
|
|
326
|
-
|
|
327
|
-
// Finalisation classnames
|
|
328
|
-
props.attrsContChamp.className = classeContChamp.join(' ');
|
|
329
|
-
props.attrsChamp.className = classeChamp.join(' ');
|
|
330
|
-
|
|
331
|
-
if (props.autoFocus) {
|
|
332
|
-
props.attrsChamp.autoFocus = true;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
/*----------------------------------
|
|
336
|
-
- RENDU FINAL
|
|
337
|
-
----------------------------------*/
|
|
338
|
-
const rendre: TFuncRendu<TPropsCompletes> = (rendu, propsRendu) => {
|
|
339
|
-
|
|
340
|
-
let {
|
|
341
|
-
ecraser, pur, readOnly,
|
|
342
|
-
erreurs, status, vide,
|
|
343
|
-
aide, suffixe, icone, prefixe, boutons, pied,
|
|
344
|
-
suffixeLabel, label, titre, attrsContChamp
|
|
345
|
-
} = { ...props, ...propsRendu }
|
|
346
|
-
|
|
347
|
-
if (pur)
|
|
348
|
-
return rendu;
|
|
349
|
-
|
|
350
|
-
if (erreurs !== undefined && erreurs.length !== 0 && status !== false)
|
|
351
|
-
// En cas d'erreur, on ecrase le message de status actuel
|
|
352
|
-
status = (
|
|
353
|
-
<div className="card bg error flat s">
|
|
354
|
-
{erreurs}
|
|
355
|
-
</div>
|
|
356
|
-
)
|
|
357
|
-
|
|
358
|
-
if (aide) {
|
|
359
|
-
|
|
360
|
-
if (!suffixe)
|
|
361
|
-
suffixe = [];
|
|
362
|
-
else if (!Array.isArray(suffixe))
|
|
363
|
-
suffixe = [suffixe];
|
|
364
|
-
|
|
365
|
-
suffixe.push(<i src="solid/question" title={aide} className="s" />);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
if (icone !== undefined)
|
|
369
|
-
prefixe = <i src={icone} />
|
|
370
|
-
|
|
371
|
-
if (boutons) {
|
|
372
|
-
|
|
373
|
-
props.attrsContChamp.className += ' avecBoutons';
|
|
374
|
-
|
|
375
|
-
pied = (
|
|
376
|
-
<div className="boutons">
|
|
377
|
-
{boutons.map((propsBouton) => (
|
|
378
|
-
<Bouton size="s" {...propsBouton} />
|
|
379
|
-
))}
|
|
380
|
-
</div>
|
|
381
|
-
)
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
return (
|
|
385
|
-
<div {...attrsContChamp}>
|
|
386
|
-
|
|
387
|
-
{ecraser === true ? rendu : <>
|
|
388
|
-
|
|
389
|
-
{(label && titre) && (
|
|
390
|
-
<div className="contLabel">
|
|
391
|
-
<label>{titre}</label>
|
|
392
|
-
{suffixeLabel && (
|
|
393
|
-
<div className="suffixeLabel">{suffixeLabel}</div>
|
|
394
|
-
)}
|
|
395
|
-
</div>
|
|
396
|
-
)}
|
|
397
|
-
|
|
398
|
-
{ecraser === 'corpsChamp' ? rendu : (
|
|
399
|
-
<div className={"corpsChamp"} onClick={() => {
|
|
400
|
-
const elemChamp = refChamp.current;
|
|
401
|
-
if (elemChamp) {
|
|
402
|
-
if (type === 'select') {
|
|
403
|
-
const bouton = elemChamp.querySelector('.bouton');
|
|
404
|
-
if (bouton)
|
|
405
|
-
bouton.click();
|
|
406
|
-
} else if (elemChamp.focus)
|
|
407
|
-
elemChamp.focus();
|
|
408
|
-
}
|
|
409
|
-
}}>
|
|
410
|
-
|
|
411
|
-
{prefixe}
|
|
412
|
-
|
|
413
|
-
{rendu}
|
|
414
|
-
|
|
415
|
-
{suffixe}
|
|
416
|
-
|
|
417
|
-
</div>
|
|
418
|
-
)}
|
|
419
|
-
|
|
420
|
-
</>}
|
|
421
|
-
|
|
422
|
-
{pied}
|
|
423
|
-
|
|
424
|
-
{status}
|
|
425
|
-
|
|
426
|
-
</div>
|
|
427
|
-
)
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
return build(props, { valeur: state.valeur, state, setState, commitCurrentValue }, rendre);
|
|
431
|
-
|
|
432
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/*----------------------------------
|
|
2
|
-
- DEPENDANCES
|
|
3
|
-
----------------------------------*/
|
|
4
|
-
|
|
5
|
-
// Npm
|
|
6
|
-
import React from 'react';
|
|
7
|
-
import { ComponentChild } from 'preact';
|
|
8
|
-
|
|
9
|
-
// Core libs
|
|
10
|
-
import { useState } from '@client/hooks';
|
|
11
|
-
|
|
12
|
-
/*----------------------------------
|
|
13
|
-
- TYPES
|
|
14
|
-
----------------------------------*/
|
|
15
|
-
|
|
16
|
-
export type InputBaseProps<TValue> = {
|
|
17
|
-
value: TValue,
|
|
18
|
-
title: string, // Now mandatory
|
|
19
|
-
onChange?: (newValue: TValue) => void,
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export type TInputState<TValue> = {
|
|
23
|
-
value: TValue,
|
|
24
|
-
fieldProps: {[key: string]: any},
|
|
25
|
-
valueSource: 'internal'|'external',
|
|
26
|
-
focus: boolean,
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/*----------------------------------
|
|
30
|
-
- HOOKS
|
|
31
|
-
----------------------------------*/
|
|
32
|
-
export function useInput<TValue>(
|
|
33
|
-
{ value: externalValue, onChange }: InputBaseProps<TValue>,
|
|
34
|
-
defaultValue: TValue,
|
|
35
|
-
): [
|
|
36
|
-
state: TInputState<TValue>,
|
|
37
|
-
setValue: (value: TValue) => void,
|
|
38
|
-
commitValue: () => void,
|
|
39
|
-
setState: (state: Partial<TInputState<TValue>>) => void,
|
|
40
|
-
] {
|
|
41
|
-
|
|
42
|
-
const [state, setState] = useState<TInputState<TValue>>({
|
|
43
|
-
value: externalValue !== undefined ? externalValue : defaultValue,
|
|
44
|
-
valueSource: 'external',
|
|
45
|
-
fieldProps: {},
|
|
46
|
-
focus: false
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
const setValue = (value: TValue) => setState({ value, valueSource: 'internal' });
|
|
50
|
-
|
|
51
|
-
const commitValue = () => {
|
|
52
|
-
console.log(`[input] Commit value:`, state.value);
|
|
53
|
-
if (onChange !== undefined)
|
|
54
|
-
onChange(state.value);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// External value change
|
|
58
|
-
React.useEffect(() => {
|
|
59
|
-
|
|
60
|
-
if (externalValue !== undefined && externalValue !== state.value) {
|
|
61
|
-
console.log("External value change", externalValue);
|
|
62
|
-
setState({ value: externalValue, valueSource: 'external' })
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
}, [externalValue]);
|
|
66
|
-
|
|
67
|
-
return [state, setValue, commitValue, setState]
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/*----------------------------------
|
|
71
|
-
- COMPONENT
|
|
72
|
-
----------------------------------*/
|