@carbon/react 1.106.0 → 1.107.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.
Files changed (161) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +1017 -982
  2. package/es/components/Accordion/AccordionItem.d.ts +2 -2
  3. package/es/components/Button/Button.d.ts +2 -2
  4. package/es/components/Button/Button.js +1 -1
  5. package/es/components/Checkbox/Checkbox.js +2 -1
  6. package/es/components/CheckboxGroup/CheckboxGroup.js +2 -1
  7. package/es/components/ComboBox/ComboBox.d.ts +1 -1
  8. package/es/components/ComboBox/ComboBox.js +1 -1
  9. package/es/components/ComboButton/index.js +2 -2
  10. package/es/components/ContentSwitcher/ContentSwitcher.d.ts +1 -1
  11. package/es/components/ContentSwitcher/ContentSwitcher.js +24 -15
  12. package/es/components/DataTable/DataTable.d.ts +3 -3
  13. package/es/components/DataTable/TableActionList.d.ts +1 -1
  14. package/es/components/DataTable/TableHead.d.ts +1 -1
  15. package/es/components/DataTable/TableSlugRow.d.ts +2 -2
  16. package/es/components/DataTable/TableSlugRow.js +8 -11
  17. package/es/components/DataTable/TableToolbarContent.d.ts +1 -1
  18. package/es/components/DataTable/TableToolbarSearch.d.ts +5 -1
  19. package/es/components/DatePicker/DatePicker.js +15 -13
  20. package/es/components/DatePicker/plugins/fixEventsPlugin.js +2 -3
  21. package/es/components/Dropdown/Dropdown.d.ts +1 -1
  22. package/es/components/FluidTimePicker/FluidTimePicker.d.ts +1 -1
  23. package/es/components/FluidTimePicker/FluidTimePicker.js +6 -4
  24. package/es/components/FluidTimePickerSelect/FluidTimePickerSelect.d.ts +4 -0
  25. package/es/components/FluidTimePickerSelect/FluidTimePickerSelect.js +2 -1
  26. package/es/components/FluidTimePickerSelect/index.js +18 -0
  27. package/es/components/Grid/CSSGrid.js +11 -6
  28. package/es/components/Grid/Column.d.ts +2 -2
  29. package/es/components/Grid/ColumnHang.d.ts +3 -3
  30. package/es/components/Grid/ColumnHang.js +1 -1
  31. package/es/components/Grid/FlexGrid.js +5 -3
  32. package/es/components/Grid/Grid.js +2 -1
  33. package/es/components/Grid/GridTypes.d.ts +5 -0
  34. package/es/components/Grid/Row.d.ts +3 -3
  35. package/es/components/Grid/Row.js +1 -1
  36. package/es/components/Menu/Menu.js +1 -1
  37. package/es/components/Menu/MenuItem.js +4 -0
  38. package/es/components/Modal/Modal.d.ts +1 -1
  39. package/es/components/Modal/Modal.js +20 -6
  40. package/es/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  41. package/es/components/MultiSelect/FilterableMultiSelect.js +3 -2
  42. package/es/components/MultiSelect/MultiSelect.d.ts +1 -1
  43. package/es/components/NumberInput/NumberInput.js +4 -2
  44. package/es/components/OverflowMenu/OverflowMenu.js +11 -12
  45. package/es/components/Pagination/Pagination.d.ts +1 -1
  46. package/es/components/Pagination/Pagination.js +2 -0
  47. package/es/components/Popover/index.js +14 -1
  48. package/es/components/RadioButtonGroup/RadioButtonGroup.d.ts +1 -1
  49. package/es/components/RadioButtonGroup/RadioButtonGroup.js +8 -6
  50. package/es/components/Search/Search.Skeleton.d.ts +12 -3
  51. package/es/components/Search/Search.Skeleton.js +16 -8
  52. package/es/components/Search/Search.d.ts +1 -1
  53. package/es/components/Search/Search.js +4 -4
  54. package/es/components/Select/Select.d.ts +1 -1
  55. package/es/components/Select/Select.js +7 -6
  56. package/es/components/Slider/Slider.js +58 -76
  57. package/es/components/Tabs/Tabs.js +2 -2
  58. package/es/components/TextArea/TextArea.js +5 -2
  59. package/es/components/TextInput/ControlledPasswordInput.js +2 -1
  60. package/es/components/TextInput/PasswordInput.d.ts +2 -2
  61. package/es/components/TextInput/PasswordInput.js +33 -21
  62. package/es/components/TextInput/TextInput.Skeleton.d.ts +10 -2
  63. package/es/components/TextInput/TextInput.Skeleton.js +10 -4
  64. package/es/components/TextInput/TextInput.d.ts +1 -1
  65. package/es/components/TextInput/TextInput.js +39 -30
  66. package/es/components/TextInput/util.d.ts +1 -0
  67. package/es/components/TextInput/util.js +1 -1
  68. package/es/components/Theme/index.d.ts +2 -2
  69. package/es/components/Theme/index.js +3 -3
  70. package/es/components/TimePicker/TimePicker.js +5 -2
  71. package/es/components/TreeView/TreeNode.js +2 -2
  72. package/es/components/UIShell/HeaderGlobalBar.d.ts +1 -1
  73. package/es/components/UIShell/HeaderMenu.d.ts +1 -1
  74. package/es/components/UIShell/HeaderMenu.js +5 -3
  75. package/es/index.js +2 -2
  76. package/es/internal/FloatingMenu.d.ts +5 -1
  77. package/es/internal/hasHelperText.d.ts +8 -0
  78. package/es/internal/hasHelperText.js +11 -0
  79. package/es/tools/wrapComponent.d.ts +3 -3
  80. package/es/tools/wrapComponent.js +1 -1
  81. package/lib/components/Accordion/AccordionItem.d.ts +2 -2
  82. package/lib/components/Button/Button.d.ts +2 -2
  83. package/lib/components/Button/Button.js +1 -1
  84. package/lib/components/Checkbox/Checkbox.js +2 -1
  85. package/lib/components/CheckboxGroup/CheckboxGroup.js +2 -1
  86. package/lib/components/ComboBox/ComboBox.d.ts +1 -1
  87. package/lib/components/ComboBox/ComboBox.js +1 -1
  88. package/lib/components/ComboButton/index.js +2 -2
  89. package/lib/components/ContentSwitcher/ContentSwitcher.d.ts +1 -1
  90. package/lib/components/ContentSwitcher/ContentSwitcher.js +22 -13
  91. package/lib/components/DataTable/DataTable.d.ts +3 -3
  92. package/lib/components/DataTable/TableActionList.d.ts +1 -1
  93. package/lib/components/DataTable/TableHead.d.ts +1 -1
  94. package/lib/components/DataTable/TableSlugRow.d.ts +2 -2
  95. package/lib/components/DataTable/TableSlugRow.js +7 -10
  96. package/lib/components/DataTable/TableToolbarContent.d.ts +1 -1
  97. package/lib/components/DataTable/TableToolbarSearch.d.ts +5 -1
  98. package/lib/components/DatePicker/DatePicker.js +15 -13
  99. package/lib/components/DatePicker/plugins/fixEventsPlugin.js +1 -2
  100. package/lib/components/Dropdown/Dropdown.d.ts +1 -1
  101. package/lib/components/FluidTimePicker/FluidTimePicker.d.ts +1 -1
  102. package/lib/components/FluidTimePicker/FluidTimePicker.js +5 -3
  103. package/lib/components/FluidTimePickerSelect/FluidTimePickerSelect.d.ts +4 -0
  104. package/lib/components/FluidTimePickerSelect/FluidTimePickerSelect.js +2 -1
  105. package/lib/components/FluidTimePickerSelect/index.js +17 -0
  106. package/lib/components/Grid/CSSGrid.js +11 -6
  107. package/lib/components/Grid/Column.d.ts +2 -2
  108. package/lib/components/Grid/ColumnHang.d.ts +3 -3
  109. package/lib/components/Grid/ColumnHang.js +1 -1
  110. package/lib/components/Grid/FlexGrid.js +5 -3
  111. package/lib/components/Grid/Grid.js +2 -1
  112. package/lib/components/Grid/GridTypes.d.ts +5 -0
  113. package/lib/components/Grid/Row.d.ts +3 -3
  114. package/lib/components/Grid/Row.js +1 -1
  115. package/lib/components/Menu/Menu.js +1 -1
  116. package/lib/components/Menu/MenuItem.js +4 -0
  117. package/lib/components/Modal/Modal.d.ts +1 -1
  118. package/lib/components/Modal/Modal.js +19 -5
  119. package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  120. package/lib/components/MultiSelect/FilterableMultiSelect.js +3 -2
  121. package/lib/components/MultiSelect/MultiSelect.d.ts +1 -1
  122. package/lib/components/NumberInput/NumberInput.js +4 -2
  123. package/lib/components/OverflowMenu/OverflowMenu.js +10 -11
  124. package/lib/components/Pagination/Pagination.d.ts +1 -1
  125. package/lib/components/Pagination/Pagination.js +2 -0
  126. package/lib/components/Popover/index.js +14 -1
  127. package/lib/components/RadioButtonGroup/RadioButtonGroup.d.ts +1 -1
  128. package/lib/components/RadioButtonGroup/RadioButtonGroup.js +7 -5
  129. package/lib/components/Search/Search.Skeleton.d.ts +12 -3
  130. package/lib/components/Search/Search.Skeleton.js +15 -7
  131. package/lib/components/Search/Search.d.ts +1 -1
  132. package/lib/components/Search/Search.js +4 -4
  133. package/lib/components/Select/Select.d.ts +1 -1
  134. package/lib/components/Select/Select.js +7 -6
  135. package/lib/components/Slider/Slider.js +58 -76
  136. package/lib/components/Tabs/Tabs.js +2 -2
  137. package/lib/components/TextArea/TextArea.js +5 -2
  138. package/lib/components/TextInput/ControlledPasswordInput.js +2 -1
  139. package/lib/components/TextInput/PasswordInput.d.ts +2 -2
  140. package/lib/components/TextInput/PasswordInput.js +33 -21
  141. package/lib/components/TextInput/TextInput.Skeleton.d.ts +10 -2
  142. package/lib/components/TextInput/TextInput.Skeleton.js +10 -4
  143. package/lib/components/TextInput/TextInput.d.ts +1 -1
  144. package/lib/components/TextInput/TextInput.js +39 -30
  145. package/lib/components/TextInput/util.d.ts +1 -0
  146. package/lib/components/TextInput/util.js +1 -1
  147. package/lib/components/Theme/index.d.ts +2 -2
  148. package/lib/components/Theme/index.js +2 -2
  149. package/lib/components/TimePicker/TimePicker.js +5 -2
  150. package/lib/components/TreeView/TreeNode.js +1 -1
  151. package/lib/components/UIShell/HeaderGlobalBar.d.ts +1 -1
  152. package/lib/components/UIShell/HeaderMenu.d.ts +1 -1
  153. package/lib/components/UIShell/HeaderMenu.js +5 -3
  154. package/lib/index.js +2 -2
  155. package/lib/internal/FloatingMenu.d.ts +5 -1
  156. package/lib/internal/hasHelperText.d.ts +8 -0
  157. package/lib/internal/hasHelperText.js +11 -0
  158. package/lib/tools/wrapComponent.d.ts +3 -3
  159. package/lib/tools/wrapComponent.js +1 -1
  160. package/package.json +11 -11
  161. package/telemetry.yml +1 -0
@@ -68,18 +68,13 @@ const DRAG_STOP_EVENT_TYPES = new Set([
68
68
  "touchcancel"
69
69
  ]);
70
70
  const Slider = (props) => {
71
- const controlledValue = props.value;
72
- const controlledValueUpper = props.unstable_valueUpper;
73
- const controlledMax = props.max;
74
- const controlledMin = props.min;
75
- const onChange = props.onChange;
76
- const onRelease = props.onRelease;
71
+ const { ariaLabelInput, unstable_ariaLabelInputUpper: ariaLabelInputUpper, className, hideTextInput = false, id: idProp, min, minLabel, max, maxLabel, formatLabel = defaultFormatLabel, labelText, hideLabel, step = 1, inputType = "number", invalidText, required, disabled = false, name, unstable_nameUpper: nameUpper, light, readOnly = false, value: controlledValue, unstable_valueUpper: controlledValueUpper, invalid, onBlur, onChange, onInputKeyUp, onRelease, stepMultiplier = 4, warn = false, warnText, translateWithId: t = defaultTranslateWithId, ...other } = props;
77
72
  const [state, setState] = useReducer((prev, args) => ({
78
73
  ...prev,
79
74
  ...args
80
75
  }), {
81
- value: props.value,
82
- valueUpper: props.unstable_valueUpper,
76
+ value: controlledValue,
77
+ valueUpper: controlledValueUpper,
83
78
  left: 0,
84
79
  leftUpper: 0,
85
80
  needsOnRelease: false,
@@ -94,15 +89,10 @@ const Slider = (props) => {
94
89
  useEffect(() => {
95
90
  stateRef.current = state;
96
91
  }, [state]);
97
- const propsRef = useRef(props);
98
- useEffect(() => {
99
- propsRef.current = props;
100
- }, [props]);
101
92
  const thumbRef = useRef(null);
102
93
  const thumbRefUpper = useRef(null);
103
94
  const filledTrackRef = useRef(null);
104
95
  const elementRef = useRef(null);
105
- const trackRef = useRef(null);
106
96
  const generatedId = useId();
107
97
  const prefix = usePrefix();
108
98
  const twoHandles = hasUpperValue(state.valueUpper);
@@ -192,23 +182,23 @@ const Slider = (props) => {
192
182
  const next = [
193
183
  controlledValue,
194
184
  controlledValueUpper,
195
- controlledMax,
196
- controlledMin
185
+ max,
186
+ min
197
187
  ];
198
188
  if (!prev || prev[0] !== next[0] || prev[1] !== next[1] || prev[2] !== next[2] || prev[3] !== next[3]) {
199
189
  setState({
200
190
  value: controlledValue,
201
191
  left: calcRawLeftPercent({
202
- max: controlledMax,
203
- min: controlledMin,
192
+ max,
193
+ min,
204
194
  value: controlledValue
205
195
  }) * 100
206
196
  });
207
197
  if (typeof controlledValueUpper !== "undefined") setState({
208
198
  valueUpper: controlledValueUpper,
209
199
  leftUpper: calcRawLeftPercent({
210
- max: controlledMax,
211
- min: controlledMin,
200
+ max,
201
+ min,
212
202
  value: controlledValueUpper
213
203
  }) * 100
214
204
  });
@@ -219,10 +209,10 @@ const Slider = (props) => {
219
209
  prevSyncKeysRef.current = next;
220
210
  }
221
211
  }, [
222
- controlledMax,
223
- controlledMin,
224
212
  controlledValue,
225
- controlledValueUpper
213
+ controlledValueUpper,
214
+ max,
215
+ min
226
216
  ]);
227
217
  /**
228
218
  * Rounds a given value to the nearest step defined by the slider's `step`
@@ -232,7 +222,7 @@ const Slider = (props) => {
232
222
  * @returns The value rounded to the precision determined by the step.
233
223
  */
234
224
  const nearestStepValue = (value = 0) => {
235
- const decimals = (props.step?.toString().split(".")[1] ?? "").length;
225
+ const decimals = (step.toString().split(".")[1] ?? "").length;
236
226
  return Number(value.toFixed(decimals));
237
227
  };
238
228
  const handleDrag = (event) => {
@@ -244,7 +234,7 @@ const Slider = (props) => {
244
234
  * event.
245
235
  */
246
236
  const onDragStart = (evt) => {
247
- if (props.disabled || props.readOnly) return;
237
+ if (disabled || readOnly) return;
248
238
  evt.preventDefault();
249
239
  DRAG_STOP_EVENT_TYPES.forEach((element) => {
250
240
  elementRef.current?.ownerDocument.addEventListener(element, onDragStop);
@@ -273,18 +263,18 @@ const Slider = (props) => {
273
263
  * indicating that the `onRelease` callback should be called.
274
264
  */
275
265
  const onDragStop = () => {
276
- if (props.disabled || props.readOnly) return;
266
+ if (disabled || readOnly) return;
277
267
  DRAG_STOP_EVENT_TYPES.forEach((element) => {
278
268
  elementRef.current?.ownerDocument.removeEventListener(element, onDragStop);
279
269
  });
280
270
  DRAG_EVENT_TYPES.forEach((element) => {
281
271
  elementRef.current?.ownerDocument.removeEventListener(element, handleDrag);
282
272
  });
283
- setState({
284
- needsOnRelease: true,
285
- isValid: true,
286
- isValidUpper: true
287
- });
273
+ setState({ needsOnRelease: true });
274
+ };
275
+ const getValidityUpdateForHandle = (handle, validity) => {
276
+ if (typeof invalid !== "undefined") return {};
277
+ return handle === "upper" ? { isValidUpper: validity } : { isValid: validity };
288
278
  };
289
279
  /**
290
280
  * Handles a "drag" event by recalculating the value/thumb and setting state
@@ -297,7 +287,7 @@ const Slider = (props) => {
297
287
  const _onDragRef = useRef(null);
298
288
  _onDragRef.current = (evt, activeHandle) => {
299
289
  activeHandle = activeHandle ?? stateRef.current.activeHandle;
300
- if (propsRef.current.disabled || propsRef.current.readOnly) return;
290
+ if (disabled || readOnly) return;
301
291
  const { value, left } = calcValue({
302
292
  clientX: getClientXFromEvent(evt),
303
293
  value: stateRef.current.value
@@ -309,7 +299,7 @@ const Slider = (props) => {
309
299
  else setState({
310
300
  value: nearestStepValue(value),
311
301
  left,
312
- isValid: true
302
+ ...getValidityUpdateForHandle("lower", true)
313
303
  });
314
304
  setState({
315
305
  correctedValue: null,
@@ -331,25 +321,24 @@ const Slider = (props) => {
331
321
  * state accordingly.
332
322
  */
333
323
  const onKeyDown = (evt) => {
334
- if (props.disabled || props.readOnly) return;
335
- const { step = 1, stepMultiplier = 4 } = props;
324
+ if (disabled || readOnly) return;
336
325
  let delta = 0;
337
326
  if (matches(evt, [ArrowDown, ArrowLeft])) delta = -step;
338
327
  else if (matches(evt, [ArrowUp$1, ArrowRight$1])) delta = step;
339
328
  else return;
340
329
  if (evt.shiftKey) delta *= stepMultiplier;
341
330
  if (twoHandles && state.activeHandle) {
342
- const { value, left } = calcValue({ value: calcValueForDelta((state.activeHandle === "lower" ? state.value : state.valueUpper) ?? props.min, delta, props.step) });
331
+ const { value, left } = calcValue({ value: calcValueForDelta((state.activeHandle === "lower" ? state.value : state.valueUpper) ?? min, delta, step) });
343
332
  setValueLeftForHandle(state.activeHandle, {
344
333
  value: nearestStepValue(value),
345
334
  left
346
335
  });
347
336
  } else {
348
- const { value, left } = calcValue({ value: calcValueForDelta(state.value, delta, props.step) });
337
+ const { value, left } = calcValue({ value: calcValueForDelta(state.value, delta, step) });
349
338
  setState({
350
339
  value: nearestStepValue(value),
351
340
  left,
352
- isValid: true
341
+ ...getValidityUpdateForHandle("lower", true)
353
342
  });
354
343
  }
355
344
  setState({
@@ -363,22 +352,22 @@ const Slider = (props) => {
363
352
  * setting state accordingly.
364
353
  */
365
354
  const onChangeInput = (evt) => {
366
- if (props.disabled || props.readOnly) return;
355
+ if (disabled || readOnly) return;
367
356
  const activeHandle = evt.target.dataset.handlePosition ?? "lower";
368
357
  const targetValue = Number.parseFloat(evt.target.value);
369
358
  if (twoHandles) if (isNaN(targetValue)) setValueForHandle(activeHandle, evt.target.value);
370
359
  else if (isValidValueForPosition({
371
360
  handle: activeHandle,
372
361
  value: targetValue,
373
- min: props.min,
374
- max: props.max
362
+ min,
363
+ max
375
364
  })) processNewInputValue(evt.target);
376
365
  else setValueForHandle(activeHandle, targetValue);
377
366
  else if (isNaN(targetValue)) setState({ value: evt.target.value });
378
367
  else if (isValidValue({
379
368
  value: targetValue,
380
- min: props.min,
381
- max: props.max
369
+ min,
370
+ max
382
371
  })) processNewInputValue(evt.target);
383
372
  else setState({ value: targetValue });
384
373
  };
@@ -389,13 +378,13 @@ const Slider = (props) => {
389
378
  const onBlurInput = (evt) => {
390
379
  const { value: targetValue } = evt.target;
391
380
  processNewInputValue(evt.target);
392
- props.onBlur?.({
381
+ onBlur?.({
393
382
  value: targetValue,
394
383
  handlePosition: evt.target.dataset.handlePosition
395
384
  });
396
385
  };
397
386
  const onInputKeyDown = (evt) => {
398
- if (props.disabled || props.readOnly || !(evt.target instanceof HTMLInputElement)) return;
387
+ if (disabled || readOnly || !(evt.target instanceof HTMLInputElement)) return;
399
388
  if (matches(evt, [Enter])) processNewInputValue(evt.target);
400
389
  };
401
390
  const processNewInputValue = (input) => {
@@ -406,19 +395,17 @@ const Slider = (props) => {
406
395
  const targetValue = Number.parseFloat(input.value);
407
396
  const validity = !isNaN(targetValue);
408
397
  const handlePosition = input.dataset.handlePosition;
409
- if (handlePosition === "lower") setState({ isValid: validity });
410
- else if (handlePosition === "upper") setState({ isValidUpper: validity });
411
- setState({ isValid: validity });
398
+ setState(getValidityUpdateForHandle(handlePosition ?? "lower", validity));
412
399
  if (validity) {
413
400
  const adjustedValue = handlePosition ? getAdjustedValueForPosition({
414
401
  handle: handlePosition,
415
402
  value: targetValue,
416
- min: props.min,
417
- max: props.max
403
+ min,
404
+ max
418
405
  }) : getAdjustedValue({
419
406
  value: targetValue,
420
- min: props.min,
421
- max: props.max
407
+ min,
408
+ max
422
409
  });
423
410
  if (adjustedValue !== targetValue) setState({
424
411
  correctedValue: targetValue.toString(),
@@ -445,12 +432,12 @@ const Slider = (props) => {
445
432
  const calcLeftPercent = ({ clientX, value }) => {
446
433
  const boundingRect = elementRef.current?.getBoundingClientRect?.();
447
434
  let width = boundingRect ? boundingRect.right - boundingRect.left : 0;
448
- const nextValue = value ?? props.min;
435
+ const nextValue = value ?? min;
449
436
  if (width <= 0) width = 1;
450
437
  if (clientX) return (state.isRtl ? (boundingRect?.right ?? 0) - clientX : clientX - (boundingRect?.left ?? 0)) / width;
451
438
  return calcRawLeftPercent({
452
- max: props.max,
453
- min: props.min,
439
+ max,
440
+ min,
454
441
  value: nextValue
455
442
  });
456
443
  };
@@ -459,7 +446,6 @@ const Slider = (props) => {
459
446
  * with the corresponding handle position percentage.
460
447
  */
461
448
  const calcDiscreteValueAndPercent = ({ leftPercent }) => {
462
- const { step = 1, min, max } = props;
463
449
  const numSteps = Math.floor((max - min) / step) + 1;
464
450
  /** Index of the step that corresponds to `leftPercent`. */
465
451
  const stepIndex = Math.round(leftPercent * (numSteps - 1));
@@ -519,22 +505,22 @@ const Slider = (props) => {
519
505
  if (handle === "lower") setState({
520
506
  value: valueUpper && newValue > valueUpper ? valueUpper : newValue,
521
507
  left: valueUpper && newValue > valueUpper ? leftUpper : newLeft,
522
- isValid: true
508
+ ...getValidityUpdateForHandle(handle, true)
523
509
  });
524
510
  else setState({
525
511
  valueUpper: value && newValue < value ? value : newValue,
526
512
  leftUpper: value && newValue < value ? left : newLeft,
527
- isValidUpper: true
513
+ ...getValidityUpdateForHandle(handle, true)
528
514
  });
529
515
  };
530
516
  const setValueForHandle = (handle, value) => {
531
517
  if (handle === "lower") setState({
532
518
  value,
533
- isValid: true
519
+ ...getValidityUpdateForHandle(handle, true)
534
520
  });
535
521
  else setState({
536
522
  valueUpper: value,
537
- isValidUpper: true
523
+ ...getValidityUpdateForHandle(handle, true)
538
524
  });
539
525
  };
540
526
  const isValidValueForPosition = ({ handle, value: newValue, min, max }) => {
@@ -586,16 +572,15 @@ const Slider = (props) => {
586
572
  useEffect(() => {
587
573
  const { isValid, isValidUpper } = stateRef.current;
588
574
  const derivedState = {};
589
- if (props.invalid === true) {
575
+ if (invalid === true) {
590
576
  if (isValid === true) derivedState.isValid = false;
591
577
  if (isValidUpper === true) derivedState.isValidUpper = false;
592
- } else if (props.invalid === false) {
578
+ } else if (invalid === false) {
593
579
  if (isValid === false) derivedState.isValid = true;
594
580
  if (isValidUpper === false) derivedState.isValidUpper = true;
595
581
  }
596
582
  if (Object.keys(derivedState).length) setState(derivedState);
597
- }, [props.invalid]);
598
- const { ariaLabelInput, unstable_ariaLabelInputUpper: ariaLabelInputUpper, className, hideTextInput = false, id: idProp, min, minLabel, max, maxLabel, formatLabel = defaultFormatLabel, labelText, hideLabel, step = 1, inputType = "number", invalidText, required, disabled = false, name, unstable_nameUpper: nameUpper, light, readOnly = false, warn = false, warnText, translateWithId: t = defaultTranslateWithId, ...other } = props;
583
+ }, [invalid]);
599
584
  const id = idProp ?? generatedId;
600
585
  const { value, valueUpper, isValid, isValidUpper, correctedValue, correctedPosition, isRtl } = state;
601
586
  const normalizedProps = useNormalizedInputProps({
@@ -612,10 +597,12 @@ const Slider = (props) => {
612
597
  invalid: !isValidUpper,
613
598
  warn
614
599
  });
615
- delete other.invalid;
616
- delete other.onRelease;
617
- delete other.stepMultiplier;
618
- delete other.unstable_valueUpper;
600
+ const passthroughProps = {
601
+ ...other,
602
+ onBlur,
603
+ onChange,
604
+ value: controlledValue
605
+ };
619
606
  const showWarning = normalizedProps.warn || correctedPosition === "lower" && isValid;
620
607
  const showWarningUpper = normalizedUpperProps.warn || correctedPosition === (twoHandles ? "upper" : "lower") && (twoHandles ? isValidUpper : isValid);
621
608
  const labelId = `${id}-label`;
@@ -715,7 +702,7 @@ const Slider = (props) => {
715
702
  step,
716
703
  onChange: onChangeInput,
717
704
  onBlur: onBlurInput,
718
- onKeyUp: props.onInputKeyUp,
705
+ onKeyUp: onInputKeyUp,
719
706
  onKeyDown: onInputKeyDown,
720
707
  "data-invalid": normalizedProps.invalid ? true : null,
721
708
  "data-handle-position": "lower",
@@ -741,7 +728,7 @@ const Slider = (props) => {
741
728
  role: "presentation",
742
729
  tabIndex: -1,
743
730
  "data-invalid": (twoHandles ? normalizedProps.invalid || normalizedUpperProps.invalid : normalizedProps.invalid) ? true : null,
744
- ...other,
731
+ ...passthroughProps,
745
732
  children: [
746
733
  /* @__PURE__ */ jsx(ThumbWrapper, {
747
734
  hasTooltip: hideTextInput,
@@ -784,12 +771,7 @@ const Slider = (props) => {
784
771
  children: !isRtl ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(UpperHandle, { "aria-label": ariaLabelInputUpper }), /* @__PURE__ */ jsx(UpperHandleFocus, { "aria-label": ariaLabelInputUpper })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(LowerHandle, { "aria-label": ariaLabelInput }), /* @__PURE__ */ jsx(LowerHandleFocus, { "aria-label": ariaLabelInput })] })
785
772
  })
786
773
  }) : null,
787
- /* @__PURE__ */ jsx("div", {
788
- className: `${prefix}--slider__track`,
789
- ref: (node) => {
790
- trackRef.current = node;
791
- }
792
- }),
774
+ /* @__PURE__ */ jsx("div", { className: `${prefix}--slider__track` }),
793
775
  /* @__PURE__ */ jsx("div", {
794
776
  className: `${prefix}--slider__filled-track`,
795
777
  ref: filledTrackRef
@@ -819,7 +801,7 @@ const Slider = (props) => {
819
801
  onChange: onChangeInput,
820
802
  onBlur: onBlurInput,
821
803
  onKeyDown: onInputKeyDown,
822
- onKeyUp: props.onInputKeyUp,
804
+ onKeyUp: onInputKeyUp,
823
805
  "data-invalid": (twoHandles ? normalizedUpperProps.invalid : normalizedProps.invalid) ? true : null,
824
806
  "data-handle-position": twoHandles ? "upper" : null,
825
807
  "aria-invalid": (twoHandles ? normalizedUpperProps.invalid : normalizedProps.invalid) ? true : void 0,
@@ -165,7 +165,7 @@ function TabList({ activation = "automatic", "aria-label": label, children, clas
165
165
  [`${prefix}--tabs--full-width`]: distributeWidth,
166
166
  [`${prefix}--tabs--dismissable`]: dismissable
167
167
  }, customClassName);
168
- const [isNextButtonVisible, setIsNextButtonVisible] = useState(ref.current ? scrollLeft + buttonWidth + ref.current.clientWidth < ref.current.scrollWidth : false);
168
+ const [isNextButtonVisible, setIsNextButtonVisible] = useState(ref.current ? scrollLeft + ref.current.clientWidth < ref.current.scrollWidth : false);
169
169
  const isPreviousButtonVisible = ref.current ? isScrollable && scrollLeft > 0 : false;
170
170
  const previousButtonClasses = classNames(`${prefix}--tab--overflow-nav-button`, `${prefix}--tab--overflow-nav-button--previous`, { [`${prefix}--tab--overflow-nav-button--hidden`]: !isPreviousButtonVisible });
171
171
  const nextButtonClasses = classNames(`${prefix}--tab--overflow-nav-button`, `${prefix}--tab--overflow-nav-button--next`, { [`${prefix}--tab--overflow-nav-button--hidden`]: !isNextButtonVisible });
@@ -220,7 +220,7 @@ function TabList({ activation = "automatic", "aria-label": label, children, clas
220
220
  });
221
221
  }, []);
222
222
  useEffect(() => {
223
- setIsNextButtonVisible(ref.current ? scrollLeft + buttonWidth + ref.current.clientWidth + 1 < ref.current.scrollWidth : false);
223
+ setIsNextButtonVisible(ref.current ? scrollLeft + ref.current.clientWidth + 1 < ref.current.scrollWidth : false);
224
224
  if (dismissable && ref.current) setIsScrollable(ref.current.scrollWidth > ref.current.clientWidth + 1);
225
225
  }, [
226
226
  children,
@@ -13,6 +13,7 @@ import { noopFn } from "../../internal/noopFn.js";
13
13
  import { deprecate } from "../../prop-types/deprecate.js";
14
14
  import { isComponentElement } from "../../internal/utils.js";
15
15
  import { useMergedRefs } from "../../internal/useMergedRefs.js";
16
+ import { hasHelperText } from "../../internal/hasHelperText.js";
16
17
  import { AILabel } from "../AILabel/index.js";
17
18
  import { FormContext } from "../FluidForm/FormContext.js";
18
19
  import { getAnnouncement } from "../../internal/getAnnouncement.js";
@@ -171,7 +172,7 @@ const TextArea = forwardRef((props, forwardRef) => {
171
172
  children: `${textCount}/${maxCount}`
172
173
  }) : null;
173
174
  const counterDescriptionId = enableCounter && maxCount ? `${id}-counter-desc` : void 0;
174
- const hasHelper = typeof helperText !== "undefined" && helperText !== null;
175
+ const hasHelper = hasHelperText(helperText);
175
176
  const helperId = !hasHelper ? void 0 : `text-area-helper-text-${textAreaInstanceId}`;
176
177
  const helper = hasHelper && /* @__PURE__ */ jsx(Text, {
177
178
  as: "div",
@@ -199,7 +200,8 @@ const TextArea = forwardRef((props, forwardRef) => {
199
200
  children: [warnText, isFluid && /* @__PURE__ */ jsx(WarningAltFilled, { className: `${prefix}--text-area__invalid-icon ${prefix}--text-area__invalid-icon--warning` })]
200
201
  }) : null;
201
202
  let ariaDescribedBy;
202
- if (invalid) ariaDescribedBy = errorId;
203
+ let ariaErrorMessage;
204
+ if (invalid) ariaErrorMessage = errorId;
203
205
  else if (warn && !isFluid) ariaDescribedBy = warnId;
204
206
  else {
205
207
  const ids = [];
@@ -242,6 +244,7 @@ const TextArea = forwardRef((props, forwardRef) => {
242
244
  className: textareaClasses,
243
245
  "aria-invalid": invalid,
244
246
  "aria-describedby": ariaDescribedBy,
247
+ "aria-errormessage": ariaErrorMessage,
245
248
  disabled,
246
249
  rows,
247
250
  readOnly: other.readOnly,
@@ -9,6 +9,7 @@ import { usePrefix } from "../../internal/usePrefix.js";
9
9
  import { useId } from "../../internal/useId.js";
10
10
  import { noopFn } from "../../internal/noopFn.js";
11
11
  import { deprecate } from "../../prop-types/deprecate.js";
12
+ import { hasHelperText } from "../../internal/hasHelperText.js";
12
13
  import { getTextInputProps } from "./util.js";
13
14
  import classNames from "classnames";
14
15
  import { forwardRef } from "react";
@@ -65,7 +66,7 @@ const ControlledPasswordInput = forwardRef(({ labelText, className, id, placehol
65
66
  [`${prefix}--tooltip--${tooltipPosition}`]: tooltipPosition,
66
67
  [`${prefix}--tooltip--align-${tooltipAlignment}`]: tooltipAlignment
67
68
  });
68
- const hasHelper = typeof helperText !== "undefined" && helperText !== null;
69
+ const hasHelper = hasHelperText(helperText);
69
70
  const helperId = !hasHelper ? void 0 : `controlled-password-helper-text-${controlledPasswordInstanceId}`;
70
71
  const input = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("input", {
71
72
  ...getTextInputProps({
@@ -96,9 +96,9 @@ export interface PasswordInputProps extends Omit<InputHTMLAttributes<HTMLInputEl
96
96
  */
97
97
  showPasswordLabel?: string;
98
98
  /**
99
- * Specify the size of the Text Input. Supports `sm`, `md`, or `lg`.
99
+ * Specify the size of the Text Input. Supports `xs`, `sm`, `md`, or `lg`.
100
100
  */
101
- size?: 'sm' | 'md' | 'lg';
101
+ size?: 'xs' | 'sm' | 'md' | 'lg';
102
102
  /**
103
103
  * Specify the alignment of the tooltip to the icon-only button.
104
104
  * Can be one of: `start`, `center`, or `end`.
@@ -8,6 +8,7 @@
8
8
  import { usePrefix } from "../../internal/usePrefix.js";
9
9
  import { deprecate } from "../../prop-types/deprecate.js";
10
10
  import { Tooltip } from "../Tooltip/Tooltip.js";
11
+ import { hasHelperText } from "../../internal/hasHelperText.js";
11
12
  import { useNormalizedInputProps } from "../../internal/useNormalizedInputProps.js";
12
13
  import { FormContext } from "../FluidForm/FormContext.js";
13
14
  import { getTextInputProps } from "./util.js";
@@ -23,7 +24,7 @@ import { View, ViewOff } from "@carbon/icons-react";
23
24
  * This source code is licensed under the Apache-2.0 license found in the
24
25
  * LICENSE file in the root directory of this source tree.
25
26
  */
26
- const PasswordInput = forwardRef(({ className, disabled = false, helperText, hideLabel, hidePasswordLabel = "Hide password", id, inline, invalid = false, invalidText, labelText, light, onChange = () => {}, onClick = () => {}, onTogglePasswordVisibility, placeholder, readOnly, size = "md", showPasswordLabel = "Show password", tooltipPosition = "bottom", tooltipAlignment = "end", type = "password", warn = false, warnText, ...rest }, ref) => {
27
+ const PasswordInput = forwardRef(({ className, disabled = false, helperText, hideLabel, hidePasswordLabel = "Hide password", id, inline, invalid = false, invalidText, labelText, light, onChange = () => {}, onClick = () => {}, onTogglePasswordVisibility, placeholder, readOnly, size, showPasswordLabel = "Show password", tooltipPosition = "bottom", tooltipAlignment = "end", type = "password", warn = false, warnText, ...rest }, ref) => {
27
28
  const [inputType, setInputType] = useState(type);
28
29
  const prefix = usePrefix();
29
30
  const normalizedProps = useNormalizedInputProps({
@@ -54,8 +55,7 @@ const PasswordInput = forwardRef(({ className, disabled = false, helperText, hid
54
55
  [`${prefix}--text-input--light`]: light,
55
56
  [`${prefix}--text-input--invalid`]: normalizedProps.invalid,
56
57
  [`${prefix}--text-input--warning`]: normalizedProps.warn,
57
- [`${prefix}--text-input--${size}`]: size,
58
- [`${prefix}--layout--size-${size}`]: size
58
+ [`${prefix}--text-input--${size}`]: size
59
59
  }),
60
60
  readOnly,
61
61
  ref,
@@ -65,6 +65,7 @@ const PasswordInput = forwardRef(({ className, disabled = false, helperText, hid
65
65
  [`${prefix}--text-input-wrapper--readonly`]: readOnly,
66
66
  [`${prefix}--text-input-wrapper--light`]: light,
67
67
  [`${prefix}--text-input-wrapper--inline`]: inline,
68
+ [`${prefix}--text-input-wrapper--inline--invalid`]: inline && normalizedProps.invalid,
68
69
  [`${prefix}--text-input--fluid`]: isFluid
69
70
  });
70
71
  const labelClasses = classNames(`${prefix}--label`, {
@@ -78,7 +79,10 @@ const PasswordInput = forwardRef(({ className, disabled = false, helperText, hid
78
79
  [`${prefix}--form__helper-text--inline`]: inline
79
80
  });
80
81
  const fieldOuterWrapperClasses = classNames(`${prefix}--text-input__field-outer-wrapper`, { [`${prefix}--text-input__field-outer-wrapper--inline`]: inline });
81
- const fieldWrapperClasses = classNames(`${prefix}--text-input__field-wrapper`, { [`${prefix}--text-input__field-wrapper--warning`]: normalizedProps.warn });
82
+ const fieldWrapperClasses = classNames(`${prefix}--text-input__field-wrapper`, {
83
+ [`${prefix}--text-input__field-wrapper--warning`]: normalizedProps.warn,
84
+ [`${prefix}--layout--size-${size}`]: size
85
+ });
82
86
  const iconClasses = classNames({
83
87
  [`${prefix}--text-input__invalid-icon`]: normalizedProps.invalid || normalizedProps.warn,
84
88
  [`${prefix}--text-input__invalid-icon--warning`]: normalizedProps.warn
@@ -88,7 +92,7 @@ const PasswordInput = forwardRef(({ className, disabled = false, helperText, hid
88
92
  className: labelClasses,
89
93
  children: labelText
90
94
  });
91
- const helper = typeof helperText !== "undefined" && helperText !== null && /* @__PURE__ */ jsx("div", {
95
+ const helper = hasHelperText(helperText) && /* @__PURE__ */ jsx("div", {
92
96
  id: normalizedProps.helperId,
93
97
  className: helperTextClasses,
94
98
  children: helperText
@@ -117,7 +121,7 @@ const PasswordInput = forwardRef(({ className, disabled = false, helperText, hid
117
121
  invalidId: normalizedProps.invalidId,
118
122
  warn: normalizedProps.warn,
119
123
  warnId: normalizedProps.warnId,
120
- hasHelper: Boolean(helperText && !isFluid && (inline || !inline && !normalizedProps.validation)),
124
+ hasHelper: hasHelperText(helperText) && !isFluid && (inline || !inline && !normalizedProps.validation),
121
125
  helperId: normalizedProps.helperId
122
126
  }),
123
127
  disabled,
@@ -143,21 +147,28 @@ const PasswordInput = forwardRef(({ className, disabled = false, helperText, hid
143
147
  const Icon = normalizedProps.icon;
144
148
  return /* @__PURE__ */ jsxs("div", {
145
149
  className: inputWrapperClasses,
146
- children: [!inline ? label : /* @__PURE__ */ jsxs("div", {
147
- className: `${prefix}--text-input__label-helper-wrapper`,
148
- children: [label, !isFluid && helper]
149
- }), /* @__PURE__ */ jsxs("div", {
150
- className: fieldOuterWrapperClasses,
151
- children: [/* @__PURE__ */ jsxs("div", {
152
- className: fieldWrapperClasses,
153
- "data-invalid": normalizedProps.invalid || null,
154
- children: [
155
- Icon && /* @__PURE__ */ jsx(Icon, { className: iconClasses }),
156
- input,
157
- isFluid && !inline && normalizedProps.validation
158
- ]
159
- }), !isFluid && !inline && (normalizedProps.validation || helper)]
160
- })]
150
+ children: [
151
+ !inline ? label : /* @__PURE__ */ jsx("div", {
152
+ className: `${prefix}--text-input__label-helper-wrapper`,
153
+ children: label
154
+ }),
155
+ /* @__PURE__ */ jsxs("div", {
156
+ className: fieldOuterWrapperClasses,
157
+ children: [/* @__PURE__ */ jsxs("div", {
158
+ className: fieldWrapperClasses,
159
+ "data-invalid": normalizedProps.invalid || null,
160
+ children: [
161
+ Icon && /* @__PURE__ */ jsx(Icon, { className: iconClasses }),
162
+ input,
163
+ isFluid && !inline && normalizedProps.validation
164
+ ]
165
+ }), !isFluid && !inline && (normalizedProps.validation || helper)]
166
+ }),
167
+ inline && !isFluid && /* @__PURE__ */ jsx("div", {
168
+ className: `${prefix}--text-input__label-helper-wrapper`,
169
+ children: normalizedProps.validation || helper
170
+ })
171
+ ]
161
172
  });
162
173
  });
163
174
  PasswordInput.displayName = "PasswordInput";
@@ -181,6 +192,7 @@ PasswordInput.propTypes = {
181
192
  placeholder: PropTypes.string,
182
193
  showPasswordLabel: PropTypes.string,
183
194
  size: PropTypes.oneOf([
195
+ "xs",
184
196
  "sm",
185
197
  "md",
186
198
  "lg"
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2023
2
+ * Copyright IBM Corp. 2016, 2026
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -15,9 +15,13 @@ export interface TextInputSkeletonProps extends React.HTMLAttributes<HTMLDivElem
15
15
  * Specify whether the label should be hidden or not.
16
16
  */
17
17
  hideLabel?: boolean;
18
+ /**
19
+ * Specify the size of the TextInputSkeleton
20
+ */
21
+ size?: 'xs' | 'sm' | 'md' | 'lg';
18
22
  }
19
23
  declare const TextInputSkeleton: {
20
- ({ hideLabel, className, ...rest }: TextInputSkeletonProps): import("react/jsx-runtime").JSX.Element;
24
+ ({ hideLabel, className, size, ...rest }: TextInputSkeletonProps): import("react/jsx-runtime").JSX.Element;
21
25
  propTypes: {
22
26
  /**
23
27
  * Specify an optional className to add to the form item wrapper.
@@ -27,6 +31,10 @@ declare const TextInputSkeleton: {
27
31
  * Specify whether the label should be hidden, or not
28
32
  */
29
33
  hideLabel: PropTypes.Requireable<boolean>;
34
+ /**
35
+ * Specify the size of the TextInputSkeleton
36
+ */
37
+ size: PropTypes.Requireable<string>;
30
38
  };
31
39
  };
32
40
  export default TextInputSkeleton;
@@ -12,22 +12,28 @@ import PropTypes from "prop-types";
12
12
  import { jsx, jsxs } from "react/jsx-runtime";
13
13
  //#region src/components/TextInput/TextInput.Skeleton.tsx
14
14
  /**
15
- * Copyright IBM Corp. 2016, 2023
15
+ * Copyright IBM Corp. 2016, 2026
16
16
  *
17
17
  * This source code is licensed under the Apache-2.0 license found in the
18
18
  * LICENSE file in the root directory of this source tree.
19
19
  */
20
- const TextInputSkeleton = ({ hideLabel, className, ...rest }) => {
20
+ const TextInputSkeleton = ({ hideLabel, className, size, ...rest }) => {
21
21
  const prefix = usePrefix();
22
22
  return /* @__PURE__ */ jsxs("div", {
23
- className: classNames(`${prefix}--form-item`, className),
23
+ className: classNames(`${prefix}--form-item`, className, { [`${prefix}--layout--size-${size}`]: size }),
24
24
  ...rest,
25
25
  children: [!hideLabel && /* @__PURE__ */ jsx("span", { className: `${prefix}--label ${prefix}--skeleton` }), /* @__PURE__ */ jsx("div", { className: `${prefix}--skeleton ${prefix}--text-input` })]
26
26
  });
27
27
  };
28
28
  TextInputSkeleton.propTypes = {
29
29
  className: PropTypes.string,
30
- hideLabel: PropTypes.bool
30
+ hideLabel: PropTypes.bool,
31
+ size: PropTypes.oneOf([
32
+ "xs",
33
+ "sm",
34
+ "md",
35
+ "lg"
36
+ ])
31
37
  };
32
38
  //#endregion
33
39
  export { TextInputSkeleton as default };
@@ -88,7 +88,7 @@ export interface TextInputProps extends Omit<React.InputHTMLAttributes<HTMLInput
88
88
  /**
89
89
  * Specify the size of the Text Input. Currently supports the following:
90
90
  */
91
- size?: 'sm' | 'md' | 'lg' | 'xl';
91
+ size?: 'xs' | 'sm' | 'md' | 'lg';
92
92
  /**
93
93
  * @deprecated please use `decorator` instead.
94
94
  * **Experimental**: Provide a `Slug` component to be rendered inside the `TextInput` component