@rsuci/shared-form-components 1.0.133 → 1.0.135

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.
@@ -1 +1 @@
1
- {"version":3,"file":"GeographicCascadeInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/GeographicCascadeInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AASjF,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnE,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,2BAA2B;IACnC,QAAQ,EAAE,GAAG,CAAC;IACd,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE;QACT,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;KAClH,CAAC;CACH;AAID,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CA2OxE,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"GeographicCascadeInput.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/GeographicCascadeInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AASjF,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnE,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,2BAA2B;IACnC,QAAQ,EAAE,GAAG,CAAC;IACd,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE;QACT,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;KAClH,CAAC;CACH;AAID,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAuOxE,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
@@ -30,31 +30,25 @@ export const GeographicCascadeInput = ({ variable, value, onChange, reponses, di
30
30
  setHasMore(true);
31
31
  return;
32
32
  }
33
- const timer = setTimeout(async () => {
34
- setLoading(true);
35
- setError(null);
33
+ setLoading(true);
34
+ setError(null);
35
+ setPage(1);
36
+ setHasMore(true);
37
+ services.fetchGeographicData(entityType, parentValue || undefined, { searchText: searchTerm || undefined, page: 1, pageSize: PAGE_SIZE })
38
+ .then(data => {
39
+ const mapped = data.map(item => ({
40
+ id: item.id,
41
+ code: item.code,
42
+ designation: item.designation,
43
+ }));
44
+ setItems(mapped);
45
+ setHasMore(mapped.length === PAGE_SIZE);
46
+ })
47
+ .catch(() => {
48
+ setError(`Erreur de chargement des ${variable.designation?.toLowerCase() || 'données'}`);
36
49
  setItems([]);
37
- setPage(1);
38
- setHasMore(true);
39
- try {
40
- const data = await services.fetchGeographicData(entityType, parentValue || undefined, { searchText: searchTerm || undefined, page: 1, pageSize: PAGE_SIZE });
41
- const mapped = data.map(item => ({
42
- id: item.id,
43
- code: item.code,
44
- designation: item.designation,
45
- }));
46
- setItems(mapped);
47
- setHasMore(mapped.length === PAGE_SIZE);
48
- }
49
- catch {
50
- setError(`Erreur de chargement des ${variable.designation?.toLowerCase() || 'données'}`);
51
- setItems([]);
52
- }
53
- finally {
54
- setLoading(false);
55
- }
56
- }, searchTerm ? 300 : 0);
57
- return () => clearTimeout(timer);
50
+ })
51
+ .finally(() => setLoading(false));
58
52
  }, [entityType, effectiveNeedsParent, parentValue, searchTerm, services]);
59
53
  const handleScrollEnd = useCallback(async () => {
60
54
  if (!hasMore || loadingMore || loading || !services?.fetchGeographicData)
@@ -158,6 +152,6 @@ export const GeographicCascadeInput = ({ variable, value, onChange, reponses, di
158
152
  } : null;
159
153
  return (_jsxs("div", { className: "w-full", children: [_jsx(SearchableSelect, { options: options, value: currentValue, onChange: handleChange, placeholder: getPlaceholder(), searchPlaceholder: "Rechercher...", disabled: isDisabled, required: required, loading: loading, error: error || undefined, className: className, noOptionsMessage: effectiveNeedsParent && !parentValue
160
154
  ? `Veuillez d'abord sélectionner ${getParentLabel(variable.typeCode)}`
161
- : `Aucun(e) ${variable.designation?.toLowerCase() || 'élément'} disponible`, formatOptionLabel: (option) => option.designation, onSearchChange: handleSearchChange, onScrollEnd: handleScrollEnd, loadingMore: loadingMore }), effectiveNeedsParent && !parentValue && !loading && !error && (_jsxs("p", { className: "mt-1 text-sm text-gray-500 flex items-center", children: [_jsx("svg", { className: "w-4 h-4 mr-1", fill: "currentColor", viewBox: "0 0 20 20", children: _jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z", clipRule: "evenodd" }) }), "Veuillez d'abord s\u00E9lectionner ", getParentLabel(variable.typeCode)] })), loading && (_jsxs("p", { className: "mt-1 text-sm text-blue-600 flex items-center", children: [_jsxs("svg", { className: "animate-spin h-4 w-4 mr-1", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), "Chargement des donn\u00E9es..."] }))] }));
155
+ : `Aucun(e) ${variable.designation?.toLowerCase() || 'élément'} disponible`, formatOptionLabel: (option) => option.designation, onSearchChange: handleSearchChange, onScrollEnd: handleScrollEnd, loadingMore: loadingMore, debounceMs: 300 }), effectiveNeedsParent && !parentValue && !loading && !error && (_jsxs("p", { className: "mt-1 text-sm text-gray-500 flex items-center", children: [_jsx("svg", { className: "w-4 h-4 mr-1", fill: "currentColor", viewBox: "0 0 20 20", children: _jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z", clipRule: "evenodd" }) }), "Veuillez d'abord s\u00E9lectionner ", getParentLabel(variable.typeCode)] })), loading && (_jsxs("p", { className: "mt-1 text-sm text-blue-600 flex items-center", children: [_jsxs("svg", { className: "animate-spin h-4 w-4 mr-1", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), "Chargement des donn\u00E9es..."] }))] }));
162
156
  };
163
157
  export default GeographicCascadeInput;
@@ -25,6 +25,7 @@ interface SearchableSelectProps {
25
25
  onSearchChange?: (term: string) => void;
26
26
  onScrollEnd?: () => void;
27
27
  loadingMore?: boolean;
28
+ debounceMs?: number;
28
29
  }
29
30
  export declare const SearchableSelect: React.FC<SearchableSelectProps>;
30
31
  export default SearchableSelect;
@@ -1 +1 @@
1
- {"version":3,"file":"SearchableSelect.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/SearchableSelect.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAsC,MAAM,OAAO,CAAC;AAE3D,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,UAAU,qBAAqB;IAC7B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,MAAM,CAAC;IACrD,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA8N5D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"SearchableSelect.d.ts","sourceRoot":"","sources":["../../../src/components/inputs/SearchableSelect.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,UAAU,qBAAqB;IAC7B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,MAAM,CAAC;IACrD,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA4O5D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -3,12 +3,29 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  * Composant de sélection avec recherche intégrée
4
4
  * Inspiré du design de production avec champ de filtre
5
5
  */
6
- import { useState, useRef, useEffect } from 'react';
7
- export const SearchableSelect = ({ options, value, onChange, placeholder = 'Sélectionner...', searchPlaceholder = 'Rechercher...', disabled = false, required = false, loading = false, error, className = '', noOptionsMessage = 'Aucune option disponible', formatOptionLabel, onSearchChange, onScrollEnd, loadingMore = false, }) => {
6
+ import { useState, useRef, useEffect, useCallback } from 'react';
7
+ export const SearchableSelect = ({ options, value, onChange, placeholder = 'Sélectionner...', searchPlaceholder = 'Rechercher...', disabled = false, required = false, loading = false, error, className = '', noOptionsMessage = 'Aucune option disponible', formatOptionLabel, onSearchChange, onScrollEnd, loadingMore = false, debounceMs = 0, }) => {
8
8
  const [isOpen, setIsOpen] = useState(false);
9
9
  const [searchTerm, setSearchTerm] = useState('');
10
10
  const dropdownRef = useRef(null);
11
11
  const searchInputRef = useRef(null);
12
+ const debounceRef = useRef();
13
+ useEffect(() => {
14
+ return () => { if (debounceRef.current)
15
+ clearTimeout(debounceRef.current); };
16
+ }, []);
17
+ const handleSearchInput = useCallback((val) => {
18
+ setSearchTerm(val);
19
+ if (!onSearchChange)
20
+ return;
21
+ if (debounceMs > 0) {
22
+ clearTimeout(debounceRef.current);
23
+ debounceRef.current = setTimeout(() => onSearchChange(val), debounceMs);
24
+ }
25
+ else {
26
+ onSearchChange(val);
27
+ }
28
+ }, [onSearchChange, debounceMs]);
12
29
  // Fermer le dropdown quand on clique à l'extérieur
13
30
  useEffect(() => {
14
31
  const handleClickOutside = (event) => {
@@ -51,7 +68,7 @@ export const SearchableSelect = ({ options, value, onChange, placeholder = 'Sél
51
68
  };
52
69
  // Gérer l'ouverture/fermeture du dropdown
53
70
  const toggleDropdown = () => {
54
- if (!disabled && !loading) {
71
+ if (!disabled && !(loading && !isOpen)) {
55
72
  setIsOpen(!isOpen);
56
73
  if (!isOpen) {
57
74
  setSearchTerm('');
@@ -72,12 +89,9 @@ export const SearchableSelect = ({ options, value, onChange, placeholder = 'Sél
72
89
  return placeholder;
73
90
  return getOptionLabel(value);
74
91
  };
75
- return (_jsxs("div", { className: `relative w-full ${className}`, ref: dropdownRef, children: [_jsx("button", { type: "button", onClick: toggleDropdown, disabled: disabled || loading, className: `w-full px-3 py-2 text-left border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors ${error ? 'border-red-300 bg-red-50' : 'border-gray-300'} ${disabled || loading
92
+ return (_jsxs("div", { className: `relative w-full ${className}`, ref: dropdownRef, children: [_jsx("button", { type: "button", onClick: toggleDropdown, disabled: disabled || (loading && !isOpen), className: `w-full px-3 py-2 text-left border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors ${error ? 'border-red-300 bg-red-50' : 'border-gray-300'} ${disabled || (loading && !isOpen)
76
93
  ? 'bg-gray-100 cursor-not-allowed text-gray-500'
77
- : 'bg-white text-gray-900 hover:border-gray-400'} ${isOpen ? 'ring-2 ring-blue-500 border-transparent' : ''}`, children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: value ? 'text-gray-900' : 'text-gray-500', children: loading ? 'Chargement...' : getSelectedLabel() }), _jsx("svg", { className: `w-5 h-5 text-gray-400 transition-transform ${isOpen ? 'transform rotate-180' : ''}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })] }) }), isOpen && !disabled && !loading && (_jsxs("div", { className: "absolute z-50 w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg", children: [_jsx("div", { className: "p-2 border-b border-gray-200 bg-gray-50", children: _jsxs("div", { className: "relative", children: [_jsx("svg", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }), _jsx("input", { ref: searchInputRef, type: "text", value: searchTerm, onChange: (e) => {
78
- setSearchTerm(e.target.value);
79
- onSearchChange?.(e.target.value);
80
- }, placeholder: searchPlaceholder, className: "w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm" })] }) }), _jsxs("div", { className: "overflow-y-auto", style: { maxHeight: '240px' }, onScroll: (e) => {
94
+ : 'bg-white text-gray-900 hover:border-gray-400'} ${isOpen ? 'ring-2 ring-blue-500 border-transparent' : ''}`, children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: value ? 'text-gray-900' : 'text-gray-500', children: loading ? 'Chargement...' : getSelectedLabel() }), _jsx("svg", { className: `w-5 h-5 text-gray-400 transition-transform ${isOpen ? 'transform rotate-180' : ''}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })] }) }), isOpen && !disabled && (_jsxs("div", { className: "absolute z-50 w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg", children: [_jsx("div", { className: "p-2 border-b border-gray-200 bg-gray-50", children: _jsxs("div", { className: "relative", children: [_jsx("svg", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }), _jsx("input", { ref: searchInputRef, type: "text", value: searchTerm, onChange: (e) => handleSearchInput(e.target.value), placeholder: searchPlaceholder, className: "w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm" })] }) }), _jsxs("div", { className: "overflow-y-auto", style: { maxHeight: '240px' }, onScroll: (e) => {
81
95
  if (!onScrollEnd)
82
96
  return;
83
97
  const { scrollTop, clientHeight, scrollHeight } = e.currentTarget;
@@ -1 +1 @@
1
- {"version":3,"file":"EnqueteInput.d.ts","sourceRoot":"","sources":["../../../src/components/selectors/EnqueteInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEtE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE;YACX,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;IACF,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qBAAqB,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,KAAK,IAAI,CAAC;IACnD,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE;QACT,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACvE,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;KAC3D,CAAC;CACH;AAID,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAsH7C,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"EnqueteInput.d.ts","sourceRoot":"","sources":["../../../src/components/selectors/EnqueteInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEtE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE;YACX,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;IACF,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qBAAqB,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,KAAK,IAAI,CAAC;IACnD,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE;QACT,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACvE,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;KAC3D,CAAC;CACH;AAID,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA+G7C,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,eAAe,YAAY,CAAC"}
@@ -12,31 +12,22 @@ const EnqueteInput = ({ variable, value, onChange, error, disabled, onFillFormFr
12
12
  const [loadingData, setLoadingData] = useState(false);
13
13
  const [loadError, setLoadError] = useState(null);
14
14
  const [searchTerm, setSearchTerm] = useState('');
15
- // Chargement initial + reset sur changement de recherche (debounce 300ms)
16
15
  useEffect(() => {
17
16
  if (!services?.fetchEnquetes) {
18
17
  setLoadError('Service de chargement des enquêtes non disponible');
19
18
  return;
20
19
  }
21
- const timer = setTimeout(async () => {
22
- setLoading(true);
23
- setLoadError(null);
24
- setEnquetes([]);
25
- setPage(1);
26
- setHasMore(true);
27
- try {
28
- const data = await services.fetchEnquetes({ searchText: searchTerm || undefined, page: 1, pageSize: PAGE_SIZE });
29
- setEnquetes(data);
30
- setHasMore(data.length === PAGE_SIZE);
31
- }
32
- catch {
33
- setLoadError('Erreur lors du chargement des enquêtes');
34
- }
35
- finally {
36
- setLoading(false);
37
- }
38
- }, searchTerm ? 300 : 0);
39
- return () => clearTimeout(timer);
20
+ setLoading(true);
21
+ setLoadError(null);
22
+ setPage(1);
23
+ setHasMore(true);
24
+ services.fetchEnquetes({ searchText: searchTerm || undefined, page: 1, pageSize: PAGE_SIZE })
25
+ .then(data => {
26
+ setEnquetes(data);
27
+ setHasMore(data.length === PAGE_SIZE);
28
+ })
29
+ .catch(() => setLoadError('Erreur lors du chargement des enquêtes'))
30
+ .finally(() => setLoading(false));
40
31
  }, [searchTerm, services]);
41
32
  const handleScrollEnd = useCallback(async () => {
42
33
  if (!hasMore || loadingMore || loading || !services?.fetchEnquetes)
@@ -85,7 +76,7 @@ const EnqueteInput = ({ variable, value, onChange, error, disabled, onFillFormFr
85
76
  }
86
77
  }
87
78
  };
88
- return (_jsxs("div", { children: [_jsx(SearchableSelect, { options: options, value: selectedOption, onChange: handleChange, placeholder: "S\u00E9lectionner une enqu\u00EAte...", searchPlaceholder: "Rechercher une enqu\u00EAte...", disabled: disabled || loadingData, required: variable.estObligatoire, loading: loading, error: loadError || error, formatOptionLabel: (option) => option.designation, noOptionsMessage: loading ? 'Chargement...' : 'Aucune enquête trouvée', onSearchChange: setSearchTerm, onScrollEnd: handleScrollEnd, loadingMore: loadingMore }), loadingData && (_jsx("p", { className: "text-sm text-blue-600 mt-1", children: "Chargement des donn\u00E9es de l'enqu\u00EAte..." }))] }));
79
+ return (_jsxs("div", { children: [_jsx(SearchableSelect, { options: options, value: selectedOption, onChange: handleChange, placeholder: "S\u00E9lectionner une enqu\u00EAte...", searchPlaceholder: "Rechercher une enqu\u00EAte...", disabled: disabled || loadingData, required: variable.estObligatoire, loading: loading, error: loadError || error, formatOptionLabel: (option) => option.designation, noOptionsMessage: loading ? 'Chargement...' : 'Aucune enquête trouvée', onSearchChange: setSearchTerm, onScrollEnd: handleScrollEnd, loadingMore: loadingMore, debounceMs: 300 }), loadingData && (_jsx("p", { className: "text-sm text-blue-600 mt-1", children: "Chargement des donn\u00E9es de l'enqu\u00EAte..." }))] }));
89
80
  };
90
81
  export { EnqueteInput };
91
82
  export default EnqueteInput;
@@ -1 +1 @@
1
- {"version":3,"file":"MenageInput.d.ts","sourceRoot":"","sources":["../../../src/components/selectors/MenageInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE;YACX,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;IACF,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC9D,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE;QACT,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;KACtE,CAAC;CACH;AAID,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAuG3C,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC;AACvB,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"MenageInput.d.ts","sourceRoot":"","sources":["../../../src/components/selectors/MenageInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE;YACX,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;IACF,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC9D,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE;QACT,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;KACtE,CAAC;CACH;AAID,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAgG3C,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC;AACvB,eAAe,WAAW,CAAC"}
@@ -11,31 +11,22 @@ const MenageInput = ({ variable, value, onChange, error, disabled, onFillFormFro
11
11
  const [loadingMore, setLoadingMore] = useState(false);
12
12
  const [loadError, setLoadError] = useState(null);
13
13
  const [searchTerm, setSearchTerm] = useState('');
14
- // Chargement initial + reset sur changement de recherche (debounce 300ms)
15
14
  useEffect(() => {
16
15
  if (!services?.fetchMenages) {
17
16
  setLoadError('Service de chargement des ménages non disponible');
18
17
  return;
19
18
  }
20
- const timer = setTimeout(async () => {
21
- setLoading(true);
22
- setLoadError(null);
23
- setMenages([]);
24
- setPage(1);
25
- setHasMore(true);
26
- try {
27
- const data = await services.fetchMenages({ searchText: searchTerm || undefined, page: 1, pageSize: PAGE_SIZE });
28
- setMenages(data);
29
- setHasMore(data.length === PAGE_SIZE);
30
- }
31
- catch {
32
- setLoadError('Erreur lors du chargement des ménages');
33
- }
34
- finally {
35
- setLoading(false);
36
- }
37
- }, searchTerm ? 300 : 0);
38
- return () => clearTimeout(timer);
19
+ setLoading(true);
20
+ setLoadError(null);
21
+ setPage(1);
22
+ setHasMore(true);
23
+ services.fetchMenages({ searchText: searchTerm || undefined, page: 1, pageSize: PAGE_SIZE })
24
+ .then(data => {
25
+ setMenages(data);
26
+ setHasMore(data.length === PAGE_SIZE);
27
+ })
28
+ .catch(() => setLoadError('Erreur lors du chargement des ménages'))
29
+ .finally(() => setLoading(false));
39
30
  }, [searchTerm, services]);
40
31
  const handleScrollEnd = useCallback(async () => {
41
32
  if (!hasMore || loadingMore || loading || !services?.fetchMenages)
@@ -73,7 +64,7 @@ const MenageInput = ({ variable, value, onChange, error, disabled, onFillFormFro
73
64
  // NOTE: onFillFormFromMenage n'est pas appelé automatiquement ici
74
65
  // pour éviter les re-renders lors de la création d'une nouvelle enquête.
75
66
  };
76
- return (_jsx(SearchableSelect, { options: options, value: selectedOption, onChange: handleChange, placeholder: "S\u00E9lectionner un m\u00E9nage...", searchPlaceholder: "Rechercher un m\u00E9nage...", disabled: disabled, required: variable.estObligatoire, loading: loading, error: loadError || error, formatOptionLabel: (option) => option.designation, noOptionsMessage: loading ? 'Chargement...' : 'Aucun ménage trouvé', onSearchChange: setSearchTerm, onScrollEnd: handleScrollEnd, loadingMore: loadingMore }));
67
+ return (_jsx(SearchableSelect, { options: options, value: selectedOption, onChange: handleChange, placeholder: "S\u00E9lectionner un m\u00E9nage...", searchPlaceholder: "Rechercher un m\u00E9nage...", disabled: disabled, required: variable.estObligatoire, loading: loading, error: loadError || error, formatOptionLabel: (option) => option.designation, noOptionsMessage: loading ? 'Chargement...' : 'Aucun ménage trouvé', onSearchChange: setSearchTerm, onScrollEnd: handleScrollEnd, loadingMore: loadingMore, debounceMs: 300 }));
77
68
  };
78
69
  export { MenageInput };
79
70
  export default MenageInput;
@@ -1 +1 @@
1
- {"version":3,"file":"RSUInput.d.ts","sourceRoot":"","sources":["../../../src/components/selectors/RSUInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE;YACX,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;IACF,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE;QACT,eAAe,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;KACrE,CAAC;CACH;AAID,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA6FrC,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"RSUInput.d.ts","sourceRoot":"","sources":["../../../src/components/selectors/RSUInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE;YACX,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;IACF,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE;QACT,eAAe,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;KACrE,CAAC;CACH;AAID,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAuFrC,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,eAAe,QAAQ,CAAC"}
@@ -16,25 +16,17 @@ const RSUInput = ({ variable, value, onChange, error, disabled, services }) => {
16
16
  setLoadError('Service de chargement des structures non disponible');
17
17
  return;
18
18
  }
19
- const timer = setTimeout(async () => {
20
- setLoading(true);
21
- setLoadError(null);
22
- setStructures([]);
23
- setPage(1);
24
- setHasMore(true);
25
- try {
26
- const data = await services.fetchStructures({ searchText: searchTerm || undefined, page: 1, pageSize: PAGE_SIZE });
27
- setStructures(data);
28
- setHasMore(data.length === PAGE_SIZE);
29
- }
30
- catch {
31
- setLoadError('Erreur lors du chargement des structures');
32
- }
33
- finally {
34
- setLoading(false);
35
- }
36
- }, searchTerm ? 300 : 0);
37
- return () => clearTimeout(timer);
19
+ setLoading(true);
20
+ setLoadError(null);
21
+ setPage(1);
22
+ setHasMore(true);
23
+ services.fetchStructures({ searchText: searchTerm || undefined, page: 1, pageSize: PAGE_SIZE })
24
+ .then(data => {
25
+ setStructures(data);
26
+ setHasMore(data.length === PAGE_SIZE);
27
+ })
28
+ .catch(() => setLoadError('Erreur lors du chargement des structures'))
29
+ .finally(() => setLoading(false));
38
30
  }, [searchTerm, services]);
39
31
  const handleScrollEnd = useCallback(async () => {
40
32
  if (!hasMore || loadingMore || loading || !services?.fetchStructures)
@@ -65,7 +57,7 @@ const RSUInput = ({ variable, value, onChange, error, disabled, services }) => {
65
57
  const newStructureId = option?.id;
66
58
  onChange(newStructureId?.toString() || null);
67
59
  };
68
- return (_jsx(SearchableSelect, { options: options, value: selectedOption, onChange: handleChange, placeholder: "S\u00E9lectionner une structure RSU...", searchPlaceholder: "Rechercher une structure...", disabled: disabled, required: variable.estObligatoire, loading: loading, error: loadError || error, formatOptionLabel: (option) => option.designation, noOptionsMessage: loading ? 'Chargement...' : 'Aucune structure trouvée', onSearchChange: setSearchTerm, onScrollEnd: handleScrollEnd, loadingMore: loadingMore }));
60
+ return (_jsx(SearchableSelect, { options: options, value: selectedOption, onChange: handleChange, placeholder: "S\u00E9lectionner une structure RSU...", searchPlaceholder: "Rechercher une structure...", disabled: disabled, required: variable.estObligatoire, loading: loading, error: loadError || error, formatOptionLabel: (option) => option.designation, noOptionsMessage: loading ? 'Chargement...' : 'Aucune structure trouvée', onSearchChange: setSearchTerm, onScrollEnd: handleScrollEnd, loadingMore: loadingMore, debounceMs: 300 }));
69
61
  };
70
62
  export { RSUInput };
71
63
  export default RSUInput;
package/package.json CHANGED
@@ -1,62 +1,62 @@
1
- {
2
- "name": "@rsuci/shared-form-components",
3
- "version": "1.0.133",
4
- "description": "Composants partagés de rendu de formulaires RSU v2 - Package local pour frontend Admin et Public",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "files": [
8
- "dist",
9
- "README.md"
10
- ],
11
- "scripts": {
12
- "build": "tsc",
13
- "watch": "tsc --watch",
14
- "test": "jest",
15
- "test:coverage": "jest --coverage"
16
- },
17
- "keywords": [
18
- "rsu",
19
- "formulaires",
20
- "enquetes",
21
- "react",
22
- "typescript"
23
- ],
24
- "author": "RSU v2 Architecture Team",
25
- "license": "MIT",
26
- "engines": {
27
- "node": ">=24.0.0",
28
- "npm": ">=11.0.0"
29
- },
30
- "peerDependencies": {
31
- "lucide-react": "^0.263.0 || ^0.525.0",
32
- "next": "^14.0.0 || ^15.0.0",
33
- "react": "^18.0.0 || ^19.0.0",
34
- "react-dom": "^18.0.0 || ^19.0.0"
35
- },
36
- "peerDependenciesMeta": {
37
- "react-dom": {
38
- "optional": true
39
- },
40
- "next": {
41
- "optional": true
42
- },
43
- "lucide-react": {
44
- "optional": true
45
- }
46
- },
47
- "devDependencies": {
48
- "@testing-library/jest-dom": "^6.0.0",
49
- "@testing-library/react": "^14.0.0",
50
- "@types/jest": "^30.0.0",
51
- "@types/react": "^18.3.0",
52
- "@types/react-dom": "^18.3.0",
53
- "jest": "^29.0.0",
54
- "jest-environment-jsdom": "^29.0.0",
55
- "ts-jest": "^29.4.6",
56
- "typescript": "^5.0.0"
57
- },
58
- "dependencies": {
59
- "clsx": "^2.0.0",
60
- "tailwind-merge": "^2.0.0"
61
- }
62
- }
1
+ {
2
+ "name": "@rsuci/shared-form-components",
3
+ "version": "1.0.135",
4
+ "description": "Composants partagés de rendu de formulaires RSU v2 - Package local pour frontend Admin et Public",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "README.md"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "watch": "tsc --watch",
14
+ "test": "jest",
15
+ "test:coverage": "jest --coverage"
16
+ },
17
+ "keywords": [
18
+ "rsu",
19
+ "formulaires",
20
+ "enquetes",
21
+ "react",
22
+ "typescript"
23
+ ],
24
+ "author": "RSU v2 Architecture Team",
25
+ "license": "MIT",
26
+ "engines": {
27
+ "node": ">=24.0.0",
28
+ "npm": ">=11.0.0"
29
+ },
30
+ "peerDependencies": {
31
+ "lucide-react": "^0.263.0 || ^0.525.0",
32
+ "next": "^14.0.0 || ^15.0.0",
33
+ "react": "^18.0.0 || ^19.0.0",
34
+ "react-dom": "^18.0.0 || ^19.0.0"
35
+ },
36
+ "peerDependenciesMeta": {
37
+ "react-dom": {
38
+ "optional": true
39
+ },
40
+ "next": {
41
+ "optional": true
42
+ },
43
+ "lucide-react": {
44
+ "optional": true
45
+ }
46
+ },
47
+ "devDependencies": {
48
+ "@testing-library/jest-dom": "^6.0.0",
49
+ "@testing-library/react": "^14.0.0",
50
+ "@types/jest": "^30.0.0",
51
+ "@types/react": "^18.3.0",
52
+ "@types/react-dom": "^18.3.0",
53
+ "jest": "^29.0.0",
54
+ "jest-environment-jsdom": "^29.0.0",
55
+ "ts-jest": "^29.4.6",
56
+ "typescript": "^5.0.0"
57
+ },
58
+ "dependencies": {
59
+ "clsx": "^2.0.0",
60
+ "tailwind-merge": "^2.0.0"
61
+ }
62
+ }