@ultraviolet/ui 1.48.1 → 1.50.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.
@@ -1,4 +1,4 @@
1
- import { useState, useReducer, useMemo, createContext, useContext } from 'react';
1
+ import { useMemo, useState, useReducer, createContext, useContext } from 'react';
2
2
  import { jsx } from '@emotion/react/jsx-runtime';
3
3
 
4
4
  const SelectInputContext = /*#__PURE__*/createContext({
@@ -20,7 +20,8 @@ const SelectInputContext = /*#__PURE__*/createContext({
20
20
  selectedGroups: [],
21
21
  selectedValues: []
22
22
  },
23
- setSelectedData: () => {}
23
+ setSelectedData: () => {},
24
+ onChange: () => {}
24
25
  });
25
26
  const useSelectInput = () => useContext(SelectInputContext);
26
27
  const SelectInputProvider = ({
@@ -30,25 +31,39 @@ const SelectInputProvider = ({
30
31
  value,
31
32
  selectAllGroup,
32
33
  numberOfOptions,
33
- children
34
+ children,
35
+ onChange
34
36
  }) => {
35
- const defaultValue = value ? [value] : [];
37
+ const currentValue = useMemo(() => {
38
+ if (value) {
39
+ if (Array.isArray(value)) {
40
+ return value;
41
+ }
42
+ return [value];
43
+ }
44
+ return [];
45
+ }, [value]);
46
+ const selectedGroups = useMemo(() => {
47
+ if (Array.isArray(options)) {
48
+ return [];
49
+ }
50
+ return Object.keys(options).filter(group => options[group].every(groupOption => currentValue.includes(groupOption.value)));
51
+ }, [currentValue, options]);
36
52
  const [displayedOptions, setDisplayedOptions] = useState(options);
37
53
  const [isDropdownVisible, setIsDropdownVisible] = useState(false);
38
54
  const [searchInput, setSearchInput] = useState('');
39
- const allValues = [];
40
- const allGroups = [];
41
- if (!Array.isArray(options)) {
42
- Object.keys(options).map(group => options[group].map(option => {
43
- if (!option.disabled) {
44
- allValues.push(option);
45
- }
46
- return null;
47
- }));
48
- Object.keys(options).forEach(group => allGroups.push(group));
49
- } else {
50
- options.map(option => allValues.push(option));
51
- }
55
+ const allValues = useMemo(() => {
56
+ if (!Array.isArray(options)) {
57
+ return Object.keys(options).map(group => options[group].filter(option => !option.disabled)).flat();
58
+ }
59
+ return options;
60
+ }, [options]);
61
+ const allGroups = useMemo(() => {
62
+ if (!Array.isArray(options)) {
63
+ return Object.keys(options);
64
+ }
65
+ return [];
66
+ }, [options]);
52
67
  const reducer = (state, action) => {
53
68
  switch (action.type) {
54
69
  case 'selectAll':
@@ -60,7 +75,7 @@ const SelectInputProvider = ({
60
75
  };
61
76
  }
62
77
  return {
63
- selectedValues: allValues,
78
+ selectedValues: allValues.map(option => option.value),
64
79
  allSelected: true,
65
80
  selectedGroups: allGroups
66
81
  };
@@ -68,13 +83,13 @@ const SelectInputProvider = ({
68
83
  if (!Array.isArray(options)) {
69
84
  if (state.selectedGroups.includes(action.selectedGroup)) {
70
85
  return {
71
- selectedValues: [...state.selectedValues].filter(selectedValue => !options[action.selectedGroup].includes(selectedValue)),
86
+ selectedValues: [...state.selectedValues].filter(selectedValue => !options[action.selectedGroup].find(option => option.value === selectedValue)),
72
87
  allSelected: false,
73
88
  selectedGroups: state.selectedGroups.filter(selectedGroup => selectedGroup !== action.selectedGroup)
74
89
  };
75
90
  }
76
91
  const newSelectedValues = [...state.selectedValues];
77
- options[action.selectedGroup].map(option => newSelectedValues.includes(option) || option.disabled ? null : newSelectedValues.push(option));
92
+ options[action.selectedGroup].map(option => newSelectedValues.find(aValue => aValue === option.value) || option.disabled ? null : newSelectedValues.push(option.value));
78
93
  return {
79
94
  selectedValues: newSelectedValues,
80
95
  allSelected: newSelectedValues.length === numberOfOptions,
@@ -84,21 +99,21 @@ const SelectInputProvider = ({
84
99
  return state;
85
100
  case 'selectOption':
86
101
  if (multiselect) {
87
- if (state.selectedValues.includes(action.clickedOption)) {
102
+ if (state.selectedValues.includes(action.clickedOption.value)) {
88
103
  return {
89
- selectedValues: state.selectedValues.filter(val => val !== action.clickedOption),
104
+ selectedValues: state.selectedValues.filter(val => val !== action.clickedOption.value),
90
105
  allSelected: false,
91
106
  selectedGroups: action.group && state.selectedGroups.includes(action.group) ? state.selectedGroups.filter(selectedGroup => selectedGroup !== action.group) : []
92
107
  };
93
108
  }
94
109
  return {
95
- selectedValues: [...state.selectedValues, action.clickedOption],
110
+ selectedValues: [...state.selectedValues, action.clickedOption.value],
96
111
  allSelected: state.selectedValues.length + 1 === numberOfOptions,
97
- selectedGroups: !Array.isArray(options) && action.group && options[action.group].every(option => [...state.selectedValues, action.clickedOption].includes(option) || option.disabled) ? [...state.selectedGroups, action.group] : state.selectedGroups
112
+ selectedGroups: !Array.isArray(options) && action.group && options[action.group].every(option => [...state.selectedValues, action.clickedOption.value].includes(option.value) || option.disabled) ? [...state.selectedGroups, action.group] : state.selectedGroups
98
113
  };
99
114
  }
100
115
  return {
101
- selectedValues: [action.clickedOption],
116
+ selectedValues: [action.clickedOption.value],
102
117
  allSelected: false,
103
118
  selectedGroups: state.selectedGroups
104
119
  };
@@ -115,9 +130,9 @@ const SelectInputProvider = ({
115
130
  allSelected: state.allSelected,
116
131
  selectedValues: state.selectedValues.filter(selectedValue => {
117
132
  if (!Array.isArray(options)) {
118
- return Object.keys(options).some(group => options[group].some(option => option === selectedValue && !option.disabled));
133
+ return Object.keys(options).some(group => options[group].some(option => option.value === selectedValue && !option.disabled));
119
134
  }
120
- return options.some(option => option === selectedValue && !option.disabled);
135
+ return options.some(option => option.value === selectedValue && !option.disabled);
121
136
  })
122
137
  };
123
138
  default:
@@ -125,9 +140,9 @@ const SelectInputProvider = ({
125
140
  }
126
141
  };
127
142
  const [selectedData, setSelectedData] = useReducer(reducer, {
128
- selectedValues: defaultValue,
143
+ selectedValues: currentValue,
129
144
  allSelected: false,
130
- selectedGroups: []
145
+ selectedGroups
131
146
  });
132
147
  const providerValue = useMemo(() => ({
133
148
  onSearch: setDisplayedOptions,
@@ -142,8 +157,9 @@ const SelectInputProvider = ({
142
157
  numberOfOptions,
143
158
  displayedOptions,
144
159
  selectedData,
145
- setSelectedData
146
- }), [displayedOptions, isDropdownVisible, multiselect, numberOfOptions, options, searchInput, selectAll, selectAllGroup, selectedData]);
160
+ setSelectedData,
161
+ onChange
162
+ }), [displayedOptions, isDropdownVisible, multiselect, numberOfOptions, options, searchInput, selectAll, selectAllGroup, selectedData, onChange]);
147
163
  return jsx(SelectInputContext.Provider, {
148
164
  value: providerValue,
149
165
  children: children
@@ -0,0 +1,11 @@
1
+ const findOptionInOptions = (options, optionValue) => {
2
+ let flatOptions = [];
3
+ if (!Array.isArray(options)) {
4
+ flatOptions = Object.keys(options).map(group => options[group]).flat();
5
+ } else {
6
+ flatOptions = options;
7
+ }
8
+ return flatOptions.find(option => option.value === optionValue);
9
+ };
10
+
11
+ export { findOptionInOptions };
@@ -72,6 +72,7 @@ const SelectInputV2 = ({
72
72
  value: value,
73
73
  selectAllGroup: selectAllGroup,
74
74
  numberOfOptions: numberOfOptions,
75
+ onChange: onChange,
75
76
  children: jsxs(SelectInputContainer, {
76
77
  id: id,
77
78
  onBlur: onBlur,
@@ -85,7 +86,6 @@ const SelectInputV2 = ({
85
86
  searchable: searchable,
86
87
  placeholder: placeholderSearch,
87
88
  footer: footer,
88
- onChange: onChange,
89
89
  refSelect: ref,
90
90
  loadMore: loadMore,
91
91
  optionalInfoPlacement: optionalInfoPlacement,
@@ -100,7 +100,7 @@ const SelectInputV2 = ({
100
100
  as: "label",
101
101
  variant: size === 'large' ? 'bodyStrong' : 'bodySmallStrong',
102
102
  children: label
103
- }) : null, required ? jsx(Icon, {
103
+ }) : null, required && label ? jsx(Icon, {
104
104
  name: "asterisk",
105
105
  sentiment: "danger",
106
106
  size: 8
@@ -113,7 +113,6 @@ const SelectInputV2 = ({
113
113
  placeholder: placeholder,
114
114
  success: success,
115
115
  error: error,
116
- onChange: onChange,
117
116
  autoFocus: autofocus,
118
117
  innerRef: ref
119
118
  })]
@@ -117,7 +117,7 @@ const SelectableCardGroup = ({
117
117
  }) : null]
118
118
  }) : null, jsx(Row, {
119
119
  gap: 2,
120
- templateColumns: `repeat(${columns}, auto)`,
120
+ templateColumns: `repeat(${columns}, minmax(0, 1fr))`,
121
121
  children: children
122
122
  })]
123
123
  })
package/dist/src/index.js CHANGED
@@ -20,6 +20,7 @@ export { Carousel } from './components/Carousel/index.js';
20
20
  export { Checkbox } from './components/Checkbox/index.js';
21
21
  export { CopyButton } from './components/CopyButton/index.js';
22
22
  export { DateInput } from './components/DateInput/index.js';
23
+ export { Dialog } from './components/Dialog/index.js';
23
24
  export { EmptyState } from './components/EmptyState/index.js';
24
25
  export { Expandable } from './components/Expandable/index.js';
25
26
  export { LineChart } from './components/LineChart/index.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultraviolet/ui",
3
- "version": "1.48.1",
3
+ "version": "1.50.0",
4
4
  "description": "Ultraviolet UI",
5
5
  "homepage": "https://github.com/scaleway/ultraviolet#readme",
6
6
  "repository": {
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "engines": {
21
21
  "node": ">=18.x",
22
- "pnpm": ">=8.0.0"
22
+ "pnpm": ">=9.x"
23
23
  },
24
24
  "os": [
25
25
  "darwin",
@@ -56,7 +56,7 @@
56
56
  "@nivo/line": "0.80.0",
57
57
  "@nivo/pie": "0.80.0",
58
58
  "@nivo/scales": "0.80.0",
59
- "@scaleway/random-name": "5.0.1",
59
+ "@scaleway/random-name": "5.0.2",
60
60
  "@scaleway/use-media": "3.0.1",
61
61
  "deepmerge": "4.3.1",
62
62
  "react-datepicker": "4.25.0",