@carbon/react 1.78.1 → 1.79.0-rc.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/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +844 -844
- package/es/components/Button/Button.js +28 -17
- package/es/components/Button/ButtonBase.js +2 -0
- package/es/components/DataTable/TableContainer.js +3 -2
- package/es/components/Grid/Column.d.ts +2 -2
- package/es/components/Grid/Column.js +7 -8
- package/es/components/IconButton/index.d.ts +2 -2
- package/es/components/IconButton/index.js +1 -1
- package/es/components/MultiSelect/index.d.ts +1 -1
- package/es/components/MultiSelect/index.js +1 -8
- package/es/components/OverflowMenu/OverflowMenu.d.ts +21 -196
- package/es/components/OverflowMenu/OverflowMenu.js +267 -336
- package/es/components/OverflowMenu/index.d.ts +5 -5
- package/es/components/OverflowMenu/index.js +2 -2
- package/es/components/OverflowMenu/next/index.d.ts +2 -2
- package/es/components/Slider/Slider.d.ts +23 -29
- package/es/components/Slider/Slider.js +35 -37
- package/es/components/Tabs/Tabs.js +8 -9
- package/es/components/Tile/Tile.js +8 -4
- package/es/index.js +1 -1
- package/es/internal/FloatingMenu.d.ts +2 -2
- package/es/internal/FloatingMenu.js +4 -1
- package/es/internal/createClassWrapper.d.ts +3 -3
- package/es/internal/createClassWrapper.js +4 -4
- package/es/internal/useMatchMedia.d.ts +8 -0
- package/es/internal/useMatchMedia.js +10 -20
- package/es/internal/useNormalizedInputProps.d.ts +52 -0
- package/es/internal/useNormalizedInputProps.js +9 -36
- package/lib/components/Button/Button.js +28 -17
- package/lib/components/Button/ButtonBase.js +2 -0
- package/lib/components/DataTable/TableContainer.js +3 -2
- package/lib/components/Grid/Column.d.ts +2 -2
- package/lib/components/Grid/Column.js +7 -8
- package/lib/components/IconButton/index.d.ts +2 -2
- package/lib/components/IconButton/index.js +1 -1
- package/lib/components/MultiSelect/index.d.ts +1 -1
- package/lib/components/MultiSelect/index.js +1 -8
- package/lib/components/OverflowMenu/OverflowMenu.d.ts +21 -196
- package/lib/components/OverflowMenu/OverflowMenu.js +266 -334
- package/lib/components/OverflowMenu/index.d.ts +5 -5
- package/lib/components/OverflowMenu/index.js +2 -2
- package/lib/components/OverflowMenu/next/index.d.ts +2 -2
- package/lib/components/Slider/Slider.d.ts +23 -29
- package/lib/components/Slider/Slider.js +35 -37
- package/lib/components/Tabs/Tabs.js +8 -9
- package/lib/components/Tile/Tile.js +8 -4
- package/lib/index.js +2 -2
- package/lib/internal/FloatingMenu.d.ts +2 -2
- package/lib/internal/FloatingMenu.js +4 -1
- package/lib/internal/createClassWrapper.d.ts +3 -3
- package/lib/internal/createClassWrapper.js +4 -4
- package/lib/internal/useMatchMedia.d.ts +8 -0
- package/lib/internal/useMatchMedia.js +10 -20
- package/lib/internal/useNormalizedInputProps.d.ts +52 -0
- package/lib/internal/useNormalizedInputProps.js +9 -36
- package/package.json +6 -6
- package/es/internal/useEffectOnce.js +0 -30
- package/lib/internal/useEffectOnce.js +0 -34
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright IBM Corp. 2016,
|
|
2
|
+
* Copyright IBM Corp. 2016, 2025
|
|
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.
|
|
6
6
|
*/
|
|
7
7
|
import { type OverflowMenuProps } from './OverflowMenu';
|
|
8
|
-
declare
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
8
|
+
declare const OverflowMenu: {
|
|
9
|
+
(props: OverflowMenuProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
displayName: string;
|
|
11
|
+
};
|
|
12
12
|
export default OverflowMenu;
|
|
13
13
|
export { OverflowMenu, type OverflowMenuProps };
|
|
@@ -12,10 +12,10 @@ import { OverflowMenu as OverflowMenu$1 } from './OverflowMenu.js';
|
|
|
12
12
|
import { createClassWrapper } from '../../internal/createClassWrapper.js';
|
|
13
13
|
|
|
14
14
|
const OverflowMenuV11 = createClassWrapper(OverflowMenu$1);
|
|
15
|
-
|
|
15
|
+
const OverflowMenu = props => {
|
|
16
16
|
const enableV12OverflowMenu = useFeatureFlag('enable-v12-overflowmenu');
|
|
17
17
|
return enableV12OverflowMenu ? /*#__PURE__*/React__default.createElement(OverflowMenu$2, props) : /*#__PURE__*/React__default.createElement(OverflowMenuV11, props);
|
|
18
|
-
}
|
|
18
|
+
};
|
|
19
19
|
OverflowMenu.displayName = 'OverflowMenu';
|
|
20
20
|
|
|
21
21
|
export { OverflowMenu, OverflowMenu as default };
|
|
@@ -4,7 +4,7 @@
|
|
|
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.
|
|
6
6
|
*/
|
|
7
|
-
import React, { type
|
|
7
|
+
import React, { type ElementType } from 'react';
|
|
8
8
|
interface OverflowMenuProps {
|
|
9
9
|
/**
|
|
10
10
|
* **Experimental**: Will attempt to automatically align the floating element to avoid collisions with the viewport and being clipped by ancestor elements.
|
|
@@ -29,7 +29,7 @@ interface OverflowMenuProps {
|
|
|
29
29
|
/**
|
|
30
30
|
* A component used to render an icon.
|
|
31
31
|
*/
|
|
32
|
-
renderIcon?:
|
|
32
|
+
renderIcon?: ElementType;
|
|
33
33
|
/**
|
|
34
34
|
* Specify the size of the menu, from a list of available sizes.
|
|
35
35
|
*/
|
|
@@ -164,11 +164,6 @@ export interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputEle
|
|
|
164
164
|
*/
|
|
165
165
|
warnText?: React.ReactNode;
|
|
166
166
|
}
|
|
167
|
-
interface CalcValueProps {
|
|
168
|
-
clientX?: number;
|
|
169
|
-
value?: number;
|
|
170
|
-
useRawValue?: boolean;
|
|
171
|
-
}
|
|
172
167
|
interface CalcLeftPercentProps {
|
|
173
168
|
clientX?: number;
|
|
174
169
|
value?: number;
|
|
@@ -415,30 +410,29 @@ declare class Slider extends PureComponent<SliderProps> {
|
|
|
415
410
|
onInputKeyDown: (evt: any) => void;
|
|
416
411
|
processNewInputValue: (input: HTMLInputElement) => void;
|
|
417
412
|
calcLeftPercent: ({ clientX, value, range }: CalcLeftPercentProps) => number;
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
calcValue: ({ clientX, value, useRawValue }: CalcValueProps) => {
|
|
413
|
+
/**
|
|
414
|
+
* Calculates the discrete value (snapped to the nearest step) along
|
|
415
|
+
* with the corresponding handle position percentage.
|
|
416
|
+
*/
|
|
417
|
+
calcDiscreteValueAndPercent: ({ leftPercent, }: {
|
|
418
|
+
/** The percentage representing the position on the track. */
|
|
419
|
+
leftPercent: number;
|
|
420
|
+
}) => {
|
|
421
|
+
discreteValue: number;
|
|
422
|
+
discretePercent: number;
|
|
423
|
+
};
|
|
424
|
+
/**
|
|
425
|
+
* Calculates the slider's value and handle position based on either a
|
|
426
|
+
* mouse/touch event or an explicit value.
|
|
427
|
+
*/
|
|
428
|
+
calcValue: ({ clientX, value, useRawValue, }: {
|
|
429
|
+
/** The x-coordinate from a mouse/touch event. */
|
|
430
|
+
clientX?: number;
|
|
431
|
+
/** Value to base the calculations on (if no `clientX`). */
|
|
432
|
+
value?: number;
|
|
433
|
+
/** Whether to bypass the stepping logic and use the raw value. */
|
|
434
|
+
useRawValue?: boolean;
|
|
435
|
+
}) => {
|
|
442
436
|
value: number | undefined;
|
|
443
437
|
left: number;
|
|
444
438
|
};
|
|
@@ -523,67 +523,65 @@ class Slider extends PureComponent {
|
|
|
523
523
|
// re-assure Typescript, return 0.
|
|
524
524
|
return 0;
|
|
525
525
|
});
|
|
526
|
-
|
|
526
|
+
/**
|
|
527
|
+
* Calculates the discrete value (snapped to the nearest step) along
|
|
528
|
+
* with the corresponding handle position percentage.
|
|
529
|
+
*/
|
|
530
|
+
_defineProperty(this, "calcDiscreteValueAndPercent", _ref3 => {
|
|
527
531
|
let {
|
|
528
|
-
leftPercent
|
|
529
|
-
range
|
|
532
|
+
leftPercent
|
|
530
533
|
} = _ref3;
|
|
531
534
|
const {
|
|
532
|
-
step = 1
|
|
535
|
+
step = 1,
|
|
536
|
+
min,
|
|
537
|
+
max
|
|
533
538
|
} = this.props;
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
|
|
539
|
+
const numSteps = Math.floor((max - min) / step) + ((max - min) % step === 0 ? 1 : 2);
|
|
540
|
+
/** Index of the step that corresponds to `leftPercent`. */
|
|
541
|
+
const stepIndex = Math.round(leftPercent * (numSteps - 1));
|
|
542
|
+
const discreteValue = stepIndex === numSteps - 1 ? max : min + step * stepIndex;
|
|
543
|
+
/** Percentage corresponding to the step index. */
|
|
544
|
+
const discretePercent = stepIndex / (numSteps - 1);
|
|
545
|
+
return {
|
|
546
|
+
discreteValue,
|
|
547
|
+
discretePercent
|
|
548
|
+
};
|
|
539
549
|
});
|
|
540
550
|
/**
|
|
541
|
-
* Calculates
|
|
542
|
-
*
|
|
543
|
-
* - If `clientX` is specified, it will be used in
|
|
544
|
-
* conjunction with the Slider's bounding rectangle to calculate the new
|
|
545
|
-
* values.
|
|
546
|
-
* - If `clientX` is not specified and `value` is, it will be used to
|
|
547
|
-
* calculate new values as though it were the current value of the Slider.
|
|
548
|
-
* - If neither `clientX` nor `value` are specified, `this.props.value` will
|
|
549
|
-
* be used to calculate the new values as though it were the current value
|
|
550
|
-
* of the Slider.
|
|
551
|
-
*
|
|
552
|
-
* @param {object} params
|
|
553
|
-
* @param {number} [params.clientX] Optional clientX value expected to be from
|
|
554
|
-
* an event fired by one of the Slider's `DRAG_EVENT_TYPES` events.
|
|
555
|
-
* @param {number} [params.value] Optional value use during calculations if
|
|
556
|
-
* clientX is not provided.
|
|
557
|
-
* @param {boolean} [params.useRawValue=false] `true` to use the given value as-is.
|
|
551
|
+
* Calculates the slider's value and handle position based on either a
|
|
552
|
+
* mouse/touch event or an explicit value.
|
|
558
553
|
*/
|
|
559
554
|
_defineProperty(this, "calcValue", _ref4 => {
|
|
560
555
|
let {
|
|
561
556
|
clientX,
|
|
562
557
|
value,
|
|
563
|
-
useRawValue
|
|
558
|
+
useRawValue
|
|
564
559
|
} = _ref4;
|
|
565
560
|
const range = this.props.max - this.props.min;
|
|
566
|
-
|
|
567
|
-
// @todo solve for rtl.
|
|
568
|
-
const leftPercent = this.calcLeftPercent({
|
|
561
|
+
const leftPercentRaw = this.calcLeftPercent({
|
|
569
562
|
clientX,
|
|
570
563
|
value,
|
|
571
564
|
range
|
|
572
565
|
});
|
|
566
|
+
/** `leftPercentRaw` clamped between 0 and 1. */
|
|
567
|
+
const leftPercent = Math.min(1, Math.max(0, leftPercentRaw));
|
|
573
568
|
if (useRawValue) {
|
|
574
|
-
// Adjusts only for min/max of thumb position
|
|
575
569
|
return {
|
|
576
570
|
value,
|
|
577
|
-
left:
|
|
571
|
+
left: leftPercent * 100
|
|
578
572
|
};
|
|
579
573
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
574
|
+
|
|
575
|
+
// Use the discrete value and percentage for snapping.
|
|
576
|
+
const {
|
|
577
|
+
discreteValue,
|
|
578
|
+
discretePercent
|
|
579
|
+
} = this.calcDiscreteValueAndPercent({
|
|
580
|
+
leftPercent
|
|
583
581
|
});
|
|
584
582
|
return {
|
|
585
|
-
value:
|
|
586
|
-
left:
|
|
583
|
+
value: discreteValue,
|
|
584
|
+
left: discretePercent * 100
|
|
587
585
|
};
|
|
588
586
|
});
|
|
589
587
|
_defineProperty(this, "calcDistanceToHandle", (handle, clientX) => {
|
|
@@ -21,7 +21,6 @@ import { isElement } from 'react-is';
|
|
|
21
21
|
import '../Tooltip/DefinitionTooltip.js';
|
|
22
22
|
import { Tooltip } from '../Tooltip/Tooltip.js';
|
|
23
23
|
import { useControllableState } from '../../internal/useControllableState.js';
|
|
24
|
-
import { useEffectOnce } from '../../internal/useEffectOnce.js';
|
|
25
24
|
import { useId } from '../../internal/useId.js';
|
|
26
25
|
import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
|
|
27
26
|
import { useMergedRefs } from '../../internal/useMergedRefs.js';
|
|
@@ -382,7 +381,7 @@ function TabList(_ref4) {
|
|
|
382
381
|
}
|
|
383
382
|
}
|
|
384
383
|
}
|
|
385
|
-
|
|
384
|
+
useEffect(() => {
|
|
386
385
|
const tab = tabs.current[selectedIndex];
|
|
387
386
|
if (scrollIntoView && tab) {
|
|
388
387
|
tab.scrollIntoView({
|
|
@@ -390,7 +389,7 @@ function TabList(_ref4) {
|
|
|
390
389
|
inline: 'nearest'
|
|
391
390
|
});
|
|
392
391
|
}
|
|
393
|
-
});
|
|
392
|
+
}, []);
|
|
394
393
|
useEffect(() => {
|
|
395
394
|
//adding 1 in calculation for firefox support
|
|
396
395
|
setIsNextButtonVisible(ref.current ? scrollLeft + buttonWidth + ref.current.clientWidth + 1 < ref.current.scrollWidth : false);
|
|
@@ -400,7 +399,7 @@ function TabList(_ref4) {
|
|
|
400
399
|
}
|
|
401
400
|
}
|
|
402
401
|
}, [scrollLeft, children, dismissable, isScrollable]);
|
|
403
|
-
|
|
402
|
+
useEffect(() => {
|
|
404
403
|
if (tabs.current[selectedIndex]?.disabled) {
|
|
405
404
|
const activeTabs = tabs.current.filter(tab => {
|
|
406
405
|
return !tab.disabled;
|
|
@@ -410,7 +409,7 @@ function TabList(_ref4) {
|
|
|
410
409
|
setSelectedIndex(tabs.current.indexOf(tab));
|
|
411
410
|
}
|
|
412
411
|
}
|
|
413
|
-
});
|
|
412
|
+
}, []);
|
|
414
413
|
useIsomorphicEffect(() => {
|
|
415
414
|
if (ref.current) {
|
|
416
415
|
// adding 1 in calculation for firefox support
|
|
@@ -624,7 +623,7 @@ function TabListVertical(_ref8) {
|
|
|
624
623
|
setActiveIndex(selectedIndex);
|
|
625
624
|
}
|
|
626
625
|
}
|
|
627
|
-
|
|
626
|
+
useEffect(() => {
|
|
628
627
|
if (tabs.current[selectedIndex]?.disabled) {
|
|
629
628
|
const activeTabs = tabs.current.filter(tab => {
|
|
630
629
|
return !tab.disabled;
|
|
@@ -634,7 +633,7 @@ function TabListVertical(_ref8) {
|
|
|
634
633
|
setSelectedIndex(tabs.current.indexOf(tab));
|
|
635
634
|
}
|
|
636
635
|
}
|
|
637
|
-
});
|
|
636
|
+
}, []);
|
|
638
637
|
useEffect(() => {
|
|
639
638
|
function handler() {
|
|
640
639
|
const containerHeight = ref.current?.offsetHeight;
|
|
@@ -1123,7 +1122,7 @@ const TabPanel = /*#__PURE__*/React__default.forwardRef(function TabPanel(_ref12
|
|
|
1123
1122
|
const className = cx(`${prefix}--tab-content`, customClassName, {
|
|
1124
1123
|
[`${prefix}--tab-content--interactive`]: interactiveContent
|
|
1125
1124
|
});
|
|
1126
|
-
|
|
1125
|
+
useEffect(() => {
|
|
1127
1126
|
if (!panel.current) {
|
|
1128
1127
|
return;
|
|
1129
1128
|
}
|
|
@@ -1132,7 +1131,7 @@ const TabPanel = /*#__PURE__*/React__default.forwardRef(function TabPanel(_ref12
|
|
|
1132
1131
|
setInteractiveContent(true);
|
|
1133
1132
|
setTabIndex(-1);
|
|
1134
1133
|
}
|
|
1135
|
-
});
|
|
1134
|
+
}, []);
|
|
1136
1135
|
|
|
1137
1136
|
// tabindex should only be 0 if no interactive content in children
|
|
1138
1137
|
useEffect(() => {
|
|
@@ -255,14 +255,18 @@ const SelectableTile = /*#__PURE__*/React__default.forwardRef(function Selectabl
|
|
|
255
255
|
evt?.persist?.();
|
|
256
256
|
if (matches(evt, [Enter, Space])) {
|
|
257
257
|
evt.preventDefault();
|
|
258
|
-
setIsSelected(
|
|
259
|
-
|
|
258
|
+
setIsSelected(prevSelected => {
|
|
259
|
+
const newSelected = !prevSelected;
|
|
260
|
+
onChange(evt, newSelected, id);
|
|
261
|
+
return newSelected;
|
|
262
|
+
});
|
|
260
263
|
}
|
|
261
264
|
keyDownHandler(evt);
|
|
262
265
|
}
|
|
263
266
|
function handleChange(event) {
|
|
264
|
-
|
|
265
|
-
|
|
267
|
+
const newSelected = event.target.checked;
|
|
268
|
+
setIsSelected(newSelected);
|
|
269
|
+
onChange(event, newSelected, id);
|
|
266
270
|
}
|
|
267
271
|
if (selected !== prevSelected) {
|
|
268
272
|
setIsSelected(selected);
|
package/es/index.js
CHANGED
|
@@ -207,6 +207,7 @@ export { default as unstable_PageSelector } from './components/Pagination/experi
|
|
|
207
207
|
export { default as unstable_Pagination } from './components/Pagination/experimental/Pagination.js';
|
|
208
208
|
export { default as ContainedListItem } from './components/ContainedList/ContainedListItem/ContainedListItem.js';
|
|
209
209
|
export { default as ContainedList } from './components/ContainedList/ContainedList.js';
|
|
210
|
+
export { default as MultiSelect } from './components/MultiSelect/MultiSelect.js';
|
|
210
211
|
export { default as SliderSkeleton } from './components/Slider/Slider.Skeleton.js';
|
|
211
212
|
export { default as TextInputSkeleton } from './components/TextInput/TextInput.Skeleton.js';
|
|
212
213
|
export { default as TextInput } from './components/TextInput/TextInput.js';
|
|
@@ -238,4 +239,3 @@ export { default as TableToolbarContent } from './components/DataTable/TableTool
|
|
|
238
239
|
export { default as TableToolbarSearch } from './components/DataTable/TableToolbarSearch.js';
|
|
239
240
|
export { default as TableToolbarMenu } from './components/DataTable/TableToolbarMenu.js';
|
|
240
241
|
export { default as FilterableMultiSelect } from './components/MultiSelect/FilterableMultiSelect.js';
|
|
241
|
-
export { default as MultiSelect } from './components/MultiSelect/MultiSelect.js';
|
|
@@ -10,8 +10,8 @@ export declare const DIRECTION_TOP = "top";
|
|
|
10
10
|
export declare const DIRECTION_RIGHT = "right";
|
|
11
11
|
export declare const DIRECTION_BOTTOM = "bottom";
|
|
12
12
|
export interface Offset {
|
|
13
|
-
top
|
|
14
|
-
left
|
|
13
|
+
top: number;
|
|
14
|
+
left: number;
|
|
15
15
|
}
|
|
16
16
|
interface Container {
|
|
17
17
|
rect: DOMRect;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright IBM Corp. 2016,
|
|
2
|
+
* Copyright IBM Corp. 2016, 2025
|
|
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.
|
|
6
6
|
*/
|
|
7
|
-
import { ComponentClass, FunctionComponent } from 'react';
|
|
7
|
+
import { type ComponentClass, type ForwardRefExoticComponent, type FunctionComponent, type PropsWithChildren } from 'react';
|
|
8
8
|
/**
|
|
9
9
|
* Wrap a class component with a functional component. This prevents an end-user
|
|
10
10
|
* from being able to pass `ref` and access the underlying class instance.
|
|
11
11
|
*/
|
|
12
|
-
export declare
|
|
12
|
+
export declare const createClassWrapper: <Props extends PropsWithChildren>(Component: ComponentClass<Props> | ForwardRefExoticComponent<Props>) => FunctionComponent<Props>;
|
|
@@ -11,13 +11,13 @@ import React__default from 'react';
|
|
|
11
11
|
* Wrap a class component with a functional component. This prevents an end-user
|
|
12
12
|
* from being able to pass `ref` and access the underlying class instance.
|
|
13
13
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const createClassWrapper = Component => {
|
|
15
|
+
const ClassWrapper = props => {
|
|
16
16
|
return /*#__PURE__*/React__default.createElement(Component, props);
|
|
17
|
-
}
|
|
17
|
+
};
|
|
18
18
|
const name = Component.displayName || Component.name;
|
|
19
19
|
ClassWrapper.displayName = `ClassWrapper(${name})`;
|
|
20
20
|
return ClassWrapper;
|
|
21
|
-
}
|
|
21
|
+
};
|
|
22
22
|
|
|
23
23
|
export { createClassWrapper };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2025
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
/** Listens to changes in a media query and returns whether it matches. */
|
|
8
|
+
export declare const useMatchMedia: (mediaQuery: string) => boolean;
|
|
@@ -8,37 +8,27 @@
|
|
|
8
8
|
import { useState, useEffect } from 'react';
|
|
9
9
|
import { canUseDOM } from './environment.js';
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/** Listens to changes in a media query and returns whether it matches. */
|
|
12
|
+
const useMatchMedia = mediaQuery => {
|
|
12
13
|
const [matches, setMatches] = useState(() => {
|
|
13
14
|
if (canUseDOM) {
|
|
14
|
-
const mediaQueryList = window.matchMedia(
|
|
15
|
+
const mediaQueryList = window.matchMedia(mediaQuery);
|
|
15
16
|
return mediaQueryList.matches;
|
|
16
17
|
}
|
|
17
18
|
return false;
|
|
18
19
|
});
|
|
19
20
|
useEffect(() => {
|
|
20
|
-
|
|
21
|
+
const listener = event => {
|
|
21
22
|
setMatches(event.matches);
|
|
22
|
-
}
|
|
23
|
-
const mediaQueryList = window.matchMedia(
|
|
24
|
-
|
|
25
|
-
if (mediaQueryList.addEventListener) {
|
|
26
|
-
mediaQueryList.addEventListener('change', listener);
|
|
27
|
-
} else {
|
|
28
|
-
mediaQueryList.addListener(listener);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Make sure the media query list is in sync with the matches state
|
|
23
|
+
};
|
|
24
|
+
const mediaQueryList = window.matchMedia(mediaQuery);
|
|
25
|
+
mediaQueryList.addEventListener('change', listener);
|
|
32
26
|
setMatches(mediaQueryList.matches);
|
|
33
27
|
return () => {
|
|
34
|
-
|
|
35
|
-
mediaQueryList.removeEventListener('change', listener);
|
|
36
|
-
} else {
|
|
37
|
-
mediaQueryList.removeListener(listener);
|
|
38
|
-
}
|
|
28
|
+
mediaQueryList.removeEventListener('change', listener);
|
|
39
29
|
};
|
|
40
|
-
}, [
|
|
30
|
+
}, [mediaQuery]);
|
|
41
31
|
return matches;
|
|
42
|
-
}
|
|
32
|
+
};
|
|
43
33
|
|
|
44
34
|
export { useMatchMedia };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2021, 2025
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import { type ComponentType, type ReactNode } from 'react';
|
|
8
|
+
interface InputProps {
|
|
9
|
+
/** The ID for the input. */
|
|
10
|
+
id: string;
|
|
11
|
+
/** Whether the input is read-only. */
|
|
12
|
+
readOnly?: boolean;
|
|
13
|
+
/** Whether the input is disabled. */
|
|
14
|
+
disabled: boolean;
|
|
15
|
+
/** Whether the input is an invalid state. */
|
|
16
|
+
invalid: boolean;
|
|
17
|
+
/** The message displayed when the input is invalid. */
|
|
18
|
+
invalidText?: ReactNode;
|
|
19
|
+
/** Whether the input is in a warning state. */
|
|
20
|
+
warn: boolean;
|
|
21
|
+
/** The message displayed when the input is in a warning state. */
|
|
22
|
+
warnText?: ReactNode;
|
|
23
|
+
}
|
|
24
|
+
interface NormalizedInputProps {
|
|
25
|
+
/** Disabled state. */
|
|
26
|
+
disabled: boolean;
|
|
27
|
+
/** Invalid state. */
|
|
28
|
+
invalid: boolean;
|
|
29
|
+
/** The generated ID for the error message. */
|
|
30
|
+
invalidId: string;
|
|
31
|
+
/** The generated ID for the helper text. */
|
|
32
|
+
helperId: string;
|
|
33
|
+
/** Warning state. */
|
|
34
|
+
warn: boolean;
|
|
35
|
+
/** The generated ID for the warning message. */
|
|
36
|
+
warnId: string;
|
|
37
|
+
/** A React node containing the validation message. */
|
|
38
|
+
validation: ReactNode | null;
|
|
39
|
+
/** A React component representing the accompanying icon. */
|
|
40
|
+
icon: ComponentType | null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Returns an object containing normalized properties for an input component.
|
|
44
|
+
*
|
|
45
|
+
* This hook ensures that only one of `invalid` or `warn` is active (with
|
|
46
|
+
* `invalid` taking precedence) and that `readOnly` overrides the `disabled`,
|
|
47
|
+
* `invalid`, and `warn` states. It generates unique IDs for error, warning, and
|
|
48
|
+
* helper messages, and conditionally provides the appropriate validation
|
|
49
|
+
* message and accompanying icon.
|
|
50
|
+
*/
|
|
51
|
+
export declare const useNormalizedInputProps: ({ id, readOnly, disabled, invalid, invalidText, warn, warnText, }: InputProps) => NormalizedInputProps;
|
|
52
|
+
export {};
|
|
@@ -7,47 +7,20 @@
|
|
|
7
7
|
|
|
8
8
|
import React__default from 'react';
|
|
9
9
|
import { WarningFilled, WarningAltFilled } from '@carbon/icons-react';
|
|
10
|
-
import { usePrefix } from './usePrefix.js';
|
|
11
10
|
import '../components/Text/index.js';
|
|
11
|
+
import { usePrefix } from './usePrefix.js';
|
|
12
12
|
import { Text } from '../components/Text/Text.js';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
* @property {string} id - The input's id
|
|
17
|
-
* @property {boolean | undefined} readOnly - Whether the input should be readonly
|
|
18
|
-
* @property {boolean} disabled - Whether the input should be disabled
|
|
19
|
-
* @property {boolean} invalid - Whether the input should be marked as invalid
|
|
20
|
-
* @property {React.ReactNode | undefined} invalidText - The validation message displayed in case the input is considered invalid
|
|
21
|
-
* @property {boolean} warn - Whether the input should be in warning state
|
|
22
|
-
* @property {React.ReactNode | undefined} warnText - The validation message displayed in case the input is in warning state
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @typedef {object} NormalizedInputProps
|
|
27
|
-
* @property {boolean} disabled - Whether the input is disabled
|
|
28
|
-
* @property {boolean} invalid - Whether the input is invalid (takes precedence over warn)
|
|
29
|
-
* @property {string} invalidId - The invalid message's id
|
|
30
|
-
* @property {string} helperId - id used for helper text
|
|
31
|
-
* @property {boolean} warn - Whether the input is in warning state
|
|
32
|
-
* @property {string} warnId - The warning message's id
|
|
33
|
-
* @property {React.ReactNode | null} validation – React node rendering the appropriate validation message (if any)
|
|
34
|
-
* @property {React.ReactNode | null} icon – React node rendering the appropriate accompanying icon (if any)
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Returns an object containing non-colliding props and additional, generated ones.
|
|
39
|
-
* This hook ensures that only either "invalid" or "warn" is true but never both at
|
|
40
|
-
* the same time. Regardless whether "invalid" or "warn", the appropriate validation
|
|
41
|
-
* message is passed as "validation". If the input should be accompanied by an icon
|
|
42
|
-
* (to visually represent a readonly, invalid or warning state), the appropriate icon
|
|
43
|
-
* is passed as "icon".
|
|
44
|
-
* It also ensure that neither "invalid", nor "warn", nor "disabled" are enabled when
|
|
45
|
-
* "readonly" is passed as "readonly" takes precedence over these variants.
|
|
15
|
+
* Returns an object containing normalized properties for an input component.
|
|
46
16
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
17
|
+
* This hook ensures that only one of `invalid` or `warn` is active (with
|
|
18
|
+
* `invalid` taking precedence) and that `readOnly` overrides the `disabled`,
|
|
19
|
+
* `invalid`, and `warn` states. It generates unique IDs for error, warning, and
|
|
20
|
+
* helper messages, and conditionally provides the appropriate validation
|
|
21
|
+
* message and accompanying icon.
|
|
49
22
|
*/
|
|
50
|
-
|
|
23
|
+
const useNormalizedInputProps = _ref => {
|
|
51
24
|
let {
|
|
52
25
|
id,
|
|
53
26
|
readOnly,
|
|
@@ -84,6 +57,6 @@ function useNormalizedInputProps(_ref) {
|
|
|
84
57
|
}, warnText);
|
|
85
58
|
}
|
|
86
59
|
return normalizedProps;
|
|
87
|
-
}
|
|
60
|
+
};
|
|
88
61
|
|
|
89
62
|
export { useNormalizedInputProps };
|
|
@@ -85,23 +85,34 @@ const Button = /*#__PURE__*/React__default["default"].forwardRef((props, ref) =>
|
|
|
85
85
|
if (tooltipPosition === 'right' || tooltipPosition === 'left') {
|
|
86
86
|
align = tooltipPosition;
|
|
87
87
|
}
|
|
88
|
-
return
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
size
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
88
|
+
return (
|
|
89
|
+
/*#__PURE__*/
|
|
90
|
+
// @ts-expect-error - `IconButton` does not support all `size`s that
|
|
91
|
+
// `Button` supports.
|
|
92
|
+
//
|
|
93
|
+
// TODO: What should be done here?
|
|
94
|
+
// 1. Should the `IconButton` not be rendered if the `size` is not
|
|
95
|
+
// supported?
|
|
96
|
+
// 2. Should an error be thrown?
|
|
97
|
+
// 3. Something else?
|
|
98
|
+
React__default["default"].createElement(index.IconButton, _rollupPluginBabelHelpers["extends"]({}, rest, {
|
|
99
|
+
ref: ref,
|
|
100
|
+
as: as,
|
|
101
|
+
align: align,
|
|
102
|
+
label: iconDescription,
|
|
103
|
+
kind: kind,
|
|
104
|
+
size: size,
|
|
105
|
+
highContrast: tooltipHighContrast,
|
|
106
|
+
dropShadow: tooltipDropShadow,
|
|
107
|
+
onMouseEnter: onMouseEnter,
|
|
108
|
+
onMouseLeave: onMouseLeave,
|
|
109
|
+
onFocus: onFocus,
|
|
110
|
+
onBlur: onBlur,
|
|
111
|
+
autoAlign: autoAlign,
|
|
112
|
+
onClick: events.composeEventHandlers([onClick, handleClick]),
|
|
113
|
+
renderIcon: iconOnlyImage ? null : ButtonImageElement // avoid doubling the icon.
|
|
114
|
+
}), iconOnlyImage ?? children)
|
|
115
|
+
);
|
|
105
116
|
}
|
|
106
117
|
});
|
|
107
118
|
Button.displayName = 'Button';
|
|
@@ -50,6 +50,8 @@ const ButtonBase = /*#__PURE__*/React__default["default"].forwardRef(function Bu
|
|
|
50
50
|
// TODO: V12 - Remove this class
|
|
51
51
|
[`${prefix}--btn--md`]: size === 'md' && !isExpressive,
|
|
52
52
|
// TODO: V12 - Remove this class
|
|
53
|
+
[`${prefix}--btn--lg`]: size === 'lg' && !isExpressive,
|
|
54
|
+
// TODO: V12 - Remove this class
|
|
53
55
|
[`${prefix}--btn--xl`]: size === 'xl',
|
|
54
56
|
// TODO: V12 - Remove this class
|
|
55
57
|
[`${prefix}--btn--2xl`]: size === '2xl',
|