allaw-ui 4.8.8 → 4.9.0

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.
@@ -12,6 +12,9 @@ export interface SearchBarProps {
12
12
  style?: "classic" | "form";
13
13
  disableAutofill?: boolean;
14
14
  showLocate?: boolean;
15
+ minChar?: number;
16
+ /** Affiche un indicateur de chargement à droite lorsque true */
17
+ loading?: boolean;
15
18
  resolveCityFromCoords?: (lat: number, lon: number) => Promise<string | undefined>;
16
19
  }
17
20
  declare const SearchBar: React.FC<SearchBarProps>;
@@ -51,9 +51,9 @@ import "../../../styles/global.css";
51
51
  import "../../../styles/icons.css";
52
52
  import TinyInfo from "../typography/TinyInfo";
53
53
  var SearchBar = function (_a) {
54
- var _b = _a.placeholder, placeholder = _b === void 0 ? "Faites une recherche" : _b, endIcon = _a.endIcon, startIcon = _a.startIcon, _c = _a.value, controlledValue = _c === void 0 ? "" : _c, onChange = _a.onChange, _d = _a.showClear, showClear = _d === void 0 ? false : _d, _e = _a.size, size = _e === void 0 ? "normal" : _e, _f = _a.style, styleProp = _f === void 0 ? "classic" : _f, _g = _a.disableAutofill, disableAutofill = _g === void 0 ? false : _g, _h = _a.showLocate, showLocate = _h === void 0 ? false : _h, resolveCityFromCoords = _a.resolveCityFromCoords;
55
- var _j = useState(controlledValue), value = _j[0], setValue = _j[1];
56
- var _k = useState(null), locationError = _k[0], setLocationError = _k[1];
54
+ var _b = _a.placeholder, placeholder = _b === void 0 ? "Faites une recherche" : _b, endIcon = _a.endIcon, startIcon = _a.startIcon, _c = _a.value, controlledValue = _c === void 0 ? "" : _c, onChange = _a.onChange, _d = _a.showClear, showClear = _d === void 0 ? false : _d, _e = _a.size, size = _e === void 0 ? "normal" : _e, _f = _a.style, styleProp = _f === void 0 ? "classic" : _f, _g = _a.disableAutofill, disableAutofill = _g === void 0 ? false : _g, _h = _a.showLocate, showLocate = _h === void 0 ? false : _h, minChar = _a.minChar, _j = _a.loading, loading = _j === void 0 ? false : _j, resolveCityFromCoords = _a.resolveCityFromCoords;
55
+ var _k = useState(controlledValue), value = _k[0], setValue = _k[1];
56
+ var _l = useState(null), locationError = _l[0], setLocationError = _l[1];
57
57
  var handleChange = function (event) {
58
58
  var newValue = event.target.value;
59
59
  setValue(newValue);
@@ -137,10 +137,13 @@ var SearchBar = function (_a) {
137
137
  }
138
138
  }, { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 });
139
139
  };
140
+ var currentValue = controlledValue || value;
141
+ var hasMinChar = minChar && minChar > 0 && currentValue.length >= minChar;
140
142
  var wrapperClassName = [
141
143
  styles.searchBar,
142
144
  styleProp === "form" ? styles.styleForm : "",
143
145
  size === "big" ? styles.sizeBig : "",
146
+ hasMinChar ? styles.minCharReached : "",
144
147
  ]
145
148
  .filter(Boolean)
146
149
  .join(" ");
@@ -156,13 +159,16 @@ var SearchBar = function (_a) {
156
159
  }))),
157
160
  showClear && (controlledValue || value) && (React.createElement("button", { type: "button", className: styles.searchBarClearButton, onClick: handleClear, "aria-label": "Effacer la recherche" },
158
161
  React.createElement("i", { className: "allaw-icon-x-small" }))),
159
- endIcon && (React.createElement("button", { className: styles.searchBarIconButton, tabIndex: -1, "aria-label": "Rechercher" },
162
+ loading && (React.createElement("span", { className: styles.searchBarLoader, "aria-live": "polite", "aria-busy": "true" })),
163
+ !loading && endIcon && (React.createElement("button", { className: styles.searchBarIconButton, tabIndex: -1, "aria-label": "Rechercher" },
160
164
  React.createElement("i", { className: endIcon }))),
161
165
  showLocate && (React.createElement("button", { type: "button", className: styles.searchBarLocateButton, onClick: function (e) {
162
166
  e.preventDefault();
163
167
  e.stopPropagation();
164
168
  handleLocate();
165
- }, "aria-label": "Me localiser", title: "Me localiser" }, "Me localiser"))),
169
+ }, "aria-label": "Me localiser", title: "Me localiser" },
170
+ React.createElement("span", { className: styles.searchBarLocateText }, "Me localiser"),
171
+ React.createElement("i", { className: "allaw-icon-map-pin ".concat(styles.searchBarLocateIcon) })))),
166
172
  locationError && (React.createElement("div", { className: styles.searchBarError },
167
173
  React.createElement(TinyInfo, { variant: "medium12", color: "actions-error", text: locationError, align: "left" })))));
168
174
  };
@@ -16,6 +16,8 @@ declare namespace _default {
16
16
  let startIcon: undefined;
17
17
  let showLocate: boolean;
18
18
  let locateIcon: string;
19
+ let minChar: undefined;
20
+ let loading: boolean;
19
21
  }
20
22
  export namespace argTypes {
21
23
  export namespace placeholder {
@@ -90,6 +92,25 @@ declare namespace _default {
90
92
  export { description_3 as description };
91
93
  }
92
94
  export { showClear_1 as showClear };
95
+ export namespace minChar_1 {
96
+ export namespace control_9 {
97
+ let type_7: string;
98
+ export { type_7 as type };
99
+ export let min: number;
100
+ export let max: number;
101
+ }
102
+ export { control_9 as control };
103
+ let description_4: string;
104
+ export { description_4 as description };
105
+ }
106
+ export { minChar_1 as minChar };
107
+ export namespace loading_1 {
108
+ let control_10: string;
109
+ export { control_10 as control };
110
+ let description_5: string;
111
+ export { description_5 as description };
112
+ }
113
+ export { loading_1 as loading };
93
114
  export namespace onChange_1 {
94
115
  let action_1: string;
95
116
  export { action_1 as action };
@@ -115,4 +136,7 @@ export const FormStyle: any;
115
136
  export const WithStartIcon: any;
116
137
  export const BigFormStartIconNoEnd: any;
117
138
  export const WithLocate: any;
139
+ export const WithMinChar: any;
140
+ export const ResponsiveLocate: any;
141
+ export const WithLoading: any;
118
142
  import SearchBar from "./SearchBar";
@@ -21,7 +21,7 @@ export default {
21
21
  component: SearchBar,
22
22
  tags: ["autodocs"],
23
23
  excludeStories: /.*Data$/,
24
- args: __assign(__assign({}, ActionsData), { endIcon: "allaw-icon-search", showClear: false, size: "normal", style: "classic", startIcon: undefined, showLocate: false, locateIcon: "allaw-icon-map-pin" }),
24
+ args: __assign(__assign({}, ActionsData), { endIcon: "allaw-icon-search", showClear: false, size: "normal", style: "classic", startIcon: undefined, showLocate: false, locateIcon: "allaw-icon-map-pin", minChar: undefined, loading: false }),
25
25
  argTypes: {
26
26
  placeholder: {
27
27
  control: {
@@ -68,6 +68,14 @@ export default {
68
68
  control: "boolean",
69
69
  description: "Affiche une croix pour effacer le champ si true.",
70
70
  },
71
+ minChar: {
72
+ control: { type: "number", min: 0, max: 20 },
73
+ description: "Nombre minimum de caractères pour changer la couleur de bordure en vert (#29a36a).",
74
+ },
75
+ loading: {
76
+ control: "boolean",
77
+ description: "Affiche un loader à la fin du champ.",
78
+ },
71
79
  onChange: { action: "changed" },
72
80
  },
73
81
  parameters: {
@@ -153,3 +161,37 @@ WithLocate.args = {
153
161
  showLocate: true,
154
162
  locateIcon: "allaw-icon-map-pin",
155
163
  };
164
+ export var WithMinChar = Template.bind({});
165
+ WithMinChar.args = {
166
+ placeholder: "Saisissez au moins 6 caractères",
167
+ endIcon: "allaw-icon-search",
168
+ showClear: true,
169
+ size: "normal",
170
+ style: "form",
171
+ minChar: 6,
172
+ };
173
+ export var ResponsiveLocate = Template.bind({});
174
+ ResponsiveLocate.args = {
175
+ placeholder: "Ville (redimensionnez la fenêtre)",
176
+ startIcon: "allaw-icon-map-pin",
177
+ showClear: true,
178
+ size: "normal",
179
+ style: "form",
180
+ showLocate: true,
181
+ };
182
+ export var WithLoading = Template.bind({});
183
+ WithLoading.args = {
184
+ placeholder: "Recherche en cours...",
185
+ endIcon: "allaw-icon-search",
186
+ showClear: false,
187
+ size: "normal",
188
+ style: "classic",
189
+ loading: true,
190
+ };
191
+ ResponsiveLocate.parameters = {
192
+ docs: {
193
+ description: {
194
+ story: "Le bouton 'Me localiser' devient une icône en dessous de 480px de largeur. Redimensionnez votre navigateur pour voir l'effet.",
195
+ },
196
+ },
197
+ };
@@ -110,6 +110,37 @@
110
110
  font-size: 13px;
111
111
  }
112
112
 
113
+ .searchBarLocateText {
114
+ display: inline;
115
+ }
116
+
117
+ .searchBarLocateIcon {
118
+ display: none;
119
+ font-size: 14px;
120
+ }
121
+
122
+ /* Responsive behavior for mobile */
123
+ @media (max-width: 479px) {
124
+ .searchBarLocateText {
125
+ display: none;
126
+ }
127
+
128
+ .searchBarLocateIcon {
129
+ display: inline;
130
+ }
131
+
132
+ .searchBarLocateButton {
133
+ padding: 0;
134
+ width: 28px;
135
+ min-width: 28px;
136
+ }
137
+
138
+ .sizeBig .searchBarLocateButton {
139
+ width: 32px;
140
+ min-width: 32px;
141
+ }
142
+ }
143
+
113
144
  .searchBarClearButton {
114
145
  display: flex;
115
146
  align-items: center;
@@ -152,3 +183,41 @@
152
183
  margin-top: 8px;
153
184
  margin-left: 14px;
154
185
  }
186
+
187
+ /* MinChar variant */
188
+ .minCharReached {
189
+ border-color: #25beeb !important;
190
+ }
191
+
192
+ .minCharReached:hover {
193
+ border-color: #25beeb !important;
194
+ }
195
+
196
+ .minCharReached:focus-within {
197
+ border-color: #25beeb !important;
198
+ }
199
+
200
+ /* Loader */
201
+ .searchBarLoader {
202
+ width: 18px;
203
+ height: 18px;
204
+ border-radius: 50%;
205
+ border: 2px solid rgba(37, 190, 235, 0.25);
206
+ border-top-color: #25beeb;
207
+ animation: searchBarSpin 0.8s linear infinite;
208
+ margin-right: 8px; /* décale de 4px depuis la bordure droite */
209
+ }
210
+
211
+ .sizeBig .searchBarLoader {
212
+ width: 20px;
213
+ height: 20px;
214
+ }
215
+
216
+ @keyframes searchBarSpin {
217
+ from {
218
+ transform: rotate(0deg);
219
+ }
220
+ to {
221
+ transform: rotate(360deg);
222
+ }
223
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "allaw-ui",
3
- "version": "4.8.8",
3
+ "version": "4.9.0",
4
4
  "description": "Composants UI pour l'application Allaw",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",