allaw-ui 2.4.8 → 2.5.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/selects/Select.d.ts +1 -0
- package/dist/components/atoms/selects/Select.js +99 -13
- package/dist/components/atoms/selects/Select.module.css +48 -3
- package/dist/components/atoms/selects/Select.stories.d.ts +14 -5
- package/dist/components/atoms/selects/Select.stories.js +7 -0
- package/dist/components/molecules/selectForm/SelectForm.d.ts +1 -0
- package/dist/components/molecules/selectForm/SelectForm.js +2 -2
- package/dist/components/molecules/selectForm/SelectForm.stories.d.ts +26 -12
- package/dist/components/molecules/selectForm/SelectForm.stories.js +8 -0
- package/package.json +1 -1
|
@@ -14,18 +14,21 @@ import "../../../styles/global.css";
|
|
|
14
14
|
import TinyInfo from "../typography/TinyInfo";
|
|
15
15
|
function Select(_a, ref) {
|
|
16
16
|
var _b;
|
|
17
|
-
var items = _a.items, selectedItem = _a.selectedItem, _c = _a.placeholder, placeholder = _c === void 0 ? "Choisir..." : _c, _d = _a.multiple, multiple = _d === void 0 ? false : _d, _e = _a.isRequired, isRequired = _e === void 0 ? false : _e, _f = _a.showError, showError = _f === void 0 ? false : _f, _g = _a.width, width = _g === void 0 ? 100 : _g, onChange = _a.onChange, onError = _a.onError;
|
|
17
|
+
var items = _a.items, selectedItem = _a.selectedItem, _c = _a.placeholder, placeholder = _c === void 0 ? "Choisir..." : _c, _d = _a.multiple, multiple = _d === void 0 ? false : _d, _e = _a.isRequired, isRequired = _e === void 0 ? false : _e, _f = _a.showError, showError = _f === void 0 ? false : _f, _g = _a.width, width = _g === void 0 ? 100 : _g, maxItems = _a.maxItems, onChange = _a.onChange, onError = _a.onError;
|
|
18
18
|
var _h = useState(false), isOpen = _h[0], setIsOpen = _h[1];
|
|
19
19
|
var _j = useState((multiple ? selectedItem || [] : selectedItem || "")), selected = _j[0], setSelected = _j[1];
|
|
20
20
|
var _k = useState(""), error = _k[0], setError = _k[1];
|
|
21
21
|
var selectRef = useRef(null);
|
|
22
22
|
var listRef = useRef(null);
|
|
23
|
-
var
|
|
23
|
+
var tagContainerRef = useRef(null);
|
|
24
|
+
var _l = useState([]), visibleTags = _l[0], setVisibleTags = _l[1];
|
|
25
|
+
var _m = useState(0), hiddenCount = _m[0], setHiddenCount = _m[1];
|
|
26
|
+
var _o = useState({
|
|
24
27
|
top: 0,
|
|
25
28
|
left: 0,
|
|
26
29
|
width: 0,
|
|
27
|
-
}), listPosition =
|
|
28
|
-
var
|
|
30
|
+
}), listPosition = _o[0], setListPosition = _o[1];
|
|
31
|
+
var _p = useState("bottom"), placement = _p[0], setPlacement = _p[1];
|
|
29
32
|
useEffect(function () {
|
|
30
33
|
setSelected((multiple ? selectedItem || [] : selectedItem || ""));
|
|
31
34
|
}, [selectedItem, multiple]);
|
|
@@ -40,14 +43,89 @@ function Select(_a, ref) {
|
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
45
|
}, [isOpen, multiple, selectedItem]);
|
|
46
|
+
useEffect(function () {
|
|
47
|
+
if (tagContainerRef.current &&
|
|
48
|
+
Array.isArray(selected) &&
|
|
49
|
+
selected.length > 0) {
|
|
50
|
+
// Initialiser avec tous les tags visibles
|
|
51
|
+
setVisibleTags(selected);
|
|
52
|
+
setHiddenCount(0);
|
|
53
|
+
requestAnimationFrame(function () {
|
|
54
|
+
var container = tagContainerRef.current;
|
|
55
|
+
if (!container)
|
|
56
|
+
return;
|
|
57
|
+
var containerWidth = container.offsetWidth - 40; // Espace pour l'icône et les marges
|
|
58
|
+
// Fonction pour calculer la largeur totale des tags
|
|
59
|
+
var calculateTagsWidth = function (tags) {
|
|
60
|
+
return tags.reduce(function (total, tag) { return total + tag.offsetWidth + 6; }, 0); // 6px pour le gap
|
|
61
|
+
};
|
|
62
|
+
// Fonction pour créer et mesurer le compteur
|
|
63
|
+
var measureCounter = function (count) {
|
|
64
|
+
var counter = document.createElement("span");
|
|
65
|
+
counter.className = styles.hiddenTagCount;
|
|
66
|
+
counter.textContent = "+ ".concat(count, " autre").concat(count > 1 ? "s" : "");
|
|
67
|
+
container.appendChild(counter);
|
|
68
|
+
var width = counter.offsetWidth;
|
|
69
|
+
container.removeChild(counter);
|
|
70
|
+
return width;
|
|
71
|
+
};
|
|
72
|
+
// Obtenir tous les tags (sans le compteur)
|
|
73
|
+
var allTags = Array.from(container.children).filter(function (child) { return !child.classList.contains("hiddenTagCount"); });
|
|
74
|
+
// Si tous les tags tiennent, on les affiche tous
|
|
75
|
+
var totalWidth = calculateTagsWidth(allTags);
|
|
76
|
+
if (totalWidth <= containerWidth) {
|
|
77
|
+
setVisibleTags(selected);
|
|
78
|
+
setHiddenCount(0);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// Sinon, on cherche le nombre optimal de tags à afficher
|
|
82
|
+
var bestVisibleCount = 0;
|
|
83
|
+
// On teste chaque combinaison possible
|
|
84
|
+
for (var i = 1; i <= allTags.length; i++) {
|
|
85
|
+
var visibleTags_1 = allTags.slice(0, i);
|
|
86
|
+
var hiddenCount_1 = selected.length - i;
|
|
87
|
+
var counterWidth = hiddenCount_1 > 0 ? measureCounter(hiddenCount_1) + 6 : 0;
|
|
88
|
+
var totalWidth_1 = calculateTagsWidth(visibleTags_1) + counterWidth;
|
|
89
|
+
if (totalWidth_1 <= containerWidth) {
|
|
90
|
+
bestVisibleCount = i;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
break; // On sort dès qu'on dépasse la largeur disponible
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Mettre à jour avec la meilleure combinaison trouvée
|
|
97
|
+
if (bestVisibleCount > 0) {
|
|
98
|
+
setVisibleTags(selected.slice(0, bestVisibleCount));
|
|
99
|
+
setHiddenCount(selected.length - bestVisibleCount);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
// Fallback : afficher au moins un tag
|
|
103
|
+
setVisibleTags(selected.slice(0, 1));
|
|
104
|
+
setHiddenCount(selected.length - 1);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
setVisibleTags([]);
|
|
110
|
+
setHiddenCount(0);
|
|
111
|
+
}
|
|
112
|
+
}, [selected]);
|
|
43
113
|
var handleSelect = function (item) {
|
|
44
114
|
var newSelected;
|
|
45
115
|
if (multiple) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
116
|
+
var currentSelected = selected;
|
|
117
|
+
if (currentSelected.includes(item.value)) {
|
|
118
|
+
newSelected = currentSelected.filter(function (i) { return i !== item.value; });
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
if (maxItems && currentSelected.length >= maxItems) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
newSelected = __spreadArray(__spreadArray([], currentSelected, true), [item.value], false);
|
|
125
|
+
if (maxItems && currentSelected.length + 1 >= maxItems) {
|
|
126
|
+
setIsOpen(false);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
51
129
|
}
|
|
52
130
|
else {
|
|
53
131
|
newSelected = item.value;
|
|
@@ -134,15 +212,23 @@ function Select(_a, ref) {
|
|
|
134
212
|
: "", " ").concat(!multiple && item.value === selectedItem ? styles.highlighted : "", " ").concat(!multiple ? styles.singleSelect : ""), onClick: function () { return handleSelect(item); } },
|
|
135
213
|
multiple && React.createElement("span", { className: styles.selectItemIcon }),
|
|
136
214
|
React.createElement("span", { className: styles.selectItemText }, item.label))); }))); };
|
|
215
|
+
var renderTags = function (selectedValues) {
|
|
216
|
+
if (!selectedValues.length)
|
|
217
|
+
return null;
|
|
218
|
+
return (React.createElement("div", { ref: tagContainerRef, className: styles.tagContainer },
|
|
219
|
+
visibleTags.map(function (val) {
|
|
220
|
+
var _a;
|
|
221
|
+
return (React.createElement("span", { key: val, className: styles.tag }, (_a = items.find(function (item) { return item.value === val; })) === null || _a === void 0 ? void 0 : _a.label));
|
|
222
|
+
}),
|
|
223
|
+
hiddenCount > 0 && (React.createElement("span", { className: "".concat(styles.hiddenTagCount, " hiddenTagCount") }, "+ ".concat(hiddenCount, " autre").concat(hiddenCount > 1 ? "s" : "")))));
|
|
224
|
+
};
|
|
137
225
|
useImperativeHandle(ref, function () { return ({
|
|
138
226
|
validate: function () { return validateSelect(selected); },
|
|
139
227
|
}); });
|
|
140
228
|
return (React.createElement("div", { ref: selectRef, className: "".concat(styles.selectContainer, " ").concat(isOpen ? styles.selectPressed : ""), style: { width: "".concat(width, "%") } },
|
|
141
|
-
React.createElement("button", { type: "button", className: "".concat(styles.select, " ").concat(isOpen ? styles.selectPressed : styles.selectDefault), onClick: toggleOpen, style: { width: "100%" } },
|
|
229
|
+
React.createElement("button", { type: "button", className: "".concat(styles.select, " ").concat(isOpen ? styles.selectPressed : styles.selectDefault, " ").concat(multiple ? styles.selectMultiple : styles.selectSingle), onClick: toggleOpen, style: { width: "100%" } },
|
|
142
230
|
React.createElement("span", { className: styles.selectText }, Array.isArray(selected) && selected.length > 0
|
|
143
|
-
? selected
|
|
144
|
-
.map(function (val) { var _a; return (_a = items.find(function (item) { return item.value === val; })) === null || _a === void 0 ? void 0 : _a.label; })
|
|
145
|
-
.join(", ")
|
|
231
|
+
? renderTags(selected)
|
|
146
232
|
: !Array.isArray(selected) && selected
|
|
147
233
|
? (_b = items.find(function (item) { return item.value === selected; })) === null || _b === void 0 ? void 0 : _b.label
|
|
148
234
|
: placeholder),
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
.selectContainer {
|
|
2
2
|
position: relative;
|
|
3
|
+
min-height: 40px;
|
|
3
4
|
}
|
|
4
5
|
|
|
5
6
|
.select {
|
|
6
7
|
display: flex;
|
|
7
|
-
padding: 8px 16px;
|
|
8
8
|
justify-content: space-between;
|
|
9
|
-
align-items:
|
|
9
|
+
align-items: flex-start;
|
|
10
10
|
gap: 11px;
|
|
11
11
|
border-radius: 8px;
|
|
12
12
|
background: var(--secondary-light-grey, #f4f7fb);
|
|
@@ -31,6 +31,10 @@
|
|
|
31
31
|
white-space: nowrap;
|
|
32
32
|
overflow: hidden;
|
|
33
33
|
text-overflow: ellipsis;
|
|
34
|
+
display: flex;
|
|
35
|
+
flex: 1;
|
|
36
|
+
min-height: 24px;
|
|
37
|
+
padding: 2px 0;
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
.selectIcon {
|
|
@@ -40,7 +44,7 @@
|
|
|
40
44
|
display: flex;
|
|
41
45
|
align-items: center;
|
|
42
46
|
justify-content: center;
|
|
43
|
-
padding-top:
|
|
47
|
+
padding-top: 2px;
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
.selectList {
|
|
@@ -113,3 +117,44 @@
|
|
|
113
117
|
.selectItem.highlighted {
|
|
114
118
|
background-color: var(--venom-grey-dark, #d1dce8);
|
|
115
119
|
}
|
|
120
|
+
|
|
121
|
+
.tagContainer {
|
|
122
|
+
display: flex;
|
|
123
|
+
flex-wrap: nowrap;
|
|
124
|
+
gap: 6px;
|
|
125
|
+
align-items: center;
|
|
126
|
+
overflow: hidden;
|
|
127
|
+
width: 100%;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.tag {
|
|
131
|
+
background: var(--grey-venom, #e6edf5);
|
|
132
|
+
border-radius: 4px;
|
|
133
|
+
padding: 8px 8px;
|
|
134
|
+
font-size: 12px;
|
|
135
|
+
font-weight: 600;
|
|
136
|
+
color: var(--Primary-Mid-black, var(--primary-black, #171e25));
|
|
137
|
+
white-space: nowrap;
|
|
138
|
+
flex-shrink: 0;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.hiddenTagCount {
|
|
142
|
+
font-size: 12px;
|
|
143
|
+
font-weight: 600;
|
|
144
|
+
color: var(--Primary-Mid-black, var(--primary-black, #171e25));
|
|
145
|
+
white-space: nowrap;
|
|
146
|
+
flex-shrink: 0;
|
|
147
|
+
padding: 2px 0;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.select:hover .tag {
|
|
151
|
+
background-color: var(--venom-grey-dark, #d1dce8);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.selectMultiple {
|
|
155
|
+
padding: 6px 8px;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.selectSingle {
|
|
159
|
+
padding: 8px 16px;
|
|
160
|
+
}
|
|
@@ -39,19 +39,28 @@ declare namespace _default {
|
|
|
39
39
|
}
|
|
40
40
|
export { control_4 as control };
|
|
41
41
|
}
|
|
42
|
+
namespace maxItems {
|
|
43
|
+
export namespace control_5 {
|
|
44
|
+
let type_5: string;
|
|
45
|
+
export { type_5 as type };
|
|
46
|
+
export let min: number;
|
|
47
|
+
}
|
|
48
|
+
export { control_5 as control };
|
|
49
|
+
}
|
|
42
50
|
namespace onChange {
|
|
43
51
|
namespace table {
|
|
44
52
|
let disable: boolean;
|
|
45
53
|
}
|
|
46
54
|
}
|
|
47
55
|
namespace width {
|
|
48
|
-
export namespace
|
|
49
|
-
let
|
|
50
|
-
export {
|
|
51
|
-
|
|
56
|
+
export namespace control_6 {
|
|
57
|
+
let type_6: string;
|
|
58
|
+
export { type_6 as type };
|
|
59
|
+
let min_1: number;
|
|
60
|
+
export { min_1 as min };
|
|
52
61
|
export let max: number;
|
|
53
62
|
}
|
|
54
|
-
export {
|
|
63
|
+
export { control_6 as control };
|
|
55
64
|
}
|
|
56
65
|
}
|
|
57
66
|
export namespace parameters {
|
|
@@ -45,6 +45,12 @@ export default {
|
|
|
45
45
|
type: "text",
|
|
46
46
|
},
|
|
47
47
|
},
|
|
48
|
+
maxItems: {
|
|
49
|
+
control: {
|
|
50
|
+
type: "number",
|
|
51
|
+
min: 1,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
48
54
|
onChange: {
|
|
49
55
|
table: {
|
|
50
56
|
disable: true,
|
|
@@ -134,6 +140,7 @@ Multiple.args = {
|
|
|
134
140
|
placeholder: "Select...",
|
|
135
141
|
multiple: true,
|
|
136
142
|
isRequired: false,
|
|
143
|
+
maxItems: 3,
|
|
137
144
|
};
|
|
138
145
|
export var Required = Template.bind({});
|
|
139
146
|
Required.args = {
|
|
@@ -10,6 +10,7 @@ export interface SelectFormProps {
|
|
|
10
10
|
placeHolder?: string;
|
|
11
11
|
width?: number;
|
|
12
12
|
selectedItem?: string | string[];
|
|
13
|
+
maxItems?: number;
|
|
13
14
|
onChange?: (selected: string | string[]) => void;
|
|
14
15
|
variant?: "bold" | "semiBold" | "medium";
|
|
15
16
|
color?: "bleu-allaw" | "mid-grey" | "dark-grey" | "noir" | "pure-white" | "grey-venom" | "venom-grey-dark";
|
|
@@ -4,12 +4,12 @@ import "../../../styles/global.css";
|
|
|
4
4
|
import Paragraph from "../../atoms/typography/Paragraph";
|
|
5
5
|
import Select from "../../atoms/selects/Select";
|
|
6
6
|
var SelectForm = function (_a) {
|
|
7
|
-
var label = _a.label, isRequired = _a.isRequired, options = _a.options, isMultiple = _a.isMultiple, _b = _a.placeHolder, placeHolder = _b === void 0 ? "Sélectionner une valeur" : _b, _c = _a.width, width = _c === void 0 ? 100 : _c, selectedItem = _a.selectedItem, onChange = _a.onChange, _d = _a.variant, variant = _d === void 0 ? "medium" : _d, _e = _a.color, color = _e === void 0 ? "noir" : _e;
|
|
7
|
+
var label = _a.label, isRequired = _a.isRequired, options = _a.options, isMultiple = _a.isMultiple, _b = _a.placeHolder, placeHolder = _b === void 0 ? "Sélectionner une valeur" : _b, _c = _a.width, width = _c === void 0 ? 100 : _c, selectedItem = _a.selectedItem, maxItems = _a.maxItems, onChange = _a.onChange, _d = _a.variant, variant = _d === void 0 ? "medium" : _d, _e = _a.color, color = _e === void 0 ? "noir" : _e;
|
|
8
8
|
return (React.createElement("div", { className: "select-form" },
|
|
9
9
|
React.createElement(Paragraph, { variant: variant, color: color, text: React.createElement(React.Fragment, null,
|
|
10
10
|
label,
|
|
11
11
|
" ",
|
|
12
12
|
isRequired && React.createElement("span", { className: "select-form-required" }, "*")), size: "default" }),
|
|
13
|
-
React.createElement(Select, { items: options, multiple: isMultiple, isRequired: isRequired, width: width, placeholder: placeHolder, selectedItem: selectedItem, onChange: onChange })));
|
|
13
|
+
React.createElement(Select, { items: options, multiple: isMultiple, isRequired: isRequired, width: width, placeholder: placeHolder, selectedItem: selectedItem, maxItems: maxItems, onChange: onChange })));
|
|
14
14
|
};
|
|
15
15
|
export default SelectForm;
|
|
@@ -18,35 +18,49 @@ declare namespace _default {
|
|
|
18
18
|
let control_3: string;
|
|
19
19
|
export { control_3 as control };
|
|
20
20
|
}
|
|
21
|
-
namespace
|
|
21
|
+
namespace maxItems {
|
|
22
22
|
export namespace control_4 {
|
|
23
23
|
let type: string;
|
|
24
24
|
let min: number;
|
|
25
|
-
let max: number;
|
|
26
25
|
}
|
|
27
26
|
export { control_4 as control };
|
|
27
|
+
export namespace _if {
|
|
28
|
+
let arg: string;
|
|
29
|
+
let truthy: boolean;
|
|
30
|
+
}
|
|
31
|
+
export { _if as if };
|
|
28
32
|
}
|
|
29
|
-
namespace
|
|
30
|
-
|
|
31
|
-
export { control_5 as control };
|
|
32
|
-
}
|
|
33
|
-
namespace variant {
|
|
34
|
-
export namespace control_6 {
|
|
33
|
+
namespace width {
|
|
34
|
+
export namespace control_5 {
|
|
35
35
|
let type_1: string;
|
|
36
36
|
export { type_1 as type };
|
|
37
|
-
let
|
|
38
|
-
export {
|
|
37
|
+
let min_1: number;
|
|
38
|
+
export { min_1 as min };
|
|
39
|
+
export let max: number;
|
|
39
40
|
}
|
|
41
|
+
export { control_5 as control };
|
|
42
|
+
}
|
|
43
|
+
namespace selectedItem {
|
|
44
|
+
let control_6: string;
|
|
40
45
|
export { control_6 as control };
|
|
41
46
|
}
|
|
42
|
-
namespace
|
|
47
|
+
namespace variant {
|
|
43
48
|
export namespace control_7 {
|
|
44
49
|
let type_2: string;
|
|
45
50
|
export { type_2 as type };
|
|
51
|
+
let options_1: string[];
|
|
52
|
+
export { options_1 as options };
|
|
53
|
+
}
|
|
54
|
+
export { control_7 as control };
|
|
55
|
+
}
|
|
56
|
+
namespace color {
|
|
57
|
+
export namespace control_8 {
|
|
58
|
+
let type_3: string;
|
|
59
|
+
export { type_3 as type };
|
|
46
60
|
let options_2: string[];
|
|
47
61
|
export { options_2 as options };
|
|
48
62
|
}
|
|
49
|
-
export {
|
|
63
|
+
export { control_8 as control };
|
|
50
64
|
}
|
|
51
65
|
}
|
|
52
66
|
}
|
|
@@ -21,6 +21,13 @@ export default {
|
|
|
21
21
|
isRequired: { control: "boolean" },
|
|
22
22
|
options: { control: "object" },
|
|
23
23
|
isMultiple: { control: "boolean" },
|
|
24
|
+
maxItems: {
|
|
25
|
+
control: {
|
|
26
|
+
type: "number",
|
|
27
|
+
min: 1,
|
|
28
|
+
},
|
|
29
|
+
if: { arg: "isMultiple", truthy: true },
|
|
30
|
+
},
|
|
24
31
|
width: {
|
|
25
32
|
control: {
|
|
26
33
|
type: "number",
|
|
@@ -89,6 +96,7 @@ Multiple.args = {
|
|
|
89
96
|
isMultiple: true,
|
|
90
97
|
width: 100,
|
|
91
98
|
selectedItem: [],
|
|
99
|
+
maxItems: 3,
|
|
92
100
|
};
|
|
93
101
|
export var CustomWidth = Template.bind({});
|
|
94
102
|
CustomWidth.args = __assign(__assign({}, Default.args), { width: 50 });
|