kelt-ui-kit-react 2.1.5 → 2.1.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kelt-ui-kit-react",
3
3
  "type": "module",
4
- "version": "2.1.5",
4
+ "version": "2.1.7",
5
5
  "private": false,
6
6
  "repository": {
7
7
  "type": "git",
@@ -9,6 +9,7 @@ import { Icon } from "../icon/Icon";
9
9
  import {
10
10
  GeocodedAddress,
11
11
  GeocodingProvider,
12
+ GeocodingSearchType,
12
13
  } from "../geocoding/geocoding.interface";
13
14
  import { geocodingService } from "../geocoding/GeocodingService";
14
15
  import "./addressSearch.css";
@@ -24,6 +25,11 @@ export interface AddressSearchProps {
24
25
  debounceTime?: number;
25
26
  limit?: number;
26
27
  provider?: GeocodingProvider;
28
+ searchType?: GeocodingSearchType;
29
+ // Valeur écrite dans le champ à la sélection (par défaut la ligne d'adresse)
30
+ formatValue?: (address: GeocodedAddress) => string;
31
+ emptyLabel?: string;
32
+ required?: boolean;
27
33
  allowManualEntry?: boolean;
28
34
  manualEntryLabel?: string;
29
35
  onChange?: (value: string) => void;
@@ -42,6 +48,10 @@ export const AddressSearch = ({
42
48
  debounceTime = 300,
43
49
  limit = 5,
44
50
  provider = geocodingService,
51
+ searchType,
52
+ formatValue = (address) => address.addressLine,
53
+ emptyLabel = "Aucune adresse trouvée.",
54
+ required = false,
45
55
  allowManualEntry = true,
46
56
  manualEntryLabel = "Je ne trouve pas mon adresse",
47
57
  onChange,
@@ -59,10 +69,17 @@ export const AddressSearch = ({
59
69
  const [activeIndex, setActiveIndex] = useState(-1);
60
70
  const containerRef = useRef<HTMLDivElement>(null);
61
71
  const requestRef = useRef<AbortController>();
62
- const skipNextSearchRef = useRef(false);
72
+ // Pas de recherche sur la valeur initiale : la liste s'ouvrirait au chargement
73
+ const skipNextSearchRef = useRef(!!value?.trim());
74
+ const queryRef = useRef(query);
75
+ queryRef.current = query;
63
76
 
77
+ // Valeur changée de l'extérieur (ex. remplie par un autre champ) : on
78
+ // l'affiche sans lancer de recherche
64
79
  useEffect(() => {
65
- if (value !== undefined) setQuery(value);
80
+ if (value === undefined || value === queryRef.current) return;
81
+ skipNextSearchRef.current = true;
82
+ setQuery(value);
66
83
  }, [value]);
67
84
 
68
85
  useEffect(() => {
@@ -103,6 +120,7 @@ export const AddressSearch = ({
103
120
  const addresses = await provider.search(normalizedQuery, {
104
121
  limit,
105
122
  signal: controller.signal,
123
+ type: searchType,
106
124
  });
107
125
  setResults(addresses);
108
126
  setActiveIndex(-1);
@@ -122,20 +140,21 @@ export const AddressSearch = ({
122
140
  window.clearTimeout(timeout);
123
141
  requestRef.current?.abort();
124
142
  };
125
- }, [debounceTime, disabled, limit, minimumQueryLength, provider, query]);
143
+ }, [debounceTime, disabled, limit, minimumQueryLength, provider, query, searchType]);
126
144
 
127
145
  const selectAddress = useCallback(
128
146
  (address: GeocodedAddress) => {
147
+ const nextValue = formatValue(address);
129
148
  requestRef.current?.abort();
130
149
  skipNextSearchRef.current = true;
131
- setQuery(address.addressLine);
150
+ setQuery(nextValue);
132
151
  setResults([]);
133
152
  setIsOpen(false);
134
153
  setActiveIndex(-1);
135
- onChange?.(address.addressLine);
154
+ onChange?.(nextValue);
136
155
  onSelect(address);
137
156
  },
138
- [onChange, onSelect],
157
+ [formatValue, onChange, onSelect],
139
158
  );
140
159
 
141
160
  const selectManualAddress = useCallback(() => {
@@ -186,6 +205,7 @@ export const AddressSearch = ({
186
205
  }
187
206
  autoComplete="off"
188
207
  disabled={disabled}
208
+ required={required}
189
209
  value={query}
190
210
  placeholder={placeholder}
191
211
  onChange={(event) => {
@@ -206,7 +226,7 @@ export const AddressSearch = ({
206
226
  La recherche d'adresse est indisponible.
207
227
  </div>
208
228
  ) : results.length === 0 && !loading ? (
209
- <div className="address-search-status">Aucune adresse trouvée.</div>
229
+ <div className="address-search-status">{emptyLabel}</div>
210
230
  ) : (
211
231
  results.map((address, index) => (
212
232
  <button
package/src/card/Card.tsx CHANGED
@@ -44,6 +44,11 @@ export const Card = ({
44
44
  const onClickCard = useCallback(
45
45
  (e: React.MouseEvent, item: CardInterface) => {
46
46
  e.stopPropagation();
47
+ // Clic dans le menu d'actions (rendu en portal) : l'événement remonte
48
+ // dans l'arbre React mais ne doit pas refermer/repositionner le menu
49
+ if (!e.currentTarget.contains(e.target as Node)) {
50
+ return;
51
+ }
47
52
  if (openActions) {
48
53
  setPositions(undefined);
49
54
  return setOpenActions(false);
@@ -89,7 +89,7 @@ export const CardAction = ({
89
89
  ),
90
90
  };
91
91
  }) as MenuInterface[];
92
- }, [actions]);
92
+ }, [actions, item, closeOverlay]);
93
93
  return (
94
94
  <div className="card-actions">
95
95
  <div
@@ -62,6 +62,8 @@ export interface dataTableActionsInterface<T> {
62
62
  visible?: boolean;
63
63
  width?: string | number;
64
64
  minWidth?: string | number;
65
+ /** Aligns inline action content within its width; omitted preserves the action type's default. */
66
+ align?: "right" | "left" | "center";
65
67
  focusNextRow?: boolean;
66
68
  /** "inline" (défaut) : affichée dans la ligne ; "menu" : regroupée dans le menu « ⋮ » en fin de ligne */
67
69
  display?: "inline" | "menu";
@@ -1,3 +1,4 @@
1
+ import type { CSSProperties } from "react";
1
2
  import { Button } from "../../button/Button";
2
3
  import { Icon } from "../../icon/Icon";
3
4
  import { dataTableActionsInterface } from "../dataTable.interface";
@@ -23,6 +24,13 @@ export const DataTableAction = ({
23
24
  title = action.labelButton ? action.labelButton(row) : action.label;
24
25
  }
25
26
 
27
+ const style: CSSProperties = {
28
+ minWidth: action.minWidth,
29
+ width: action.width,
30
+ justifyContent: action.align === "right" ? "flex-end" : action.align === "left" ? "flex-start" : action.align,
31
+ textAlign: action.align,
32
+ };
33
+
26
34
  const handleClick = (e?: React.MouseEvent) => {
27
35
  e?.stopPropagation();
28
36
  if (action.disabled) return;
@@ -40,10 +48,7 @@ export const DataTableAction = ({
40
48
  key={`button-action-${action.id}-${index}`}
41
49
  onClick={handleClick}
42
50
  disabled={action.disabled}
43
- style={{
44
- minWidth: action.minWidth,
45
- width: action.width,
46
- }}
51
+ style={style}
47
52
  className={`data-table-action button--tertiary mr-2 w-100 ${
48
53
  action.classIcon ? action.classIcon : ""
49
54
  }`}
@@ -65,16 +70,13 @@ export const DataTableAction = ({
65
70
  }
66
71
  }}
67
72
  onClick={handleClick}
68
- style={{
69
- minWidth: action.minWidth,
70
- width: action.width,
71
- }}
73
+ style={style}
72
74
  >
73
75
  <Icon classIcon={action.classIcon ?? ""} key={action.id} />
74
76
  </div>
75
77
  )}
76
78
  {action.type === "link" && (
77
- <button type="button" className="data-table-action-link" disabled={action.disabled} onClick={handleClick}>
79
+ <button type="button" className="data-table-action-link" style={style} disabled={action.disabled} onClick={handleClick}>
78
80
  {title}
79
81
  </button>
80
82
  )}
package/src/form/Form.tsx CHANGED
@@ -345,6 +345,10 @@ export const DynamicForm = forwardRef(
345
345
  debounceTime={v.addressSearch?.debounceTime}
346
346
  limit={v.addressSearch?.limit}
347
347
  provider={v.addressSearch?.provider}
348
+ searchType={v.addressSearch?.searchType}
349
+ formatValue={v.addressSearch?.formatValue}
350
+ emptyLabel={v.addressSearch?.emptyLabel}
351
+ required={required}
348
352
  allowManualEntry
349
353
  manualEntryLabel={v.addressSearch?.manualEntryLabel}
350
354
  onChange={(value) =>
@@ -3,6 +3,7 @@ import { GridBreakpoints } from "../grid/grid.interface";
3
3
  import {
4
4
  GeocodedAddress,
5
5
  GeocodingProvider,
6
+ GeocodingSearchType,
6
7
  } from "../geocoding/geocoding.interface";
7
8
 
8
9
  export type FormMode = "read" | "edit";
@@ -46,6 +47,9 @@ export interface FormInterface {
46
47
  debounceTime?: number;
47
48
  limit?: number;
48
49
  provider?: GeocodingProvider;
50
+ searchType?: GeocodingSearchType;
51
+ formatValue?: (address: GeocodedAddress) => string;
52
+ emptyLabel?: string;
49
53
  manualEntryLabel?: string;
50
54
  mapAddress?: (
51
55
  address: GeocodedAddress,
@@ -0,0 +1,144 @@
1
+ import {
2
+ GeocodedAddress,
3
+ GeocodingProvider,
4
+ GeocodingSearchOptions,
5
+ } from "./geocoding.interface";
6
+
7
+ const DEFAULT_CITY_URL = "https://geo.api.gouv.fr";
8
+ const FIELDS = "nom,codesPostaux,centre";
9
+
10
+ interface Commune {
11
+ code: string;
12
+ nom: string;
13
+ codesPostaux?: string[];
14
+ centre?: { coordinates?: [number, number] };
15
+ }
16
+
17
+ export interface CityGeocodingServiceOptions {
18
+ baseUrl?: string;
19
+ fetcher?: typeof fetch;
20
+ }
21
+
22
+ /**
23
+ * Recherche de communes au fil de la saisie (API Découpage administratif) :
24
+ * - chiffres : début de code postal ("292" propose 29200 Brest),
25
+ * - texte : début de nom de commune ("bre" propose Brest, Brech...).
26
+ * Une commune à plusieurs codes postaux donne un résultat par code postal.
27
+ */
28
+ export class CityGeocodingService implements GeocodingProvider {
29
+ private readonly baseUrl: string;
30
+ private readonly fetcher: typeof fetch;
31
+ // Communes par département, chargées une seule fois
32
+ private readonly departements = new Map<string, Promise<Commune[]>>();
33
+
34
+ constructor(options: CityGeocodingServiceOptions = {}) {
35
+ this.baseUrl = options.baseUrl ?? DEFAULT_CITY_URL;
36
+ this.fetcher = options.fetcher ?? globalThis.fetch.bind(globalThis);
37
+ }
38
+
39
+ async search(
40
+ query: string,
41
+ options: GeocodingSearchOptions = {},
42
+ ): Promise<GeocodedAddress[]> {
43
+ const normalizedQuery = query.trim();
44
+ if (!normalizedQuery) return [];
45
+ const limit = options.limit ?? 5;
46
+
47
+ if (/^\d+$/.test(normalizedQuery)) {
48
+ const communes = await this.communesDuCodePostal(normalizedQuery);
49
+ // Recherche dépassée par une saisie plus récente
50
+ if (options.signal?.aborted) {
51
+ throw new DOMException("Aborted", "AbortError");
52
+ }
53
+ return communes
54
+ .flatMap((commune) =>
55
+ (commune.codesPostaux ?? [])
56
+ .filter((codePostal) => codePostal.startsWith(normalizedQuery))
57
+ .map((codePostal) => this.toAddress(commune, codePostal)),
58
+ )
59
+ .sort(
60
+ (a, b) =>
61
+ a.postalCode.localeCompare(b.postalCode) ||
62
+ a.city.localeCompare(b.city, "fr"),
63
+ )
64
+ .slice(0, limit);
65
+ }
66
+
67
+ const params = new URLSearchParams({
68
+ nom: normalizedQuery,
69
+ fields: FIELDS,
70
+ boost: "population",
71
+ limit: String(limit),
72
+ });
73
+ const communes = await this.get(`/communes?${params}`, options.signal);
74
+ return communes
75
+ .flatMap((commune) =>
76
+ (commune.codesPostaux ?? []).map((codePostal) =>
77
+ this.toAddress(commune, codePostal),
78
+ ),
79
+ )
80
+ .slice(0, limit);
81
+ }
82
+
83
+ // Départements concernés par un début de code postal
84
+ private async communesDuCodePostal(codePostal: string): Promise<Commune[]> {
85
+ const prefixe = codePostal.slice(0, 2);
86
+ if (prefixe.length < 2 || prefixe === "98") return [];
87
+ // Corse : codes postaux 20xxx pour la Corse-du-Sud et la Haute-Corse
88
+ const departements =
89
+ prefixe === "20"
90
+ ? ["2A", "2B"]
91
+ : prefixe === "97"
92
+ ? codePostal.length >= 3
93
+ ? [codePostal.slice(0, 3)]
94
+ : []
95
+ : [prefixe];
96
+ const listes = await Promise.all(
97
+ departements.map((departement) => this.communesDuDepartement(departement)),
98
+ );
99
+ return listes.flat();
100
+ }
101
+
102
+ // Sans signal : la requête est partagée par toutes les recherches du département
103
+ private communesDuDepartement(departement: string): Promise<Commune[]> {
104
+ let communes = this.departements.get(departement);
105
+ if (!communes) {
106
+ communes = this.get(
107
+ `/departements/${departement}/communes?fields=${FIELDS}`,
108
+ ).catch((error) => {
109
+ this.departements.delete(departement);
110
+ throw error;
111
+ });
112
+ this.departements.set(departement, communes);
113
+ }
114
+ return communes;
115
+ }
116
+
117
+ private async get(path: string, signal?: AbortSignal): Promise<Commune[]> {
118
+ const response = await this.fetcher(`${this.baseUrl}${path}`, { signal });
119
+ // Département inconnu (ex. 96) : aucune commune
120
+ if (response.status === 404) return [];
121
+ if (!response.ok) {
122
+ throw new Error(`City search request failed (${response.status})`);
123
+ }
124
+ return (await response.json()) as Commune[];
125
+ }
126
+
127
+ private toAddress(commune: Commune, codePostal: string): GeocodedAddress {
128
+ const [longitude, latitude] = commune.centre?.coordinates ?? [0, 0];
129
+ return {
130
+ id: `${commune.code}-${codePostal}`,
131
+ label: `${codePostal} ${commune.nom}`,
132
+ addressLine: commune.nom,
133
+ postalCode: codePostal,
134
+ city: commune.nom,
135
+ cityCode: commune.code,
136
+ countryCode: "FR",
137
+ longitude,
138
+ latitude,
139
+ type: "municipality",
140
+ };
141
+ }
142
+ }
143
+
144
+ export const cityGeocodingService = new CityGeocodingService();
@@ -53,6 +53,7 @@ export class GeocodingService implements GeocodingProvider {
53
53
  autocomplete: "1",
54
54
  index: "address",
55
55
  });
56
+ if (options.type) params.set("type", options.type);
56
57
  const response = await this.fetcher(`${this.baseUrl}?${params}`, {
57
58
  signal: options.signal,
58
59
  });
@@ -12,9 +12,17 @@ export interface GeocodedAddress {
12
12
  type?: string;
13
13
  }
14
14
 
15
+ // "municipality" : communes seulement (recherche par code postal ou ville)
16
+ export type GeocodingSearchType =
17
+ | "housenumber"
18
+ | "street"
19
+ | "locality"
20
+ | "municipality";
21
+
15
22
  export interface GeocodingSearchOptions {
16
23
  limit?: number;
17
24
  signal?: AbortSignal;
25
+ type?: GeocodingSearchType;
18
26
  }
19
27
 
20
28
  export interface GeocodingProvider {
package/src/index.ts CHANGED
@@ -52,10 +52,15 @@ export {
52
52
  GeocodingService,
53
53
  geocodingService,
54
54
  } from "./geocoding/GeocodingService";
55
+ export {
56
+ CityGeocodingService,
57
+ cityGeocodingService,
58
+ } from "./geocoding/CityGeocodingService";
55
59
  export type {
56
60
  GeocodedAddress,
57
61
  GeocodingProvider,
58
62
  GeocodingSearchOptions,
63
+ GeocodingSearchType,
59
64
  } from "./geocoding/geocoding.interface";
60
65
  export { Header } from "./header/Header";
61
66
  export { Icon } from "./icon/Icon";
@@ -155,6 +155,38 @@ export const Sidebar = ({
155
155
  [toggleSidebar],
156
156
  );
157
157
 
158
+ // iOS : un glissé vertical sans rien à scroller dans la sidebar fait rebondir
159
+ // la page derrière (fond blanc, contenu visible en haut). Écouteur natif non
160
+ // passif : celui de React est passif, son preventDefault n'a pas d'effet.
161
+ useEffect(() => {
162
+ const sidebar = sidebarRef.current;
163
+ if (!isOpen || !sidebar) return;
164
+
165
+ const onTouchMove = (event: TouchEvent) => {
166
+ const deltaY = event.touches[0].clientY - touchStartY.current;
167
+ let element = event.target as HTMLElement | null;
168
+ while (element && element !== sidebar.parentElement) {
169
+ const { overflowY } = window.getComputedStyle(element);
170
+ const scrollable =
171
+ (overflowY === "auto" || overflowY === "scroll") &&
172
+ element.scrollHeight > element.clientHeight;
173
+ if (scrollable) {
174
+ const enHaut = element.scrollTop <= 0;
175
+ const enBas =
176
+ element.scrollTop + element.clientHeight >= element.scrollHeight;
177
+ // Laisse scroller tant qu'on n'est pas en butée dans le sens du geste
178
+ if ((deltaY > 0 && !enHaut) || (deltaY < 0 && !enBas)) return;
179
+ break;
180
+ }
181
+ element = element.parentElement;
182
+ }
183
+ if (event.cancelable) event.preventDefault();
184
+ };
185
+
186
+ sidebar.addEventListener("touchmove", onTouchMove, { passive: false });
187
+ return () => sidebar.removeEventListener("touchmove", onTouchMove);
188
+ }, [isOpen]);
189
+
158
190
  useEffect(() => {
159
191
  if (isOpen) {
160
192
  document.addEventListener("mousedown", handleClickOutside);
@@ -2,10 +2,13 @@
2
2
  touch-action: pan-y;
3
3
  /* laisse le scroll vertical natif, gère le X nous-même */
4
4
  will-change: transform;
5
+ /* le scroll ne se propage pas à la page derrière */
6
+ overscroll-behavior: contain;
5
7
  }
6
8
 
7
9
  .overlay {
8
10
  touch-action: none;
11
+ overscroll-behavior: contain;
9
12
  }
10
13
 
11
14
  .toggle-btn {
@@ -15,7 +18,12 @@
15
18
 
16
19
  .sidebar {
17
20
  width: 200px;
21
+ /* iOS (Safari, WKWebView) : 100vh dépasse la zone visible et cache le bas
22
+ de la sidebar sous la barre d'outils ; 100dvh suit la hauteur visible */
18
23
  height: 100vh;
24
+ height: 100dvh;
25
+ padding-bottom: env(safe-area-inset-bottom);
26
+ box-sizing: border-box;
19
27
  background-color: var(--primary-color);
20
28
  color: white;
21
29
  transition: width 0.3s;
@@ -26,10 +26,12 @@ const server = await createServer({
26
26
  server: { middlewareMode: true, watch: null, hmr: false },
27
27
  });
28
28
  let DataTableRow;
29
+ let DataTableAction;
29
30
  let Tabs;
30
31
  let Select;
31
32
  try {
32
33
  ({ DataTableRow } = await server.ssrLoadModule("/src/dataTable/dataTableRow/DataTableRow.tsx"));
34
+ ({ DataTableAction } = await server.ssrLoadModule("/src/dataTable/dataTableActions/DataTableAction.tsx"));
33
35
  ({ Tabs } = await server.ssrLoadModule("/src/tabs/Tabs.tsx"));
34
36
  ({ Select } = await server.ssrLoadModule("/src/select/Select.tsx"));
35
37
  } finally {
@@ -50,6 +52,33 @@ test("action widths preserve Hub sums and Kelt explicit column widths", () => {
50
52
  assert.equal(utils.getActionsWidth([]), 200);
51
53
  });
52
54
 
55
+ test("inline action content aligns within its width for every action type", () => {
56
+ for (const type of ["button", "icon", "link"]) {
57
+ for (const [align, justifyContent] of [["left", "flex-start"], ["center", "center"], ["right", "flex-end"]]) {
58
+ const html = renderToStaticMarkup(createElement(DataTableAction, {
59
+ action: { id: "delete", label: "Delete", type, classIcon: "bi-trash", width: 50, minWidth: 40, align, onClick() {} },
60
+ row: {},
61
+ }));
62
+ assert.match(html, /width:50px/);
63
+ assert.match(html, /min-width:40px/);
64
+ assert.ok(html.includes(`justify-content:${justifyContent}`));
65
+ assert.ok(html.includes(`text-align:${align}`));
66
+ }
67
+ }
68
+ });
69
+
70
+ test("omitting action alignment preserves default styles and visibility", () => {
71
+ for (const type of ["button", "icon", "link"]) {
72
+ const action = { id: "delete", label: "Delete", type, width: "50px", onClick() {} };
73
+ const html = renderToStaticMarkup(createElement(DataTableAction, { action, row: {} }));
74
+ assert.doesNotMatch(html, /justify-content|text-align/);
75
+ assert.match(html, /width:50px/);
76
+ assert.equal(renderToStaticMarkup(createElement(DataTableAction, {
77
+ action: { ...action, visible: false }, row: {},
78
+ })), "");
79
+ }
80
+ });
81
+
53
82
  test("menu actions are grouped behind a single three-dots toggle", () => {
54
83
  assert.equal(utils.getActionsWidth([{ width: 48 }, { width: 100, display: "menu" }]), 48 + utils.ACTION_MENU_WIDTH);
55
84
  assert.equal(utils.getActionsWidth([{ display: "menu" }, { display: "menu" }]), utils.ACTION_MENU_WIDTH);
@@ -1 +1 @@
1
- {"root":["./src/App.menu.tsx","./src/App.routes.tsx","./src/App.tsx","./src/index.ts","./src/main.tsx","./src/_core/hooks/HistoryProvider.tsx","./src/_core/hooks/ImageChecker.tsx","./src/_core/hooks/imageExist.tsx","./src/_core/hooks/isEAN13.tsx","./src/_core/hooks/objectToQueryParams.tsx","./src/_core/hooks/useCurrency.tsx","./src/_core/hooks/useDateutils.ts","./src/_core/hooks/useIsMobile.ts","./src/_core/hooks/useToken.tsx","./src/_core/hooks/useValidate.tsx","./src/_core/hooks/widgetSupport.tsx","./src/_core/type/generiqueType.tsx","./src/action/Action.view.tsx","./src/action/ButtonAction.tsx","./src/addressSearch/AddressSearch.tsx","./src/addressSearch/AddressSearch.view.tsx","./src/badge/Badge.tsx","./src/badge/Badge.view.tsx","./src/button/Button.tsx","./src/button/Button.view.tsx","./src/button/button.interface.tsx","./src/button/buttonActions/ButtonActions.tsx","./src/button/buttonFile/ButtonFile.tsx","./src/button/buttonFile/ButtonFile.view.tsx","./src/button/buttonFilters/ButtonFilters.tsx","./src/button/buttonImport/ButtonImport.tsx","./src/button/buttonImport/ButtonImport.view.tsx","./src/card/Card.tsx","./src/card/Card.view.tsx","./src/card/card.interface.tsx","./src/card/cardAction.interface.tsx","./src/card/cardAction/CardAction.tsx","./src/card/hook/useCardInteractions.tsx","./src/carousel/Carousel.tsx","./src/carousel/Carousel.view.tsx","./src/damier/Damier.tsx","./src/damier/Damier.view.tsx","./src/damier/damierCell/DamierCell.tsx","./src/damier/damierCell/damierCell.interface.tsx","./src/dataTable/DataTable.tsx","./src/dataTable/DataTable.view.tsx","./src/dataTable/dataTable.interface.ts","./src/dataTable/dataTable.utils.ts","./src/dataTable/useDataTableState.tsx","./src/dataTable/dataTableActions/DataTableAction.tsx","./src/dataTable/dataTableActions/DataTableActionMenu.tsx","./src/dataTable/dataTableColumn/DataTableColumn.tsx","./src/dataTable/dataTableColumn/dataTableColumnFilter/DataTableColumnFilter.tsx","./src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDate/DataTableColumnFilterDate.tsx","./src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDateRange/dataTableColumnFilterDateRange.tsx","./src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterEnum/DataTableColumnFilterEnum.tsx","./src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterString/DataTableColumnFilterString.tsx","./src/dataTable/dataTableColumn/dataTableColumnSort/DataTableColumnSort.tsx","./src/dataTable/dataTableFilters/DataTableFilters.tsx","./src/dataTable/dataTableLoading/DataTableLoading.tsx","./src/dataTable/dataTableRow/DataTableRow.tsx","./src/datePicker/DatePicker.tsx","./src/datePicker/DatePicker.view.tsx","./src/docs/ComponentDocs.tsx","./src/docs/catalog.ts","./src/docs/documentation.types.ts","./src/docs/virtual.d.ts","./src/expands/Expands.tsx","./src/expands/Expands.view.tsx","./src/expands/expand/expand.interface.tsx","./src/expands/expand/expand.tsx","./src/filAriane/FilAriane.tsx","./src/filAriane/FilAriane.view.tsx","./src/filAriane/filAriane.interface.tsx","./src/form/Form.tsx","./src/form/Form.view.tsx","./src/form/form.enum.ts","./src/form/form.interface.tsx","./src/form/input/Input.tsx","./src/form/inputNumber/InputNumber.tsx","./src/form/inputNumber/InputNumber.view.tsx","./src/form/inputPrice/InputPrice.tsx","./src/form/inputPrice/InputPrice.view.tsx","./src/form/textArea/TextArea.tsx","./src/form/textArea/TextArea.view.tsx","./src/geocoding/GeocodingService.ts","./src/geocoding/geocoding.interface.ts","./src/grid/Grid.tsx","./src/grid/Grid.view.tsx","./src/grid/grid.interface.tsx","./src/grid/col/Col.tsx","./src/grid/col/colStyled/ColStyled.tsx","./src/grid/container/Container.tsx","./src/grid/row/Row.tsx","./src/header/Header.tsx","./src/header/Header.view.tsx","./src/header/header.interface.tsx","./src/home/Home.tsx","./src/icon/Icon.tsx","./src/icon/Icons.view.tsx","./src/icon/icon.interface.tsx","./src/icon/iconSize.enum.ts","./src/loader/Loader.tsx","./src/loader/Loader.view.tsx","./src/menus/Menus.tsx","./src/menus/Menus.view.tsx","./src/menus/menu/Menu.tsx","./src/menus/menu/menu.interface.tsx","./src/message/Message.tsx","./src/message/Message.view.tsx","./src/modal/Modal.tsx","./src/modal/Modal.view.tsx","./src/notFound/NotFound.tsx","./src/overlayPanel/OverlayPanel.tsx","./src/overlayPanel/OverlayPanel.view.tsx","./src/overlayPanel/overlay.context.tsx","./src/overlayPanel/overlayPanelStyled/OverlayPanelStyled.tsx","./src/pdfViewer/PdfViewer.tsx","./src/pdfViewer/PdfViewer.view.tsx","./src/quantity/Quantity.tsx","./src/quantity/Quantity.view.tsx","./src/search/Search.tsx","./src/search/Search.view.tsx","./src/select/Select.tsx","./src/select/Select.view.tsx","./src/select/selectOption.interface.ts","./src/sidebar/Sidebar.tsx","./src/sidebar/Sidebar.view.tsx","./src/sidebarData/SidebarData.tsx","./src/sidebarData/SidebarData.view.tsx","./src/tabs/Tabs.tsx","./src/tabs/Tabs.view.tsx","./src/toaster/Toaster.tsx","./src/toaster/Toaster.view.tsx","./src/toaster/store/useToasterStore.tsx"],"version":"5.9.3"}
1
+ {"root":["./src/App.menu.tsx","./src/App.routes.tsx","./src/App.tsx","./src/index.ts","./src/main.tsx","./src/_core/hooks/HistoryProvider.tsx","./src/_core/hooks/ImageChecker.tsx","./src/_core/hooks/imageExist.tsx","./src/_core/hooks/isEAN13.tsx","./src/_core/hooks/objectToQueryParams.tsx","./src/_core/hooks/useCurrency.tsx","./src/_core/hooks/useDateutils.ts","./src/_core/hooks/useIsMobile.ts","./src/_core/hooks/useToken.tsx","./src/_core/hooks/useValidate.tsx","./src/_core/hooks/widgetSupport.tsx","./src/_core/type/generiqueType.tsx","./src/action/Action.view.tsx","./src/action/ButtonAction.tsx","./src/addressSearch/AddressSearch.tsx","./src/addressSearch/AddressSearch.view.tsx","./src/badge/Badge.tsx","./src/badge/Badge.view.tsx","./src/button/Button.tsx","./src/button/Button.view.tsx","./src/button/button.interface.tsx","./src/button/buttonActions/ButtonActions.tsx","./src/button/buttonFile/ButtonFile.tsx","./src/button/buttonFile/ButtonFile.view.tsx","./src/button/buttonFilters/ButtonFilters.tsx","./src/button/buttonImport/ButtonImport.tsx","./src/button/buttonImport/ButtonImport.view.tsx","./src/card/Card.tsx","./src/card/Card.view.tsx","./src/card/card.interface.tsx","./src/card/cardAction.interface.tsx","./src/card/cardAction/CardAction.tsx","./src/card/hook/useCardInteractions.tsx","./src/carousel/Carousel.tsx","./src/carousel/Carousel.view.tsx","./src/damier/Damier.tsx","./src/damier/Damier.view.tsx","./src/damier/damierCell/DamierCell.tsx","./src/damier/damierCell/damierCell.interface.tsx","./src/dataTable/DataTable.tsx","./src/dataTable/DataTable.view.tsx","./src/dataTable/dataTable.interface.ts","./src/dataTable/dataTable.utils.ts","./src/dataTable/useDataTableState.tsx","./src/dataTable/dataTableActions/DataTableAction.tsx","./src/dataTable/dataTableActions/DataTableActionMenu.tsx","./src/dataTable/dataTableColumn/DataTableColumn.tsx","./src/dataTable/dataTableColumn/dataTableColumnFilter/DataTableColumnFilter.tsx","./src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDate/DataTableColumnFilterDate.tsx","./src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDateRange/dataTableColumnFilterDateRange.tsx","./src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterEnum/DataTableColumnFilterEnum.tsx","./src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterString/DataTableColumnFilterString.tsx","./src/dataTable/dataTableColumn/dataTableColumnSort/DataTableColumnSort.tsx","./src/dataTable/dataTableFilters/DataTableFilters.tsx","./src/dataTable/dataTableLoading/DataTableLoading.tsx","./src/dataTable/dataTableRow/DataTableRow.tsx","./src/datePicker/DatePicker.tsx","./src/datePicker/DatePicker.view.tsx","./src/docs/ComponentDocs.tsx","./src/docs/catalog.ts","./src/docs/documentation.types.ts","./src/docs/virtual.d.ts","./src/expands/Expands.tsx","./src/expands/Expands.view.tsx","./src/expands/expand/expand.interface.tsx","./src/expands/expand/expand.tsx","./src/filAriane/FilAriane.tsx","./src/filAriane/FilAriane.view.tsx","./src/filAriane/filAriane.interface.tsx","./src/form/Form.tsx","./src/form/Form.view.tsx","./src/form/form.enum.ts","./src/form/form.interface.tsx","./src/form/input/Input.tsx","./src/form/inputNumber/InputNumber.tsx","./src/form/inputNumber/InputNumber.view.tsx","./src/form/inputPrice/InputPrice.tsx","./src/form/inputPrice/InputPrice.view.tsx","./src/form/textArea/TextArea.tsx","./src/form/textArea/TextArea.view.tsx","./src/geocoding/CityGeocodingService.ts","./src/geocoding/GeocodingService.ts","./src/geocoding/geocoding.interface.ts","./src/grid/Grid.tsx","./src/grid/Grid.view.tsx","./src/grid/grid.interface.tsx","./src/grid/col/Col.tsx","./src/grid/col/colStyled/ColStyled.tsx","./src/grid/container/Container.tsx","./src/grid/row/Row.tsx","./src/header/Header.tsx","./src/header/Header.view.tsx","./src/header/header.interface.tsx","./src/home/Home.tsx","./src/icon/Icon.tsx","./src/icon/Icons.view.tsx","./src/icon/icon.interface.tsx","./src/icon/iconSize.enum.ts","./src/loader/Loader.tsx","./src/loader/Loader.view.tsx","./src/menus/Menus.tsx","./src/menus/Menus.view.tsx","./src/menus/menu/Menu.tsx","./src/menus/menu/menu.interface.tsx","./src/message/Message.tsx","./src/message/Message.view.tsx","./src/modal/Modal.tsx","./src/modal/Modal.view.tsx","./src/notFound/NotFound.tsx","./src/overlayPanel/OverlayPanel.tsx","./src/overlayPanel/OverlayPanel.view.tsx","./src/overlayPanel/overlay.context.tsx","./src/overlayPanel/overlayPanelStyled/OverlayPanelStyled.tsx","./src/pdfViewer/PdfViewer.tsx","./src/pdfViewer/PdfViewer.view.tsx","./src/quantity/Quantity.tsx","./src/quantity/Quantity.view.tsx","./src/search/Search.tsx","./src/search/Search.view.tsx","./src/select/Select.tsx","./src/select/Select.view.tsx","./src/select/selectOption.interface.ts","./src/sidebar/Sidebar.tsx","./src/sidebar/Sidebar.view.tsx","./src/sidebarData/SidebarData.tsx","./src/sidebarData/SidebarData.view.tsx","./src/tabs/Tabs.tsx","./src/tabs/Tabs.view.tsx","./src/toaster/Toaster.tsx","./src/toaster/Toaster.view.tsx","./src/toaster/store/useToasterStore.tsx"],"version":"5.9.3"}
package/vite.config.ts CHANGED
@@ -22,6 +22,13 @@ export default defineConfig(({ command, mode }) => ({
22
22
  },
23
23
  rollupOptions: {
24
24
  external: [/^react(\/.*)?$/, /^react-dom(\/.*)?$/, "react-router", "react-router-dom"],
25
+ // Rapport de durée des plugins : bruit à chaque build
26
+ checks: { pluginTimings: false },
27
+ onwarn(warning, warn) {
28
+ // 'use client' de react-calendar : directive Next.js, sans effet ici
29
+ if (warning.code === "MODULE_LEVEL_DIRECTIVE") return;
30
+ warn(warning);
31
+ },
25
32
  },
26
33
  },
27
34
  }));