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.
- package/dist/components/atoms/inputs/SearchBar.d.ts +3 -0
- package/dist/components/atoms/inputs/SearchBar.js +11 -5
- package/dist/components/atoms/inputs/SearchBar.stories.d.ts +24 -0
- package/dist/components/atoms/inputs/SearchBar.stories.js +43 -1
- package/dist/components/atoms/inputs/searchBar.module.css +69 -0
- package/package.json +1 -1
|
@@ -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
|
|
56
|
-
var
|
|
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
|
-
|
|
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" },
|
|
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
|
+
}
|