@hitachivantara/uikit-react-core 5.75.0 → 5.76.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,10 +1,11 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
- import { forwardRef, useState, useRef, useEffect } from "react";
2
+ import { useState, useRef, useEffect } from "react";
3
3
  import { useForkRef } from "@mui/material/utils";
4
4
  import { useDefaultProps } from "@hitachivantara/uikit-react-utils";
5
5
  import { useControlled } from "../hooks/useControlled.js";
6
6
  import { useLabels } from "../hooks/useLabels.js";
7
7
  import { useUniqueId } from "../hooks/useUniqueId.js";
8
+ import { fixedForwardRef } from "../types/generic.js";
8
9
  import { setId } from "../utils/setId.js";
9
10
  import { useClasses } from "./Dropdown.styles.js";
10
11
  import { staticClasses } from "./Dropdown.styles.js";
@@ -31,298 +32,292 @@ const DEFAULT_LABELS = {
31
32
  /** The label used in search. */
32
33
  multiSelectionConjunction: "/"
33
34
  };
34
- const HvDropdown = forwardRef(
35
- (props, ref) => {
36
- const {
37
- classes: classesProp,
38
- className,
39
- id,
40
- name,
41
- required = false,
42
- disabled = false,
43
- readOnly = false,
44
- label,
45
- "aria-label": ariaLabel,
46
- "aria-labelledby": ariaLabelledBy,
47
- description,
48
- "aria-describedby": ariaDescribedBy,
49
- placeholder = "Select...",
50
- onChange,
51
- status,
52
- statusMessage,
53
- "aria-errormessage": ariaErrorMessage,
54
- onCancel,
55
- onToggle,
56
- onClickOutside,
57
- onFocus,
58
- onBlur,
59
- values,
60
- multiSelect = false,
61
- showSearch = false,
62
- expanded,
63
- defaultExpanded = false,
64
- notifyChangesOnFirstRender = false,
65
- labels: labelsProp,
66
- hasTooltips = false,
67
- disablePortal = false,
68
- singleSelectionToggle = true,
69
- placement,
70
- variableWidth = false,
71
- popperProps = {},
72
- height,
73
- maxHeight,
74
- virtualized = false,
75
- baseDropdownProps = {},
76
- listProps = {},
77
- ...others
78
- } = useDefaultProps("HvDropdown", props);
79
- const { classes, cx } = useClasses(classesProp);
80
- const labels = useLabels(DEFAULT_LABELS, labelsProp);
81
- const elementId = useUniqueId(id);
82
- const [validationState, setValidationState] = useControlled(
83
- status,
84
- "standBy"
85
- );
86
- const [validationMessage] = useControlled(statusMessage, "Required");
87
- const [isOpen, setIsOpen] = useControlled(
88
- expanded,
89
- Boolean(defaultExpanded)
90
- );
91
- const [selectionLabel, setSelectionLabel] = useState(
35
+ const HvDropdown = fixedForwardRef(function HvDropdown2(props, ref) {
36
+ const {
37
+ classes: classesProp,
38
+ className,
39
+ id,
40
+ name,
41
+ required = false,
42
+ disabled = false,
43
+ readOnly = false,
44
+ label,
45
+ "aria-label": ariaLabel,
46
+ "aria-labelledby": ariaLabelledBy,
47
+ description,
48
+ "aria-describedby": ariaDescribedBy,
49
+ placeholder = "Select...",
50
+ onChange,
51
+ status,
52
+ statusMessage,
53
+ "aria-errormessage": ariaErrorMessage,
54
+ onCancel,
55
+ onToggle,
56
+ onClickOutside,
57
+ onFocus,
58
+ onBlur,
59
+ values,
60
+ multiSelect = false,
61
+ showSearch,
62
+ expanded,
63
+ defaultExpanded,
64
+ notifyChangesOnFirstRender,
65
+ labels: labelsProp,
66
+ hasTooltips,
67
+ disablePortal,
68
+ singleSelectionToggle = true,
69
+ placement,
70
+ variableWidth,
71
+ popperProps = {},
72
+ height,
73
+ maxHeight,
74
+ virtualized,
75
+ baseDropdownProps = {},
76
+ listProps = {},
77
+ ...others
78
+ } = useDefaultProps("HvDropdown", props);
79
+ const { classes, cx } = useClasses(classesProp);
80
+ const labels = useLabels(DEFAULT_LABELS, labelsProp);
81
+ const elementId = useUniqueId(id);
82
+ const [validationState, setValidationState] = useControlled(
83
+ status,
84
+ "standBy"
85
+ );
86
+ const [validationMessage] = useControlled(statusMessage, "Required");
87
+ const [isOpen, setIsOpen] = useControlled(expanded, Boolean(defaultExpanded));
88
+ const [selectionLabel, setSelectionLabel] = useState(
89
+ getSelectionLabel(labels, placeholder, multiSelect, values)
90
+ );
91
+ const [internalValues, setInternalValues] = useState(values);
92
+ const internalValuesRef = useRef(values);
93
+ useEffect(() => {
94
+ setInternalValues(values);
95
+ internalValuesRef.current = values;
96
+ }, [values]);
97
+ useEffect(() => {
98
+ setSelectionLabel(
92
99
  getSelectionLabel(labels, placeholder, multiSelect, values)
93
100
  );
94
- const [internalValues, setInternalValues] = useState(values);
95
- const internalValuesRef = useRef(values);
96
- useEffect(() => {
97
- setInternalValues(values);
98
- internalValuesRef.current = values;
99
- }, [values]);
100
- useEffect(() => {
101
- setSelectionLabel(
102
- getSelectionLabel(labels, placeholder, multiSelect, values)
103
- );
104
- }, [labels, multiSelect, placeholder, values]);
105
- const dropdownHeaderRef = useRef();
106
- const {
107
- ref: refProp,
108
- dropdownHeaderRef: dropdownHeaderRefProp,
109
- ...otherBaseDropdownProps
110
- } = baseDropdownProps;
111
- const headerForkedRef = useForkRef(
112
- dropdownHeaderRefProp,
113
- dropdownHeaderRef
114
- );
115
- const dropdownForkedRef = useForkRef(ref, refProp);
116
- const handleToggle = (event, open) => {
117
- onToggle?.(event, open);
118
- setIsOpen(open);
119
- if (!open) {
120
- setValidationState(() => {
121
- if (required) {
122
- const hasSelection = getSelected(internalValuesRef.current).length > 0;
123
- if (!hasSelection) {
124
- return "invalid";
125
- }
126
- }
127
- return "valid";
128
- });
129
- }
130
- };
131
- const handleSelection = (listValues, commitChanges, toggle, notifyChanges = true) => {
132
- const selected = getSelected(listValues);
133
- if (commitChanges) {
134
- setInternalValues(listValues);
135
- internalValuesRef.current = listValues;
136
- setSelectionLabel(
137
- getSelectionLabel(labels, placeholder, multiSelect, listValues)
138
- );
139
- setValidationState(() => {
140
- if (required && selected.length === 0) {
101
+ }, [labels, multiSelect, placeholder, values]);
102
+ const dropdownHeaderRef = useRef();
103
+ const {
104
+ ref: refProp,
105
+ dropdownHeaderRef: dropdownHeaderRefProp,
106
+ ...otherBaseDropdownProps
107
+ } = baseDropdownProps;
108
+ const headerForkedRef = useForkRef(dropdownHeaderRefProp, dropdownHeaderRef);
109
+ const dropdownForkedRef = useForkRef(ref, refProp);
110
+ const handleToggle = (event, open) => {
111
+ onToggle?.(event, open);
112
+ setIsOpen(open);
113
+ if (!open) {
114
+ setValidationState(() => {
115
+ if (required) {
116
+ const hasSelection = getSelected(internalValuesRef.current).length > 0;
117
+ if (!hasSelection) {
141
118
  return "invalid";
142
119
  }
143
- return "valid";
144
- });
145
- }
146
- if (notifyChanges) onChange?.(multiSelect ? selected : selected[0]);
147
- if (toggle) {
148
- handleToggle(void 0, false);
149
- dropdownHeaderRef.current?.focus({ preventScroll: true });
150
- }
151
- };
152
- const handleCancel = (evt) => {
153
- onCancel?.(evt);
154
- handleToggle(evt, false);
155
- dropdownHeaderRef.current?.focus({ preventScroll: true });
156
- };
157
- const handleClickOutside = (evt) => {
158
- onClickOutside?.(evt);
159
- onCancel?.(evt);
160
- };
161
- const setFocusToContent = (containerRef) => {
162
- const inputs = containerRef?.getElementsByTagName("input");
163
- if (inputs && inputs.length > 0) {
164
- inputs[0].focus();
165
- return;
166
- }
167
- const listItems = containerRef != null ? [...containerRef.getElementsByTagName("li")] : [];
168
- listItems.every((listItem) => {
169
- if (listItem.tabIndex >= 0) {
170
- listItem.focus();
171
- return false;
172
120
  }
173
- return true;
121
+ return "valid";
174
122
  });
175
- };
176
- const buildHeaderLabel = () => {
177
- const hasSelection = getSelected(internalValues).length > 0;
178
- return labels?.select || !multiSelect ? /* @__PURE__ */ jsx(
179
- HvTypography,
180
- {
181
- component: "div",
182
- variant: "body",
183
- className: cx(classes.placeholder, {
184
- [classes.selectionDisabled]: disabled,
185
- [classes.placeholderClosed]: !(isOpen || hasSelection)
186
- }),
187
- children: selectionLabel.selected
188
- }
189
- ) : /* @__PURE__ */ jsxs(
190
- HvTypography,
191
- {
192
- component: "div",
193
- className: cx(classes.placeholder, {
194
- [classes.selectionDisabled]: disabled
195
- }),
196
- variant: "body",
197
- children: [
198
- /* @__PURE__ */ jsx("b", { children: selectionLabel.selected }),
199
- ` ${labels?.multiSelectionConjunction} ${selectionLabel.total}`
200
- ]
201
- }
123
+ }
124
+ };
125
+ const handleSelection = (listValues, commitChanges, toggle, notifyChanges = true) => {
126
+ const selected = getSelected(listValues);
127
+ if (commitChanges) {
128
+ setInternalValues(listValues);
129
+ internalValuesRef.current = listValues;
130
+ setSelectionLabel(
131
+ getSelectionLabel(labels, placeholder, multiSelect, listValues)
202
132
  );
203
- };
204
- const hasLabel = label != null;
205
- const hasDescription = description != null;
206
- const canShowError = ariaErrorMessage == null && (status !== void 0 && statusMessage !== void 0 || status === void 0 && required);
207
- const isStateInvalid = isInvalid(validationState);
208
- let errorMessageId;
209
- if (isStateInvalid) {
210
- errorMessageId = canShowError ? setId(elementId, "error") : ariaErrorMessage;
133
+ setValidationState(() => {
134
+ if (required && selected.length === 0) {
135
+ return "invalid";
136
+ }
137
+ return "valid";
138
+ });
139
+ }
140
+ if (notifyChanges) {
141
+ onChange?.(multiSelect ? selected : selected[0]);
142
+ }
143
+ if (toggle) {
144
+ handleToggle(void 0, false);
145
+ dropdownHeaderRef.current?.focus({ preventScroll: true });
211
146
  }
212
- return /* @__PURE__ */ jsxs(
213
- HvFormElement,
147
+ };
148
+ const handleCancel = (evt) => {
149
+ onCancel?.(evt);
150
+ handleToggle(evt, false);
151
+ dropdownHeaderRef.current?.focus({ preventScroll: true });
152
+ };
153
+ const handleClickOutside = (evt) => {
154
+ onClickOutside?.(evt);
155
+ onCancel?.(evt);
156
+ };
157
+ const setFocusToContent = (containerRef) => {
158
+ const inputs = containerRef?.getElementsByTagName("input");
159
+ if (inputs && inputs.length > 0) {
160
+ inputs[0].focus();
161
+ return;
162
+ }
163
+ const listItems = containerRef != null ? [...containerRef.getElementsByTagName("li")] : [];
164
+ listItems.every((listItem) => {
165
+ if (listItem.tabIndex >= 0) {
166
+ listItem.focus();
167
+ return false;
168
+ }
169
+ return true;
170
+ });
171
+ };
172
+ const buildHeaderLabel = () => {
173
+ const hasSelection = getSelected(internalValues).length > 0;
174
+ return labels?.select || !multiSelect ? /* @__PURE__ */ jsx(
175
+ HvTypography,
214
176
  {
215
- id,
216
- name,
217
- status: validationState,
218
- disabled,
219
- readOnly,
220
- required,
221
- className: cx(
222
- classes.root,
223
- {
224
- [classes.disabled]: disabled
225
- },
226
- className
227
- ),
228
- ...others,
177
+ component: "div",
178
+ variant: "body",
179
+ className: cx(classes.placeholder, {
180
+ [classes.selectionDisabled]: disabled,
181
+ [classes.placeholderClosed]: !(isOpen || hasSelection)
182
+ }),
183
+ children: selectionLabel.selected
184
+ }
185
+ ) : /* @__PURE__ */ jsxs(
186
+ HvTypography,
187
+ {
188
+ component: "div",
189
+ className: cx(classes.placeholder, {
190
+ [classes.selectionDisabled]: disabled
191
+ }),
192
+ variant: "body",
229
193
  children: [
230
- (hasLabel || hasDescription) && /* @__PURE__ */ jsxs("div", { className: classes.labelContainer, children: [
231
- hasLabel && /* @__PURE__ */ jsx(
232
- HvLabel,
233
- {
234
- id: setId(elementId, "label"),
235
- label,
236
- className: classes.label
237
- }
238
- ),
239
- hasDescription && /* @__PURE__ */ jsx(
240
- HvInfoMessage,
241
- {
242
- id: setId(elementId, "description"),
243
- className: classes.description,
244
- children: description
245
- }
246
- )
247
- ] }),
248
- /* @__PURE__ */ jsx(
249
- HvBaseDropdown,
194
+ /* @__PURE__ */ jsx("b", { children: selectionLabel.selected }),
195
+ ` ${labels?.multiSelectionConjunction} ${selectionLabel.total}`
196
+ ]
197
+ }
198
+ );
199
+ };
200
+ const hasLabel = label != null;
201
+ const hasDescription = description != null;
202
+ const canShowError = ariaErrorMessage == null && (status !== void 0 && statusMessage !== void 0 || status === void 0 && required);
203
+ const isStateInvalid = isInvalid(validationState);
204
+ let errorMessageId;
205
+ if (isStateInvalid) {
206
+ errorMessageId = canShowError ? setId(elementId, "error") : ariaErrorMessage;
207
+ }
208
+ return /* @__PURE__ */ jsxs(
209
+ HvFormElement,
210
+ {
211
+ id,
212
+ name,
213
+ status: validationState,
214
+ disabled,
215
+ readOnly,
216
+ required,
217
+ className: cx(
218
+ classes.root,
219
+ {
220
+ [classes.disabled]: disabled
221
+ },
222
+ className
223
+ ),
224
+ ...others,
225
+ children: [
226
+ (hasLabel || hasDescription) && /* @__PURE__ */ jsxs("div", { className: classes.labelContainer, children: [
227
+ hasLabel && /* @__PURE__ */ jsx(
228
+ HvLabel,
250
229
  {
251
- ref: dropdownForkedRef,
252
- id: setId(id, "dropdown"),
253
- classes: {
254
- root: cx(classes.dropdown, {
255
- [classes.readOnly]: readOnly
256
- }),
257
- arrow: classes.arrow,
258
- header: cx(classes.dropdownHeader, {
259
- [classes.dropdownHeaderInvalid]: isStateInvalid
260
- }),
261
- headerOpen: classes.dropdownHeaderOpen
262
- },
263
- expanded: isOpen,
264
- disabled,
265
- readOnly,
266
- required,
267
- disablePortal,
268
- placement,
269
- popperProps,
270
- placeholder: buildHeaderLabel(),
271
- onToggle: handleToggle,
272
- onClickOutside: handleClickOutside,
273
- onContainerCreation: setFocusToContent,
274
- role: "combobox",
275
- variableWidth,
276
- "aria-label": ariaLabel,
277
- "aria-labelledby": [label && setId(elementId, "label"), ariaLabelledBy].join(" ").trim() || void 0,
278
- "aria-invalid": isStateInvalid ? true : void 0,
279
- "aria-errormessage": errorMessageId,
280
- "aria-describedby": [description && setId(elementId, "description"), ariaDescribedBy].join(" ").trim() || void 0,
281
- onFocus,
282
- onBlur,
283
- dropdownHeaderRef: headerForkedRef,
284
- ...otherBaseDropdownProps,
285
- children: /* @__PURE__ */ jsx(
286
- HvDropdownList,
287
- {
288
- id: setId(elementId, "values"),
289
- classes: {
290
- rootList: classes.rootList,
291
- dropdownListContainer: classes.dropdownListContainer
292
- },
293
- values: internalValues,
294
- multiSelect,
295
- showSearch,
296
- onChange: handleSelection,
297
- onCancel: handleCancel,
298
- labels,
299
- notifyChangesOnFirstRender,
300
- hasTooltips,
301
- singleSelectionToggle,
302
- "aria-label": ariaLabel,
303
- "aria-labelledby": hasLabel ? setId(elementId, "label") : void 0,
304
- height,
305
- maxHeight,
306
- virtualized,
307
- ...listProps
308
- }
309
- )
230
+ id: setId(elementId, "label"),
231
+ label,
232
+ className: classes.label
310
233
  }
311
234
  ),
312
- canShowError && /* @__PURE__ */ jsx(
313
- HvWarningText,
235
+ hasDescription && /* @__PURE__ */ jsx(
236
+ HvInfoMessage,
314
237
  {
315
- id: setId(elementId, "error"),
316
- disableBorder: true,
317
- className: classes.error,
318
- children: validationMessage
238
+ id: setId(elementId, "description"),
239
+ className: classes.description,
240
+ children: description
319
241
  }
320
242
  )
321
- ]
322
- }
323
- );
324
- }
325
- );
243
+ ] }),
244
+ /* @__PURE__ */ jsx(
245
+ HvBaseDropdown,
246
+ {
247
+ ref: dropdownForkedRef,
248
+ id: setId(id, "dropdown"),
249
+ classes: {
250
+ root: cx(classes.dropdown, {
251
+ [classes.readOnly]: readOnly
252
+ }),
253
+ arrow: classes.arrow,
254
+ header: cx(classes.dropdownHeader, {
255
+ [classes.dropdownHeaderInvalid]: isStateInvalid
256
+ }),
257
+ headerOpen: classes.dropdownHeaderOpen
258
+ },
259
+ expanded: isOpen,
260
+ disabled,
261
+ readOnly,
262
+ required,
263
+ disablePortal,
264
+ placement,
265
+ popperProps,
266
+ placeholder: buildHeaderLabel(),
267
+ onToggle: handleToggle,
268
+ onClickOutside: handleClickOutside,
269
+ onContainerCreation: setFocusToContent,
270
+ role: "combobox",
271
+ variableWidth,
272
+ "aria-label": ariaLabel,
273
+ "aria-labelledby": [label && setId(elementId, "label"), ariaLabelledBy].join(" ").trim() || void 0,
274
+ "aria-invalid": isStateInvalid ? true : void 0,
275
+ "aria-errormessage": errorMessageId,
276
+ "aria-describedby": [description && setId(elementId, "description"), ariaDescribedBy].join(" ").trim() || void 0,
277
+ onFocus,
278
+ onBlur,
279
+ dropdownHeaderRef: headerForkedRef,
280
+ ...otherBaseDropdownProps,
281
+ children: /* @__PURE__ */ jsx(
282
+ HvDropdownList,
283
+ {
284
+ id: setId(elementId, "values"),
285
+ classes: {
286
+ rootList: classes.rootList,
287
+ dropdownListContainer: classes.dropdownListContainer
288
+ },
289
+ values: internalValues,
290
+ multiSelect,
291
+ showSearch,
292
+ onChange: handleSelection,
293
+ onCancel: handleCancel,
294
+ labels,
295
+ notifyChangesOnFirstRender,
296
+ hasTooltips,
297
+ singleSelectionToggle,
298
+ "aria-label": ariaLabel,
299
+ "aria-labelledby": hasLabel ? setId(elementId, "label") : void 0,
300
+ height,
301
+ maxHeight,
302
+ virtualized,
303
+ ...listProps
304
+ }
305
+ )
306
+ }
307
+ ),
308
+ canShowError && /* @__PURE__ */ jsx(
309
+ HvWarningText,
310
+ {
311
+ id: setId(elementId, "error"),
312
+ disableBorder: true,
313
+ className: classes.error,
314
+ children: validationMessage
315
+ }
316
+ )
317
+ ]
318
+ }
319
+ );
320
+ });
326
321
  export {
327
322
  HvDropdown,
328
323
  staticClasses as dropdownClasses