@itwin/itwinui-react 3.0.10 → 3.1.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 (56) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +1 -1
  3. package/cjs/core/ButtonGroup/ButtonGroup.d.ts +2 -0
  4. package/cjs/core/ButtonGroup/ButtonGroup.js +26 -21
  5. package/cjs/core/Buttons/IconButton.d.ts +6 -0
  6. package/cjs/core/Buttons/IconButton.js +4 -2
  7. package/cjs/core/Carousel/Carousel.d.ts +110 -2
  8. package/cjs/core/Carousel/CarouselNavigation.d.ts +110 -2
  9. package/cjs/core/ComboBox/ComboBoxInput.js +17 -5
  10. package/cjs/core/FileUpload/FileUpload.d.ts +3 -1
  11. package/cjs/core/FileUpload/FileUpload.js +5 -8
  12. package/cjs/core/InputWithDecorations/InputWithDecorations.d.ts +55 -1
  13. package/cjs/core/Popover/Popover.d.ts +22 -14
  14. package/cjs/core/Popover/Popover.js +14 -2
  15. package/cjs/core/Table/Table.js +28 -2
  16. package/cjs/core/Tabs/Tabs.js +23 -3
  17. package/cjs/core/ThemeProvider/ThemeProvider.js +44 -21
  18. package/cjs/core/Tile/Tile.d.ts +61 -1
  19. package/cjs/core/Tooltip/Tooltip.js +6 -2
  20. package/cjs/core/Tree/Tree.d.ts +6 -0
  21. package/cjs/core/Tree/Tree.js +4 -3
  22. package/cjs/core/Tree/TreeContext.d.ts +4 -0
  23. package/cjs/core/Tree/TreeNodeExpander.js +4 -1
  24. package/cjs/core/utils/icons/SvgChevronRightSmall.d.ts +2 -0
  25. package/cjs/core/utils/icons/SvgChevronRightSmall.js +15 -0
  26. package/cjs/core/utils/icons/index.d.ts +1 -0
  27. package/cjs/core/utils/icons/index.js +1 -0
  28. package/cjs/styles.js +2 -2
  29. package/esm/core/ButtonGroup/ButtonGroup.d.ts +2 -0
  30. package/esm/core/ButtonGroup/ButtonGroup.js +25 -20
  31. package/esm/core/Buttons/IconButton.d.ts +6 -0
  32. package/esm/core/Buttons/IconButton.js +4 -2
  33. package/esm/core/Carousel/Carousel.d.ts +110 -2
  34. package/esm/core/Carousel/CarouselNavigation.d.ts +110 -2
  35. package/esm/core/ComboBox/ComboBoxInput.js +17 -5
  36. package/esm/core/FileUpload/FileUpload.d.ts +3 -1
  37. package/esm/core/FileUpload/FileUpload.js +6 -9
  38. package/esm/core/InputWithDecorations/InputWithDecorations.d.ts +55 -1
  39. package/esm/core/Popover/Popover.d.ts +22 -14
  40. package/esm/core/Popover/Popover.js +15 -3
  41. package/esm/core/Table/Table.js +28 -2
  42. package/esm/core/Tabs/Tabs.js +23 -3
  43. package/esm/core/ThemeProvider/ThemeProvider.js +45 -22
  44. package/esm/core/Tile/Tile.d.ts +61 -1
  45. package/esm/core/Tooltip/Tooltip.js +6 -2
  46. package/esm/core/Tree/Tree.d.ts +6 -0
  47. package/esm/core/Tree/Tree.js +4 -3
  48. package/esm/core/Tree/TreeContext.d.ts +4 -0
  49. package/esm/core/Tree/TreeNodeExpander.js +5 -2
  50. package/esm/core/utils/icons/SvgChevronRightSmall.d.ts +2 -0
  51. package/esm/core/utils/icons/SvgChevronRightSmall.js +10 -0
  52. package/esm/core/utils/icons/index.d.ts +1 -0
  53. package/esm/core/utils/icons/index.js +1 -0
  54. package/esm/styles.js +2 -2
  55. package/package.json +4 -4
  56. package/styles.css +15 -15
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1731](https://github.com/iTwin/iTwinUI/pull/1731): ThemeProvider will now correctly inherit theme changes from a v2 ancestor.
8
+ - [#1710](https://github.com/iTwin/iTwinUI/pull/1710): Added new `middleware` and `positionReference` props to `Popover` for more control over the positioning logic.
9
+ - [#1676](https://github.com/iTwin/iTwinUI/pull/1676): Added `size="small` prop to `Tree`, and decreased indentations on default size tree.
10
+ - [#1707](https://github.com/iTwin/iTwinUI/pull/1707): `FileUpload`'s `onFileDropped` prop will now expose the underlying drop event as the second argument. This can be useful for accessing information about the directory structure.
11
+ - [#1709](https://github.com/iTwin/iTwinUI/pull/1709): `IconButton`s inside a vertical `ButtonGroup` will now show tooltips on the right side by default, to avoid obscuring adjacent buttons in the group. The behavior of these tooltips can also be customized using the new `labelProps` prop, which can contain `labelProps.placement`, etc.
12
+
13
+ ### Patch Changes
14
+
15
+ - [#1733](https://github.com/iTwin/iTwinUI/pull/1733): Fixed an overflow-related layout shift in vertical `Tabs`.
16
+ - [#1725](https://github.com/iTwin/iTwinUI/pull/1725): Table is now scrollable horizontally even when no rows are present.
17
+
18
+ ## 3.0.11
19
+
20
+ ### Patch Changes
21
+
22
+ - [#1716](https://github.com/iTwin/iTwinUI/pull/1716): Truncate the `select-tag` when only one tag is present in `select-tag-container`
23
+
3
24
  ## 3.0.10
4
25
 
5
26
  ### Patch Changes
package/README.md CHANGED
@@ -78,7 +78,7 @@ const Page = () => (
78
78
 
79
79
  Check out this template for a live interactive demo:
80
80
 
81
- [![Edit in CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/s/github/iTwin/iTwinUI/tree/main/cra-sandbox?file=/src/App.tsx)
81
+ [![Edit in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.io/github/iTwin/iTwinUI/tree/main/minimal-sandbox?file=/src/App.tsx)
82
82
 
83
83
  ---
84
84
 
@@ -1,5 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import type { PolymorphicForwardRefComponent } from '../utils/index.js';
3
+ /** This context is used for letting descendant IconButtons know the ButtonGroup's orientation. */
4
+ export declare const ButtonGroupContext: React.Context<string | undefined>;
3
5
  type ButtonGroupProps = {
4
6
  /**
5
7
  * Buttons in the ButtonGroup.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ButtonGroup = void 0;
3
+ exports.ButtonGroup = exports.ButtonGroupContext = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  /*---------------------------------------------------------------------------------------------
6
6
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
@@ -10,6 +10,10 @@ const React = tslib_1.__importStar(require("react"));
10
10
  const classnames_1 = tslib_1.__importDefault(require("classnames"));
11
11
  const index_js_1 = require("../utils/index.js");
12
12
  const react_1 = require("@floating-ui/react");
13
+ // ----------------------------------------------------------------------------
14
+ /** This context is used for letting descendant IconButtons know the ButtonGroup's orientation. */
15
+ exports.ButtonGroupContext = React.createContext(undefined);
16
+ exports.ButtonGroupContext.displayName = 'ButtonGroupContext';
13
17
  /**
14
18
  * Group buttons together for common actions.
15
19
  * Handles responsive overflow when the `overflowButton` prop is specified.
@@ -44,25 +48,26 @@ exports.ButtonGroup = React.forwardRef((props, ref) => {
44
48
  const [overflowRef, visibleCount] = (0, index_js_1.useOverflow)(items, !overflowButton, orientation);
45
49
  const refs = (0, index_js_1.useMergedRefs)(overflowRef, ref);
46
50
  return (React.createElement(react_1.FloatingDelayGroup, { delay: { open: 50, close: 250 } },
47
- React.createElement(index_js_1.Box, { className: (0, classnames_1.default)('iui-button-group', {
48
- 'iui-button-group-overflow-x': !!overflowButton && orientation === 'horizontal',
49
- }, className), "data-iui-orientation": orientation === 'vertical' ? orientation : undefined, ref: refs, ...rest }, (() => {
50
- if (!(visibleCount < items.length)) {
51
- return items;
52
- }
53
- const overflowStart = overflowPlacement === 'start'
54
- ? items.length - visibleCount
55
- : visibleCount - 1;
56
- return (React.createElement(React.Fragment, null,
57
- overflowButton &&
58
- overflowPlacement === 'start' &&
59
- overflowButton(overflowStart),
60
- overflowPlacement === 'start'
61
- ? items.slice(overflowStart + 1)
62
- : items.slice(0, Math.max(0, overflowStart)),
63
- overflowButton &&
64
- overflowPlacement === 'end' &&
65
- overflowButton(overflowStart)));
66
- })())));
51
+ React.createElement(exports.ButtonGroupContext.Provider, { value: orientation },
52
+ React.createElement(index_js_1.Box, { className: (0, classnames_1.default)('iui-button-group', {
53
+ 'iui-button-group-overflow-x': !!overflowButton && orientation === 'horizontal',
54
+ }, className), "data-iui-orientation": orientation === 'vertical' ? orientation : undefined, ref: refs, ...rest }, (() => {
55
+ if (!(visibleCount < items.length)) {
56
+ return items;
57
+ }
58
+ const overflowStart = overflowPlacement === 'start'
59
+ ? items.length - visibleCount
60
+ : visibleCount - 1;
61
+ return (React.createElement(React.Fragment, null,
62
+ overflowButton &&
63
+ overflowPlacement === 'start' &&
64
+ overflowButton(overflowStart),
65
+ overflowPlacement === 'start'
66
+ ? items.slice(overflowStart + 1)
67
+ : items.slice(0, Math.max(0, overflowStart)),
68
+ overflowButton &&
69
+ overflowPlacement === 'end' &&
70
+ overflowButton(overflowStart)));
71
+ })()))));
67
72
  });
68
73
  exports.default = exports.ButtonGroup;
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { Tooltip } from '../Tooltip/Tooltip.js';
2
3
  import type { ButtonProps } from './Button.js';
3
4
  import type { PolymorphicForwardRefComponent } from '../utils/index.js';
4
5
  export type IconButtonProps = {
@@ -11,6 +12,11 @@ export type IconButtonProps = {
11
12
  * Name of the button, shown in a tooltip and exposed to assistive technologies.
12
13
  */
13
14
  label?: React.ReactNode;
15
+ /**
16
+ * Props passed to the Tooltip that contains the `label`.
17
+ * Can be used for customizing the tooltip's `placement`, etc.
18
+ */
19
+ labelProps?: Omit<React.ComponentPropsWithoutRef<typeof Tooltip>, 'content' | 'reference' | 'ariaStrategy' | 'children'>;
14
20
  /**
15
21
  * Passes props to IconButton icon.
16
22
  */
@@ -11,6 +11,7 @@ const React = tslib_1.__importStar(require("react"));
11
11
  const index_js_1 = require("../utils/index.js");
12
12
  const Tooltip_js_1 = require("../Tooltip/Tooltip.js");
13
13
  const VisuallyHidden_js_1 = require("../VisuallyHidden/VisuallyHidden.js");
14
+ const ButtonGroup_js_1 = require("../ButtonGroup/ButtonGroup.js");
14
15
  /**
15
16
  * Icon button
16
17
  * @example
@@ -19,10 +20,11 @@ const VisuallyHidden_js_1 = require("../VisuallyHidden/VisuallyHidden.js");
19
20
  * <IconButton label='Add' styleType='borderless'><SvgAdd /></IconButton>
20
21
  */
21
22
  exports.IconButton = React.forwardRef((props, ref) => {
22
- const { isActive, children, styleType = 'default', size, className, label, iconProps, ...rest } = props;
23
+ const { isActive, children, styleType = 'default', size, className, label, iconProps, labelProps, ...rest } = props;
24
+ const buttonGroupOrientation = React.useContext(ButtonGroup_js_1.ButtonGroupContext);
23
25
  const button = (React.createElement(index_js_1.ButtonBase, { ref: ref, className: (0, classnames_1.default)('iui-button', className), "data-iui-variant": styleType !== 'default' ? styleType : undefined, "data-iui-size": size, "data-iui-active": isActive, "aria-pressed": isActive, ...rest },
24
26
  React.createElement(index_js_1.Box, { as: 'span', "aria-hidden": true, ...iconProps, className: (0, classnames_1.default)('iui-button-icon', iconProps?.className) }, children),
25
27
  label ? React.createElement(VisuallyHidden_js_1.VisuallyHidden, null, label) : null));
26
- return label ? (React.createElement(Tooltip_js_1.Tooltip, { content: label, ariaStrategy: 'none' }, button)) : (button);
28
+ return label ? (React.createElement(Tooltip_js_1.Tooltip, { placement: buttonGroupOrientation === 'vertical' ? 'right' : 'top', ...labelProps, content: label, ariaStrategy: 'none' }, button)) : (button);
27
29
  });
28
30
  exports.default = exports.IconButton;
@@ -42,18 +42,126 @@ export declare const Carousel: PolymorphicForwardRefComponent<"section", Carouse
42
42
  Navigation: PolymorphicForwardRefComponent<"div", {}> & {
43
43
  PreviousButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
44
44
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
45
- }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "isActive" | "iconProps"> & {
45
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "isActive" | "iconProps"> & {
46
46
  isActive?: boolean | undefined;
47
47
  label?: React.ReactNode;
48
+ labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
49
+ ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
50
+ }, "as" | "children" | "content" | "portal" | keyof {
51
+ placement?: import("@floating-ui/utils").Placement | undefined;
52
+ visible?: boolean | undefined;
53
+ onVisibleChange?: ((visible: boolean) => void) | undefined;
54
+ autoUpdateOptions?: {
55
+ ancestorScroll?: boolean | undefined;
56
+ ancestorResize?: boolean | undefined;
57
+ elementResize?: boolean | undefined;
58
+ animationFrame?: boolean | undefined;
59
+ layoutShift?: boolean | undefined;
60
+ } | undefined;
61
+ middleware?: {
62
+ offset?: number | undefined;
63
+ flip?: boolean | undefined;
64
+ shift?: boolean | undefined;
65
+ size?: boolean | undefined;
66
+ autoPlacement?: boolean | undefined;
67
+ hide?: boolean | undefined;
68
+ inline?: boolean | undefined;
69
+ } | undefined;
70
+ reference?: HTMLElement | null | undefined;
71
+ ariaStrategy?: "label" | "description" | "none" | undefined;
72
+ id?: string | undefined;
73
+ }> & {
74
+ content: React.ReactNode;
75
+ children?: React.ReactNode;
76
+ } & import("../utils/index.js").PortalProps & {
77
+ placement?: import("@floating-ui/utils").Placement | undefined;
78
+ visible?: boolean | undefined;
79
+ onVisibleChange?: ((visible: boolean) => void) | undefined;
80
+ autoUpdateOptions?: {
81
+ ancestorScroll?: boolean | undefined;
82
+ ancestorResize?: boolean | undefined;
83
+ elementResize?: boolean | undefined;
84
+ animationFrame?: boolean | undefined;
85
+ layoutShift?: boolean | undefined;
86
+ } | undefined;
87
+ middleware?: {
88
+ offset?: number | undefined;
89
+ flip?: boolean | undefined;
90
+ shift?: boolean | undefined;
91
+ size?: boolean | undefined;
92
+ autoPlacement?: boolean | undefined;
93
+ hide?: boolean | undefined;
94
+ inline?: boolean | undefined;
95
+ } | undefined;
96
+ reference?: HTMLElement | null | undefined;
97
+ ariaStrategy?: "label" | "description" | "none" | undefined;
98
+ id?: string | undefined;
99
+ } & {
100
+ as?: "div" | undefined;
101
+ }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
48
102
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
49
103
  } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
50
104
  as?: "button" | undefined;
51
105
  }>;
52
106
  NextButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
53
107
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
54
- }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "isActive" | "iconProps"> & {
108
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "isActive" | "iconProps"> & {
55
109
  isActive?: boolean | undefined;
56
110
  label?: React.ReactNode;
111
+ labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
112
+ ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
113
+ }, "as" | "children" | "content" | "portal" | keyof {
114
+ placement?: import("@floating-ui/utils").Placement | undefined;
115
+ visible?: boolean | undefined;
116
+ onVisibleChange?: ((visible: boolean) => void) | undefined;
117
+ autoUpdateOptions?: {
118
+ ancestorScroll?: boolean | undefined;
119
+ ancestorResize?: boolean | undefined;
120
+ elementResize?: boolean | undefined;
121
+ animationFrame?: boolean | undefined;
122
+ layoutShift?: boolean | undefined;
123
+ } | undefined;
124
+ middleware?: {
125
+ offset?: number | undefined;
126
+ flip?: boolean | undefined;
127
+ shift?: boolean | undefined;
128
+ size?: boolean | undefined;
129
+ autoPlacement?: boolean | undefined;
130
+ hide?: boolean | undefined;
131
+ inline?: boolean | undefined;
132
+ } | undefined;
133
+ reference?: HTMLElement | null | undefined;
134
+ ariaStrategy?: "label" | "description" | "none" | undefined;
135
+ id?: string | undefined;
136
+ }> & {
137
+ content: React.ReactNode;
138
+ children?: React.ReactNode;
139
+ } & import("../utils/index.js").PortalProps & {
140
+ placement?: import("@floating-ui/utils").Placement | undefined;
141
+ visible?: boolean | undefined;
142
+ onVisibleChange?: ((visible: boolean) => void) | undefined;
143
+ autoUpdateOptions?: {
144
+ ancestorScroll?: boolean | undefined;
145
+ ancestorResize?: boolean | undefined;
146
+ elementResize?: boolean | undefined;
147
+ animationFrame?: boolean | undefined;
148
+ layoutShift?: boolean | undefined;
149
+ } | undefined;
150
+ middleware?: {
151
+ offset?: number | undefined;
152
+ flip?: boolean | undefined;
153
+ shift?: boolean | undefined;
154
+ size?: boolean | undefined;
155
+ autoPlacement?: boolean | undefined;
156
+ hide?: boolean | undefined;
157
+ inline?: boolean | undefined;
158
+ } | undefined;
159
+ reference?: HTMLElement | null | undefined;
160
+ ariaStrategy?: "label" | "description" | "none" | undefined;
161
+ id?: string | undefined;
162
+ } & {
163
+ as?: "div" | undefined;
164
+ }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
57
165
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
58
166
  } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
59
167
  as?: "button" | undefined;
@@ -9,18 +9,126 @@ import type { PolymorphicForwardRefComponent } from '../utils/index.js';
9
9
  export declare const CarouselNavigation: PolymorphicForwardRefComponent<"div", {}> & {
10
10
  PreviousButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
11
11
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
12
- }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "isActive" | "iconProps"> & {
12
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "isActive" | "iconProps"> & {
13
13
  isActive?: boolean | undefined;
14
14
  label?: React.ReactNode;
15
+ labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
16
+ ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
17
+ }, "as" | "children" | "content" | "portal" | keyof {
18
+ placement?: import("@floating-ui/utils").Placement | undefined;
19
+ visible?: boolean | undefined;
20
+ onVisibleChange?: ((visible: boolean) => void) | undefined;
21
+ autoUpdateOptions?: {
22
+ ancestorScroll?: boolean | undefined;
23
+ ancestorResize?: boolean | undefined;
24
+ elementResize?: boolean | undefined;
25
+ animationFrame?: boolean | undefined;
26
+ layoutShift?: boolean | undefined;
27
+ } | undefined;
28
+ middleware?: {
29
+ offset?: number | undefined;
30
+ flip?: boolean | undefined;
31
+ shift?: boolean | undefined;
32
+ size?: boolean | undefined;
33
+ autoPlacement?: boolean | undefined;
34
+ hide?: boolean | undefined;
35
+ inline?: boolean | undefined;
36
+ } | undefined;
37
+ reference?: HTMLElement | null | undefined;
38
+ ariaStrategy?: "label" | "description" | "none" | undefined;
39
+ id?: string | undefined;
40
+ }> & {
41
+ content: React.ReactNode;
42
+ children?: React.ReactNode;
43
+ } & import("../utils/index.js").PortalProps & {
44
+ placement?: import("@floating-ui/utils").Placement | undefined;
45
+ visible?: boolean | undefined;
46
+ onVisibleChange?: ((visible: boolean) => void) | undefined;
47
+ autoUpdateOptions?: {
48
+ ancestorScroll?: boolean | undefined;
49
+ ancestorResize?: boolean | undefined;
50
+ elementResize?: boolean | undefined;
51
+ animationFrame?: boolean | undefined;
52
+ layoutShift?: boolean | undefined;
53
+ } | undefined;
54
+ middleware?: {
55
+ offset?: number | undefined;
56
+ flip?: boolean | undefined;
57
+ shift?: boolean | undefined;
58
+ size?: boolean | undefined;
59
+ autoPlacement?: boolean | undefined;
60
+ hide?: boolean | undefined;
61
+ inline?: boolean | undefined;
62
+ } | undefined;
63
+ reference?: HTMLElement | null | undefined;
64
+ ariaStrategy?: "label" | "description" | "none" | undefined;
65
+ id?: string | undefined;
66
+ } & {
67
+ as?: "div" | undefined;
68
+ }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
15
69
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
16
70
  } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
17
71
  as?: "button" | undefined;
18
72
  }>;
19
73
  NextButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
20
74
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
21
- }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "isActive" | "iconProps"> & {
75
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "isActive" | "iconProps"> & {
22
76
  isActive?: boolean | undefined;
23
77
  label?: React.ReactNode;
78
+ labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
79
+ ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
80
+ }, "as" | "children" | "content" | "portal" | keyof {
81
+ placement?: import("@floating-ui/utils").Placement | undefined;
82
+ visible?: boolean | undefined;
83
+ onVisibleChange?: ((visible: boolean) => void) | undefined;
84
+ autoUpdateOptions?: {
85
+ ancestorScroll?: boolean | undefined;
86
+ ancestorResize?: boolean | undefined;
87
+ elementResize?: boolean | undefined;
88
+ animationFrame?: boolean | undefined;
89
+ layoutShift?: boolean | undefined;
90
+ } | undefined;
91
+ middleware?: {
92
+ offset?: number | undefined;
93
+ flip?: boolean | undefined;
94
+ shift?: boolean | undefined;
95
+ size?: boolean | undefined;
96
+ autoPlacement?: boolean | undefined;
97
+ hide?: boolean | undefined;
98
+ inline?: boolean | undefined;
99
+ } | undefined;
100
+ reference?: HTMLElement | null | undefined;
101
+ ariaStrategy?: "label" | "description" | "none" | undefined;
102
+ id?: string | undefined;
103
+ }> & {
104
+ content: React.ReactNode;
105
+ children?: React.ReactNode;
106
+ } & import("../utils/index.js").PortalProps & {
107
+ placement?: import("@floating-ui/utils").Placement | undefined;
108
+ visible?: boolean | undefined;
109
+ onVisibleChange?: ((visible: boolean) => void) | undefined;
110
+ autoUpdateOptions?: {
111
+ ancestorScroll?: boolean | undefined;
112
+ ancestorResize?: boolean | undefined;
113
+ elementResize?: boolean | undefined;
114
+ animationFrame?: boolean | undefined;
115
+ layoutShift?: boolean | undefined;
116
+ } | undefined;
117
+ middleware?: {
118
+ offset?: number | undefined;
119
+ flip?: boolean | undefined;
120
+ shift?: boolean | undefined;
121
+ size?: boolean | undefined;
122
+ autoPlacement?: boolean | undefined;
123
+ hide?: boolean | undefined;
124
+ inline?: boolean | undefined;
125
+ } | undefined;
126
+ reference?: HTMLElement | null | undefined;
127
+ ariaStrategy?: "label" | "description" | "none" | undefined;
128
+ id?: string | undefined;
129
+ } & {
130
+ as?: "div" | undefined;
131
+ }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
24
132
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
25
133
  } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
26
134
  as?: "button" | undefined;
@@ -12,7 +12,7 @@ const index_js_1 = require("../utils/index.js");
12
12
  const ComboBoxMultipleContainer_js_1 = require("./ComboBoxMultipleContainer.js");
13
13
  const helpers_js_1 = require("./helpers.js");
14
14
  exports.ComboBoxInput = React.forwardRef((props, forwardedRef) => {
15
- const { onKeyDown: onKeyDownProp, onClick: onClickProp, selectTags, size, ...rest } = props;
15
+ const { selectTags, size, ...rest } = props;
16
16
  const { isOpen, id, focusedIndex, enableVirtualization, multiple, onClickHandler, popover, show, hide, } = (0, index_js_1.useSafeContext)(helpers_js_1.ComboBoxStateContext);
17
17
  const dispatch = (0, index_js_1.useSafeContext)(helpers_js_1.ComboBoxActionContext);
18
18
  const { inputRef, menuRef, optionsExtraInfoRef } = (0, index_js_1.useSafeContext)(helpers_js_1.ComboBoxRefsContext);
@@ -125,21 +125,33 @@ exports.ComboBoxInput = React.forwardRef((props, forwardedRef) => {
125
125
  show,
126
126
  hide,
127
127
  ]);
128
+ /**
129
+ * This temporarily stores the state of `isOpen` before click event starts and resets it later.
130
+ * It is necessary because `isOpen` may have changed during the process of the click,
131
+ * e.g. because of focus, which could cause the menu to close immediately after opening.
132
+ */
133
+ const wasOpenBeforeClick = React.useRef(false);
134
+ const handlePointerDown = React.useCallback(() => {
135
+ wasOpenBeforeClick.current = isOpen;
136
+ }, [isOpen]);
128
137
  const handleClick = React.useCallback(() => {
129
- if (!isOpen) {
138
+ if (!wasOpenBeforeClick.current) {
130
139
  show();
131
140
  }
132
141
  else {
133
142
  hide();
134
143
  }
135
- }, [hide, isOpen, show]);
144
+ wasOpenBeforeClick.current = false;
145
+ }, [hide, show]);
136
146
  const [tagContainerWidthRef, tagContainerWidth] = (0, index_js_1.useContainerWidth)();
137
147
  return (React.createElement(React.Fragment, null,
138
- React.createElement(Input_js_1.Input, { ref: refs, onClick: (0, index_js_1.mergeEventHandlers)(onClickProp, handleClick), "aria-expanded": isOpen, "aria-activedescendant": isOpen && focusedIndex != undefined && focusedIndex > -1
148
+ React.createElement(Input_js_1.Input, { ref: refs, "aria-expanded": isOpen, "aria-activedescendant": isOpen && focusedIndex != undefined && focusedIndex > -1
139
149
  ? getIdFromIndex(focusedIndex)
140
150
  : undefined, role: 'combobox', "aria-controls": isOpen ? `${id}-list` : undefined, "aria-autocomplete": 'list', spellCheck: false, autoCapitalize: 'none', autoCorrect: 'off', style: multiple ? { paddingInlineStart: tagContainerWidth + 18 } : {}, "aria-describedby": multiple ? `${id}-selected-live` : undefined, size: size, ...popover.getReferenceProps({
141
- onKeyDown: (0, index_js_1.mergeEventHandlers)(onKeyDownProp, handleKeyDown),
142
151
  ...rest,
152
+ onPointerDown: (0, index_js_1.mergeEventHandlers)(props.onPointerDown, handlePointerDown),
153
+ onClick: (0, index_js_1.mergeEventHandlers)(props.onClick, handleClick),
154
+ onKeyDown: (0, index_js_1.mergeEventHandlers)(props.onKeyDown, handleKeyDown),
143
155
  }) }),
144
156
  multiple && selectTags ? (React.createElement(ComboBoxMultipleContainer_js_1.ComboBoxMultipleContainer, { ref: tagContainerWidthRef, selectedItems: selectTags, id: `${id}-selected-live` })) : null));
145
157
  });
@@ -8,8 +8,10 @@ type FileUploadProps = {
8
8
  dragContent?: React.ReactNode;
9
9
  /**
10
10
  * Callback fired when files are dropped onto the component.
11
+ *
12
+ * The first argument is the `files` list, and the second argument is the underlying "drop" event.
11
13
  */
12
- onFileDropped: (files: FileList) => void;
14
+ onFileDropped: (files: FileList, event: React.DragEvent) => void;
13
15
  /**
14
16
  * Component to wrap `FileUpload` around.
15
17
  * Either pass `FileUploadCard` (for default state) or a different component to wrap.
@@ -16,11 +16,9 @@ const index_js_1 = require("../utils/index.js");
16
16
  * <FileUpload onFileDropped={console.log}><FileUploadCard /></FileUpload>
17
17
  * <FileUpload dragContent='Drop file here' onFileDropped={console.log}><Textarea /></FileUpload>
18
18
  */
19
- exports.FileUpload = React.forwardRef((props, ref) => {
20
- const { dragContent, children, onFileDropped, className, contentProps, ...rest } = props;
19
+ exports.FileUpload = React.forwardRef((props, forwardedRef) => {
20
+ const { dragContent, children, onFileDropped, contentProps, ...rest } = props;
21
21
  const [isDragActive, setIsDragActive] = React.useState(false);
22
- const fileUploadRef = React.useRef(null);
23
- const refs = (0, index_js_1.useMergedRefs)(fileUploadRef, ref);
24
22
  const onDragOverHandler = (e) => {
25
23
  e.preventDefault();
26
24
  e.stopPropagation();
@@ -37,8 +35,7 @@ exports.FileUpload = React.forwardRef((props, ref) => {
37
35
  e.preventDefault();
38
36
  e.stopPropagation();
39
37
  // only set inactive if secondary target is outside the component
40
- if (isDragActive &&
41
- !fileUploadRef.current?.contains(e.relatedTarget)) {
38
+ if (isDragActive && !e.currentTarget?.contains(e.relatedTarget)) {
42
39
  setIsDragActive(false);
43
40
  }
44
41
  };
@@ -47,10 +44,10 @@ exports.FileUpload = React.forwardRef((props, ref) => {
47
44
  e.stopPropagation();
48
45
  if (isDragActive) {
49
46
  setIsDragActive(false);
50
- onFileDropped(e.dataTransfer?.files);
47
+ onFileDropped(e.dataTransfer?.files, e);
51
48
  }
52
49
  };
53
- return (React.createElement(index_js_1.Box, { className: (0, classnames_1.default)('iui-file-upload', { 'iui-drag': isDragActive }, className), onDragEnter: onDragEnterHandler, onDragOver: onDragOverHandler, onDragLeave: onDragLeaveHandler, onDrop: onDropHandler, ref: refs, ...rest },
50
+ return (React.createElement(index_js_1.Box, { ...rest, className: (0, classnames_1.default)('iui-file-upload', { 'iui-drag': isDragActive }, props?.className), ref: forwardedRef, onDragEnter: (0, index_js_1.mergeEventHandlers)(props.onDragEnter, onDragEnterHandler), onDragOver: (0, index_js_1.mergeEventHandlers)(props.onDragOver, onDragOverHandler), onDragLeave: (0, index_js_1.mergeEventHandlers)(props.onDragLeave, onDragLeaveHandler), onDrop: (0, index_js_1.mergeEventHandlers)(props.onDrop, onDropHandler) },
54
51
  dragContent ? (children) : (React.createElement(index_js_1.Box, { as: 'div', ...contentProps, className: (0, classnames_1.default)('iui-content', contentProps?.className) }, children)),
55
52
  dragContent && (React.createElement(index_js_1.Box, { as: 'div', ...contentProps, className: (0, classnames_1.default)('iui-content', contentProps?.className) }, dragContent))));
56
53
  });
@@ -29,9 +29,63 @@ export declare const InputWithDecorations: PolymorphicForwardRefComponent<"div",
29
29
  */
30
30
  Button: PolymorphicForwardRefComponent<"span", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
31
31
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
32
- }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "isActive" | "iconProps"> & {
32
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "isActive" | "iconProps"> & {
33
33
  isActive?: boolean | undefined;
34
34
  label?: React.ReactNode;
35
+ labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
36
+ ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
37
+ }, "as" | "children" | "content" | "portal" | keyof {
38
+ placement?: import("@floating-ui/utils").Placement | undefined;
39
+ visible?: boolean | undefined;
40
+ onVisibleChange?: ((visible: boolean) => void) | undefined;
41
+ autoUpdateOptions?: {
42
+ ancestorScroll?: boolean | undefined;
43
+ ancestorResize?: boolean | undefined;
44
+ elementResize?: boolean | undefined;
45
+ animationFrame?: boolean | undefined;
46
+ layoutShift?: boolean | undefined;
47
+ } | undefined;
48
+ middleware?: {
49
+ offset?: number | undefined;
50
+ flip?: boolean | undefined;
51
+ shift?: boolean | undefined;
52
+ size?: boolean | undefined;
53
+ autoPlacement?: boolean | undefined;
54
+ hide?: boolean | undefined;
55
+ inline?: boolean | undefined;
56
+ } | undefined;
57
+ reference?: HTMLElement | null | undefined;
58
+ ariaStrategy?: "label" | "description" | "none" | undefined;
59
+ id?: string | undefined;
60
+ }> & {
61
+ content: React.ReactNode;
62
+ children?: React.ReactNode;
63
+ } & import("../utils/index.js").PortalProps & {
64
+ placement?: import("@floating-ui/utils").Placement | undefined;
65
+ visible?: boolean | undefined;
66
+ onVisibleChange?: ((visible: boolean) => void) | undefined;
67
+ autoUpdateOptions?: {
68
+ ancestorScroll?: boolean | undefined;
69
+ ancestorResize?: boolean | undefined;
70
+ elementResize?: boolean | undefined;
71
+ animationFrame?: boolean | undefined;
72
+ layoutShift?: boolean | undefined;
73
+ } | undefined;
74
+ middleware?: {
75
+ offset?: number | undefined;
76
+ flip?: boolean | undefined;
77
+ shift?: boolean | undefined;
78
+ size?: boolean | undefined;
79
+ autoPlacement?: boolean | undefined;
80
+ hide?: boolean | undefined;
81
+ inline?: boolean | undefined;
82
+ } | undefined;
83
+ reference?: HTMLElement | null | undefined;
84
+ ariaStrategy?: "label" | "description" | "none" | undefined;
85
+ id?: string | undefined;
86
+ } & {
87
+ as?: "div" | undefined;
88
+ }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
35
89
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
36
90
  } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
37
91
  as?: "button" | undefined;
@@ -23,6 +23,21 @@ type PopoverOptions = {
23
23
  * @default true
24
24
  */
25
25
  closeOnOutsideClick?: boolean;
26
+ /**
27
+ * Middleware options.
28
+ *
29
+ * By default, `flip` and `shift` are enabled.
30
+ *
31
+ * @see https://floating-ui.com/docs/middleware
32
+ */
33
+ middleware?: {
34
+ offset?: number;
35
+ flip?: boolean;
36
+ shift?: boolean;
37
+ autoPlacement?: boolean;
38
+ hide?: boolean;
39
+ inline?: boolean;
40
+ };
26
41
  };
27
42
  type PopoverInternalProps = {
28
43
  /**
@@ -43,19 +58,6 @@ type PopoverInternalProps = {
43
58
  animationFrame?: boolean;
44
59
  layoutShift?: boolean;
45
60
  };
46
- /**
47
- * Middleware options.
48
- *
49
- * @see https://floating-ui.com/docs/offset
50
- */
51
- middleware?: {
52
- offset?: number;
53
- flip?: boolean;
54
- shift?: boolean;
55
- autoPlacement?: boolean;
56
- hide?: boolean;
57
- inline?: boolean;
58
- };
59
61
  /**
60
62
  * By default, the popover will only open on click.
61
63
  * `hover` and `focus` can be manually specified as triggers.
@@ -96,7 +98,7 @@ export declare const usePopover: (options: PopoverOptions & PopoverInternalProps
96
98
  update: () => void;
97
99
  floatingStyles: React.CSSProperties;
98
100
  open: boolean;
99
- onOpenChange: (open: boolean, event?: Event | undefined) => void;
101
+ onOpenChange: (open: boolean, event?: Event | undefined, reason?: import("@floating-ui/react").OpenChangeReason | undefined) => void;
100
102
  events: import("@floating-ui/react").FloatingEvents;
101
103
  dataRef: React.MutableRefObject<import("@floating-ui/react").ContextData>;
102
104
  nodeId: string | undefined;
@@ -125,6 +127,12 @@ type PopoverPublicProps = {
125
127
  * @default false
126
128
  */
127
129
  applyBackground?: boolean;
130
+ /**
131
+ * This is used to position the popover relative to a different element than the trigger.
132
+ *
133
+ * Recommended to use state to store this element, rather than a ref.
134
+ */
135
+ positionReference?: HTMLElement;
128
136
  } & PortalProps & PopoverOptions;
129
137
  /**
130
138
  * A utility component to help with positioning of floating content relative to a trigger.