@itwin/itwinui-react 2.11.1 → 2.11.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.11.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1309](https://github.com/iTwin/iTwinUI/pull/1309): Fixed missing CSS imports in `FileUploadCard` and `FileUpoadTemplate`.
8
+
9
+ ## 2.11.2
10
+
11
+ ### Patch Changes
12
+
13
+ - [#1288](https://github.com/iTwin/iTwinUI/pull/1288): Fixed hover styling for SearchBox.
14
+ - Updated dependencies:
15
+ - @itwin/itwinui-css@1.11.1
16
+
3
17
  ## 2.11.1
4
18
 
5
19
  ### Patch Changes
@@ -44,11 +44,8 @@ exports.ComboBoxEndIcon = React.forwardRef((props, forwardedRef) => {
44
44
  'iui-actionable': !disabled,
45
45
  'iui-disabled': disabled,
46
46
  'iui-open': isOpen,
47
- }, className), onClick: (e) => {
48
- onClickProp === null || onClickProp === void 0 ? void 0 : onClickProp(e);
49
- if (!e.isDefaultPrevented()) {
50
- dispatch({ type: isOpen ? 'close' : 'open' });
51
- }
52
- }, ...rest }, children !== null && children !== void 0 ? children : React.createElement(index_js_1.SvgCaretDownSmall, { "aria-hidden": true })));
47
+ }, className), onClick: (0, index_js_1.mergeEventHandlers)(onClickProp, () => {
48
+ dispatch({ type: isOpen ? 'close' : 'open' });
49
+ }), ...rest }, children !== null && children !== void 0 ? children : React.createElement(index_js_1.SvgCaretDownSmall, { "aria-hidden": true })));
53
50
  });
54
51
  exports.ComboBoxEndIcon.displayName = 'ComboBoxEndIcon';
@@ -150,18 +150,14 @@ exports.ComboBoxInput = React.forwardRef((props, forwardedRef) => {
150
150
  dispatch({ type: 'open' });
151
151
  onFocusProp === null || onFocusProp === void 0 ? void 0 : onFocusProp(event);
152
152
  }, [dispatch, onFocusProp]);
153
- const handleClick = React.useCallback((e) => {
154
- onClickProp === null || onClickProp === void 0 ? void 0 : onClickProp(e);
155
- if (e.isDefaultPrevented()) {
156
- return;
157
- }
153
+ const handleClick = React.useCallback(() => {
158
154
  if (!isOpen) {
159
155
  dispatch({ type: 'open' });
160
156
  }
161
- }, [dispatch, isOpen, onClickProp]);
157
+ }, [dispatch, isOpen]);
162
158
  const [tagContainerWidthRef, tagContainerWidth] = (0, index_js_2.useContainerWidth)();
163
159
  return (React.createElement(React.Fragment, null,
164
- React.createElement(index_js_1.Input, { ref: refs, onKeyDown: handleKeyDown, onClick: handleClick, onFocus: handleFocus, "aria-activedescendant": isOpen && focusedIndex != undefined && focusedIndex > -1
160
+ React.createElement(index_js_1.Input, { ref: refs, onKeyDown: handleKeyDown, onClick: (0, index_js_2.mergeEventHandlers)(onClickProp, handleClick), onFocus: handleFocus, "aria-activedescendant": isOpen && focusedIndex != undefined && focusedIndex > -1
165
161
  ? getIdFromIndex(focusedIndex)
166
162
  : undefined, role: 'combobox', "aria-controls": isOpen ? `${id}-list` : undefined, "aria-autocomplete": 'list', spellCheck: false, autoCapitalize: 'none', autoCorrect: 'off', style: multiple ? { paddingLeft: tagContainerWidth + 18 } : {}, "aria-describedby": multiple ? `${id}-selected-live` : undefined, ...rest }),
167
163
  multiple && selectTags ? (React.createElement(ComboBoxMultipleContainer_js_1.ComboBoxMultipleContainer, { ref: tagContainerWidthRef, selectedItems: selectTags, id: `${id}-selected-live` })) : null));
@@ -60,16 +60,10 @@ exports.DialogTitleBar = Object.assign(React.forwardRef((props, ref) => {
60
60
  const dialogContext = (0, DialogContext_js_1.useDialogContext)();
61
61
  const { children, titleText, isDismissible = dialogContext.isDismissible, onClose = dialogContext.onClose, isDraggable = dialogContext.isDraggable, className, onPointerDown: onPointerDownProp, ...rest } = props;
62
62
  const { onPointerDown } = (0, DialogDragContext_js_1.useDialogDragContext)();
63
- const handlePointerDown = React.useCallback((event) => {
64
- onPointerDownProp === null || onPointerDownProp === void 0 ? void 0 : onPointerDownProp(event);
65
- if (!event.defaultPrevented) {
66
- onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(event);
67
- }
68
- }, [onPointerDown, onPointerDownProp]);
69
63
  (0, index_js_1.useTheme)();
70
64
  return (React.createElement("div", { className: (0, classnames_1.default)('iui-dialog-title-bar', className, {
71
65
  'iui-dialog-title-bar-filled': isDraggable,
72
- }), ref: ref, onPointerDown: handlePointerDown, ...rest }, children ? (children) : (React.createElement(React.Fragment, null,
66
+ }), ref: ref, onPointerDown: (0, index_js_1.mergeEventHandlers)(onPointerDownProp, onPointerDown), ...rest }, children ? (children) : (React.createElement(React.Fragment, null,
73
67
  React.createElement(DialogTitleBarTitle_js_1.DialogTitleBarTitle, null, titleText),
74
68
  isDismissible && (React.createElement(index_js_2.IconButton, { size: 'small', styleType: 'borderless', onClick: onClose, "aria-label": 'Close' },
75
69
  React.createElement(index_js_1.SvgClose, null)))))));
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import '@itwin/itwinui-css/css/file-upload.css';
2
3
  export declare type FileUploadCardIconProps = React.ComponentPropsWithRef<'span'>;
3
4
  export declare type FileUploadCardInfoProps = React.ComponentPropsWithRef<'span'>;
4
5
  export declare type FileUploadCardTitleProps = React.ComponentPropsWithRef<'span'>;
@@ -35,6 +35,8 @@ const React = __importStar(require("react"));
35
35
  const index_js_1 = require("../utils/index.js");
36
36
  const classnames_1 = __importDefault(require("classnames"));
37
37
  const FileEmptyCard_js_1 = require("./FileEmptyCard.js");
38
+ const Anchor_js_1 = require("../Typography/Anchor/Anchor.js");
39
+ require("@itwin/itwinui-css/css/file-upload.css");
38
40
  const toBytes = (bytes) => {
39
41
  const units = [' bytes', 'KB', 'MB', 'GB', 'TB'];
40
42
  let i = 0;
@@ -82,13 +84,13 @@ const FileUploadCardAction = React.forwardRef((props, ref) => {
82
84
  });
83
85
  FileUploadCardAction.displayName = 'FileUploadCard.Action';
84
86
  const FileUploadCardInputLabel = React.forwardRef((props, ref) => {
85
- const { children, className, ...rest } = props;
87
+ const { children, ...rest } = props;
86
88
  const { inputId } = (0, index_js_1.useSafeContext)(exports.FileUploadCardContext);
87
- return (React.createElement("label", { className: (0, classnames_1.default)('iui-anchor', className), ref: ref, htmlFor: inputId, ...rest }, children));
89
+ return (React.createElement(Anchor_js_1.Anchor, { as: 'label', ref: ref, htmlFor: inputId, ...rest }, children));
88
90
  });
89
91
  FileUploadCardInputLabel.displayName = 'FileUploadCard.InputLabel';
90
92
  const FileUploadCardInput = React.forwardRef((props, ref) => {
91
- const { children, className, onChange, id, ...rest } = props;
93
+ const { children, onChange, id, ...rest } = props;
92
94
  const { files, onFilesChange, setInternalFiles, inputId, setInputId } = (0, index_js_1.useSafeContext)(exports.FileUploadCardContext);
93
95
  const setNativeFilesRef = React.useCallback((node) => {
94
96
  var _a;
@@ -107,14 +109,11 @@ const FileUploadCardInput = React.forwardRef((props, ref) => {
107
109
  }
108
110
  }, [id, inputId, setInputId]);
109
111
  return (React.createElement(React.Fragment, null,
110
- React.createElement("input", { className: (0, classnames_1.default)('iui-visually-hidden', className), type: 'file', onChange: (e) => {
111
- onChange === null || onChange === void 0 ? void 0 : onChange(e);
112
- if (!e.isDefaultPrevented()) {
113
- const _files = Array.from(e.currentTarget.files || []);
114
- onFilesChange === null || onFilesChange === void 0 ? void 0 : onFilesChange(_files);
115
- setInternalFiles(_files);
116
- }
117
- }, ref: refs, id: id !== null && id !== void 0 ? id : inputId, ...rest }),
112
+ React.createElement(index_js_1.VisuallyHidden, { as: 'input', type: 'file', onChange: (0, index_js_1.mergeEventHandlers)(onChange, (e) => {
113
+ const _files = Array.from(e.currentTarget.files || []);
114
+ onFilesChange === null || onFilesChange === void 0 ? void 0 : onFilesChange(_files);
115
+ setInternalFiles(_files);
116
+ }), ref: refs, id: id !== null && id !== void 0 ? id : inputId, ...rest }),
118
117
  children));
119
118
  });
120
119
  FileUploadCardInput.displayName = 'FileUploadCard.Input';
@@ -35,6 +35,7 @@ const React = __importStar(require("react"));
35
35
  const classnames_1 = __importDefault(require("classnames"));
36
36
  const index_js_1 = require("../utils/index.js");
37
37
  require("@itwin/itwinui-css/css/file-upload.css");
38
+ const Anchor_js_1 = require("../Typography/Anchor/Anchor.js");
38
39
  /**
39
40
  * Default template to be used with the `FileUpload` wrapper component.
40
41
  * Contains a hidden input with styled labels (customizable).
@@ -47,7 +48,7 @@ const FileUploadTemplate = (props) => {
47
48
  return (React.createElement("div", { className: (0, classnames_1.default)('iui-file-upload-template', className), ...rest },
48
49
  React.createElement(index_js_1.SvgUpload, { className: 'iui-template-icon', "aria-hidden": true }),
49
50
  React.createElement("div", { className: 'iui-template-text' },
50
- React.createElement("label", { className: 'iui-anchor' },
51
+ React.createElement(Anchor_js_1.Anchor, { as: 'label' },
51
52
  React.createElement("input", { className: 'iui-browse-input', type: 'file', onChange: onChange, multiple: acceptMultiple, accept: acceptType }),
52
53
  label),
53
54
  React.createElement("div", null, subtitle),
@@ -123,26 +123,14 @@ SearchBoxButton.displayName = 'SearchBox.Button';
123
123
  const SearchBoxCollapseButton = React.forwardRef((props, ref) => {
124
124
  const { children, onClick: onClickProp, ...rest } = props;
125
125
  const { onCollapse, size: sizeContext, isDisabled, } = (0, index_js_1.useSafeContext)(SearchBoxContext);
126
- return (React.createElement(SearchBoxButton, { ref: ref, "aria-label": 'Close searchbox', size: sizeContext, disabled: isDisabled, onClick: (e) => {
127
- onClickProp === null || onClickProp === void 0 ? void 0 : onClickProp(e);
128
- if (e.isDefaultPrevented()) {
129
- return;
130
- }
131
- onCollapse === null || onCollapse === void 0 ? void 0 : onCollapse();
132
- }, ...rest }, children !== null && children !== void 0 ? children : React.createElement(index_js_1.SvgCloseSmall, null)));
126
+ return (React.createElement(SearchBoxButton, { ref: ref, "aria-label": 'Close searchbox', size: sizeContext, disabled: isDisabled, onClick: (0, index_js_1.mergeEventHandlers)(onClickProp, onCollapse), ...rest }, children !== null && children !== void 0 ? children : React.createElement(index_js_1.SvgCloseSmall, null)));
133
127
  });
134
128
  SearchBoxCollapseButton.displayName = 'SearchBox.CollapseButton';
135
129
  // ----------------------------------------------------------------------------
136
130
  const SearchBoxExpandButton = React.forwardRef((props, ref) => {
137
131
  const { children, className, onClick: onClickProp, ...rest } = props;
138
132
  const { onExpand, size: sizeContext, isDisabled, openButtonRef, } = (0, index_js_1.useSafeContext)(SearchBoxContext);
139
- return (React.createElement(SearchBoxButton, { ref: (0, index_js_1.useMergedRefs)(ref, openButtonRef), className: (0, classnames_1.default)('iui-searchbox-open-button', className), "aria-label": 'Expand searchbox', size: sizeContext, disabled: isDisabled, onClick: (e) => {
140
- onClickProp === null || onClickProp === void 0 ? void 0 : onClickProp(e);
141
- if (e.isDefaultPrevented()) {
142
- return;
143
- }
144
- onExpand === null || onExpand === void 0 ? void 0 : onExpand();
145
- }, ...rest }, children !== null && children !== void 0 ? children : React.createElement(index_js_1.SvgSearch, null)));
133
+ return (React.createElement(SearchBoxButton, { ref: (0, index_js_1.useMergedRefs)(ref, openButtonRef), className: (0, classnames_1.default)('iui-searchbox-open-button', className), "aria-label": 'Expand searchbox', size: sizeContext, disabled: isDisabled, onClick: (0, index_js_1.mergeEventHandlers)(onClickProp, onExpand), ...rest }, children !== null && children !== void 0 ? children : React.createElement(index_js_1.SvgSearch, null)));
146
134
  });
147
135
  SearchBoxExpandButton.displayName = 'SearchBox.ExpandButton';
148
136
  // ----------------------------------------------------------------------------
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  /**
2
3
  * Get the container as a child of body, or create one if it doesn't exist.
3
4
  * Mostly used for dynamic components like Modal or Toast.
@@ -16,3 +17,8 @@ export declare const getDocument: () => Document | undefined;
16
17
  * Used to support SSR/SSG applications.
17
18
  */
18
19
  export declare const getWindow: () => (Window & typeof globalThis) | undefined;
20
+ /**
21
+ * Merges multiple event handlers into one, while making sure that
22
+ * `defaultPrevented` is respected for each callback.
23
+ */
24
+ export declare const mergeEventHandlers: <E extends import("react").SyntheticEvent<Element, Event>>(...callbacks: (((event: E) => void) | undefined)[]) => (event: E) => void;
@@ -4,7 +4,7 @@
4
4
  * See LICENSE.md in the project root for license terms and full copyright notice.
5
5
  *--------------------------------------------------------------------------------------------*/
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.getWindow = exports.getDocument = exports.getContainer = void 0;
7
+ exports.mergeEventHandlers = exports.getWindow = exports.getDocument = exports.getContainer = void 0;
8
8
  /**
9
9
  * Get the container as a child of body, or create one if it doesn't exist.
10
10
  * Mostly used for dynamic components like Modal or Toast.
@@ -40,3 +40,16 @@ const getWindow = () => {
40
40
  return typeof window === 'undefined' ? undefined : window;
41
41
  };
42
42
  exports.getWindow = getWindow;
43
+ /**
44
+ * Merges multiple event handlers into one, while making sure that
45
+ * `defaultPrevented` is respected for each callback.
46
+ */
47
+ const mergeEventHandlers = (...callbacks) => (event) => {
48
+ for (const cb of callbacks) {
49
+ cb === null || cb === void 0 ? void 0 : cb(event);
50
+ if (event === null || event === void 0 ? void 0 : event.defaultPrevented) {
51
+ return;
52
+ }
53
+ }
54
+ };
55
+ exports.mergeEventHandlers = mergeEventHandlers;
@@ -4,7 +4,7 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import cx from 'classnames';
6
6
  import * as React from 'react';
7
- import { useSafeContext, useMergedRefs, SvgCaretDownSmall, } from '../utils/index.js';
7
+ import { useSafeContext, useMergedRefs, SvgCaretDownSmall, mergeEventHandlers, } from '../utils/index.js';
8
8
  import { ComboBoxActionContext, ComboBoxRefsContext } from './helpers.js';
9
9
  export const ComboBoxEndIcon = React.forwardRef((props, forwardedRef) => {
10
10
  const { className, children, onClick: onClickProp, disabled, isOpen, ...rest } = props;
@@ -15,11 +15,8 @@ export const ComboBoxEndIcon = React.forwardRef((props, forwardedRef) => {
15
15
  'iui-actionable': !disabled,
16
16
  'iui-disabled': disabled,
17
17
  'iui-open': isOpen,
18
- }, className), onClick: (e) => {
19
- onClickProp === null || onClickProp === void 0 ? void 0 : onClickProp(e);
20
- if (!e.isDefaultPrevented()) {
21
- dispatch({ type: isOpen ? 'close' : 'open' });
22
- }
23
- }, ...rest }, children !== null && children !== void 0 ? children : React.createElement(SvgCaretDownSmall, { "aria-hidden": true })));
18
+ }, className), onClick: mergeEventHandlers(onClickProp, () => {
19
+ dispatch({ type: isOpen ? 'close' : 'open' });
20
+ }), ...rest }, children !== null && children !== void 0 ? children : React.createElement(SvgCaretDownSmall, { "aria-hidden": true })));
24
21
  });
25
22
  ComboBoxEndIcon.displayName = 'ComboBoxEndIcon';
@@ -4,7 +4,7 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as React from 'react';
6
6
  import { Input } from '../Input/index.js';
7
- import { useSafeContext, useMergedRefs, useContainerWidth, } from '../utils/index.js';
7
+ import { useSafeContext, useMergedRefs, useContainerWidth, mergeEventHandlers, } from '../utils/index.js';
8
8
  import { ComboBoxMultipleContainer } from './ComboBoxMultipleContainer.js';
9
9
  import { ComboBoxStateContext, ComboBoxActionContext, ComboBoxRefsContext, } from './helpers.js';
10
10
  export const ComboBoxInput = React.forwardRef((props, forwardedRef) => {
@@ -124,18 +124,14 @@ export const ComboBoxInput = React.forwardRef((props, forwardedRef) => {
124
124
  dispatch({ type: 'open' });
125
125
  onFocusProp === null || onFocusProp === void 0 ? void 0 : onFocusProp(event);
126
126
  }, [dispatch, onFocusProp]);
127
- const handleClick = React.useCallback((e) => {
128
- onClickProp === null || onClickProp === void 0 ? void 0 : onClickProp(e);
129
- if (e.isDefaultPrevented()) {
130
- return;
131
- }
127
+ const handleClick = React.useCallback(() => {
132
128
  if (!isOpen) {
133
129
  dispatch({ type: 'open' });
134
130
  }
135
- }, [dispatch, isOpen, onClickProp]);
131
+ }, [dispatch, isOpen]);
136
132
  const [tagContainerWidthRef, tagContainerWidth] = useContainerWidth();
137
133
  return (React.createElement(React.Fragment, null,
138
- React.createElement(Input, { ref: refs, onKeyDown: handleKeyDown, onClick: handleClick, onFocus: handleFocus, "aria-activedescendant": isOpen && focusedIndex != undefined && focusedIndex > -1
134
+ React.createElement(Input, { ref: refs, onKeyDown: handleKeyDown, onClick: mergeEventHandlers(onClickProp, handleClick), onFocus: handleFocus, "aria-activedescendant": isOpen && focusedIndex != undefined && focusedIndex > -1
139
135
  ? getIdFromIndex(focusedIndex)
140
136
  : undefined, role: 'combobox', "aria-controls": isOpen ? `${id}-list` : undefined, "aria-autocomplete": 'list', spellCheck: false, autoCapitalize: 'none', autoCorrect: 'off', style: multiple ? { paddingLeft: tagContainerWidth + 18 } : {}, "aria-describedby": multiple ? `${id}-selected-live` : undefined, ...rest }),
141
137
  multiple && selectTags ? (React.createElement(ComboBoxMultipleContainer, { ref: tagContainerWidthRef, selectedItems: selectTags, id: `${id}-selected-live` })) : null));
@@ -4,7 +4,7 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as React from 'react';
6
6
  import cx from 'classnames';
7
- import { useTheme, SvgClose } from '../utils/index.js';
7
+ import { useTheme, SvgClose, mergeEventHandlers } from '../utils/index.js';
8
8
  import { IconButton } from '../Buttons/index.js';
9
9
  import '@itwin/itwinui-css/css/dialog.css';
10
10
  import { useDialogContext } from './DialogContext.js';
@@ -31,16 +31,10 @@ export const DialogTitleBar = Object.assign(React.forwardRef((props, ref) => {
31
31
  const dialogContext = useDialogContext();
32
32
  const { children, titleText, isDismissible = dialogContext.isDismissible, onClose = dialogContext.onClose, isDraggable = dialogContext.isDraggable, className, onPointerDown: onPointerDownProp, ...rest } = props;
33
33
  const { onPointerDown } = useDialogDragContext();
34
- const handlePointerDown = React.useCallback((event) => {
35
- onPointerDownProp === null || onPointerDownProp === void 0 ? void 0 : onPointerDownProp(event);
36
- if (!event.defaultPrevented) {
37
- onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(event);
38
- }
39
- }, [onPointerDown, onPointerDownProp]);
40
34
  useTheme();
41
35
  return (React.createElement("div", { className: cx('iui-dialog-title-bar', className, {
42
36
  'iui-dialog-title-bar-filled': isDraggable,
43
- }), ref: ref, onPointerDown: handlePointerDown, ...rest }, children ? (children) : (React.createElement(React.Fragment, null,
37
+ }), ref: ref, onPointerDown: mergeEventHandlers(onPointerDownProp, onPointerDown), ...rest }, children ? (children) : (React.createElement(React.Fragment, null,
44
38
  React.createElement(DialogTitleBarTitle, null, titleText),
45
39
  isDismissible && (React.createElement(IconButton, { size: 'small', styleType: 'borderless', onClick: onClose, "aria-label": 'Close' },
46
40
  React.createElement(SvgClose, null)))))));
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import '@itwin/itwinui-css/css/file-upload.css';
2
3
  export declare type FileUploadCardIconProps = React.ComponentPropsWithRef<'span'>;
3
4
  export declare type FileUploadCardInfoProps = React.ComponentPropsWithRef<'span'>;
4
5
  export declare type FileUploadCardTitleProps = React.ComponentPropsWithRef<'span'>;
@@ -3,9 +3,11 @@
3
3
  * See LICENSE.md in the project root for license terms and full copyright notice.
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as React from 'react';
6
- import { getWindow, SvgDocument, useMergedRefs, useSafeContext, useId, } from '../utils/index.js';
6
+ import { getWindow, SvgDocument, useMergedRefs, useSafeContext, useId, mergeEventHandlers, VisuallyHidden, } from '../utils/index.js';
7
7
  import cx from 'classnames';
8
8
  import { FileEmptyCard } from './FileEmptyCard.js';
9
+ import { Anchor } from '../Typography/Anchor/Anchor.js';
10
+ import '@itwin/itwinui-css/css/file-upload.css';
9
11
  const toBytes = (bytes) => {
10
12
  const units = [' bytes', 'KB', 'MB', 'GB', 'TB'];
11
13
  let i = 0;
@@ -53,13 +55,13 @@ const FileUploadCardAction = React.forwardRef((props, ref) => {
53
55
  });
54
56
  FileUploadCardAction.displayName = 'FileUploadCard.Action';
55
57
  const FileUploadCardInputLabel = React.forwardRef((props, ref) => {
56
- const { children, className, ...rest } = props;
58
+ const { children, ...rest } = props;
57
59
  const { inputId } = useSafeContext(FileUploadCardContext);
58
- return (React.createElement("label", { className: cx('iui-anchor', className), ref: ref, htmlFor: inputId, ...rest }, children));
60
+ return (React.createElement(Anchor, { as: 'label', ref: ref, htmlFor: inputId, ...rest }, children));
59
61
  });
60
62
  FileUploadCardInputLabel.displayName = 'FileUploadCard.InputLabel';
61
63
  const FileUploadCardInput = React.forwardRef((props, ref) => {
62
- const { children, className, onChange, id, ...rest } = props;
64
+ const { children, onChange, id, ...rest } = props;
63
65
  const { files, onFilesChange, setInternalFiles, inputId, setInputId } = useSafeContext(FileUploadCardContext);
64
66
  const setNativeFilesRef = React.useCallback((node) => {
65
67
  var _a;
@@ -78,14 +80,11 @@ const FileUploadCardInput = React.forwardRef((props, ref) => {
78
80
  }
79
81
  }, [id, inputId, setInputId]);
80
82
  return (React.createElement(React.Fragment, null,
81
- React.createElement("input", { className: cx('iui-visually-hidden', className), type: 'file', onChange: (e) => {
82
- onChange === null || onChange === void 0 ? void 0 : onChange(e);
83
- if (!e.isDefaultPrevented()) {
84
- const _files = Array.from(e.currentTarget.files || []);
85
- onFilesChange === null || onFilesChange === void 0 ? void 0 : onFilesChange(_files);
86
- setInternalFiles(_files);
87
- }
88
- }, ref: refs, id: id !== null && id !== void 0 ? id : inputId, ...rest }),
83
+ React.createElement(VisuallyHidden, { as: 'input', type: 'file', onChange: mergeEventHandlers(onChange, (e) => {
84
+ const _files = Array.from(e.currentTarget.files || []);
85
+ onFilesChange === null || onFilesChange === void 0 ? void 0 : onFilesChange(_files);
86
+ setInternalFiles(_files);
87
+ }), ref: refs, id: id !== null && id !== void 0 ? id : inputId, ...rest }),
89
88
  children));
90
89
  });
91
90
  FileUploadCardInput.displayName = 'FileUploadCard.Input';
@@ -6,6 +6,7 @@ import * as React from 'react';
6
6
  import cx from 'classnames';
7
7
  import { useTheme, SvgUpload } from '../utils/index.js';
8
8
  import '@itwin/itwinui-css/css/file-upload.css';
9
+ import { Anchor } from '../Typography/Anchor/Anchor.js';
9
10
  /**
10
11
  * Default template to be used with the `FileUpload` wrapper component.
11
12
  * Contains a hidden input with styled labels (customizable).
@@ -18,7 +19,7 @@ export const FileUploadTemplate = (props) => {
18
19
  return (React.createElement("div", { className: cx('iui-file-upload-template', className), ...rest },
19
20
  React.createElement(SvgUpload, { className: 'iui-template-icon', "aria-hidden": true }),
20
21
  React.createElement("div", { className: 'iui-template-text' },
21
- React.createElement("label", { className: 'iui-anchor' },
22
+ React.createElement(Anchor, { as: 'label' },
22
23
  React.createElement("input", { className: 'iui-browse-input', type: 'file', onChange: onChange, multiple: acceptMultiple, accept: acceptType }),
23
24
  label),
24
25
  React.createElement("div", null, subtitle),
@@ -4,7 +4,7 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as React from 'react';
6
6
  import cx from 'classnames';
7
- import { InputFlexContainer, useTheme, SvgSearch, SvgCloseSmall, useSafeContext, useId, Icon, useMergedRefs, } from '../utils/index.js';
7
+ import { InputFlexContainer, useTheme, SvgSearch, SvgCloseSmall, useSafeContext, useId, Icon, useMergedRefs, mergeEventHandlers, } from '../utils/index.js';
8
8
  import { IconButton } from '../Buttons/IconButton/index.js';
9
9
  import '@itwin/itwinui-css/css/searchbox.css';
10
10
  const SearchBoxContext = React.createContext(undefined);
@@ -94,26 +94,14 @@ SearchBoxButton.displayName = 'SearchBox.Button';
94
94
  const SearchBoxCollapseButton = React.forwardRef((props, ref) => {
95
95
  const { children, onClick: onClickProp, ...rest } = props;
96
96
  const { onCollapse, size: sizeContext, isDisabled, } = useSafeContext(SearchBoxContext);
97
- return (React.createElement(SearchBoxButton, { ref: ref, "aria-label": 'Close searchbox', size: sizeContext, disabled: isDisabled, onClick: (e) => {
98
- onClickProp === null || onClickProp === void 0 ? void 0 : onClickProp(e);
99
- if (e.isDefaultPrevented()) {
100
- return;
101
- }
102
- onCollapse === null || onCollapse === void 0 ? void 0 : onCollapse();
103
- }, ...rest }, children !== null && children !== void 0 ? children : React.createElement(SvgCloseSmall, null)));
97
+ return (React.createElement(SearchBoxButton, { ref: ref, "aria-label": 'Close searchbox', size: sizeContext, disabled: isDisabled, onClick: mergeEventHandlers(onClickProp, onCollapse), ...rest }, children !== null && children !== void 0 ? children : React.createElement(SvgCloseSmall, null)));
104
98
  });
105
99
  SearchBoxCollapseButton.displayName = 'SearchBox.CollapseButton';
106
100
  // ----------------------------------------------------------------------------
107
101
  const SearchBoxExpandButton = React.forwardRef((props, ref) => {
108
102
  const { children, className, onClick: onClickProp, ...rest } = props;
109
103
  const { onExpand, size: sizeContext, isDisabled, openButtonRef, } = useSafeContext(SearchBoxContext);
110
- return (React.createElement(SearchBoxButton, { ref: useMergedRefs(ref, openButtonRef), className: cx('iui-searchbox-open-button', className), "aria-label": 'Expand searchbox', size: sizeContext, disabled: isDisabled, onClick: (e) => {
111
- onClickProp === null || onClickProp === void 0 ? void 0 : onClickProp(e);
112
- if (e.isDefaultPrevented()) {
113
- return;
114
- }
115
- onExpand === null || onExpand === void 0 ? void 0 : onExpand();
116
- }, ...rest }, children !== null && children !== void 0 ? children : React.createElement(SvgSearch, null)));
104
+ return (React.createElement(SearchBoxButton, { ref: useMergedRefs(ref, openButtonRef), className: cx('iui-searchbox-open-button', className), "aria-label": 'Expand searchbox', size: sizeContext, disabled: isDisabled, onClick: mergeEventHandlers(onClickProp, onExpand), ...rest }, children !== null && children !== void 0 ? children : React.createElement(SvgSearch, null)));
117
105
  });
118
106
  SearchBoxExpandButton.displayName = 'SearchBox.ExpandButton';
119
107
  // ----------------------------------------------------------------------------
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  /**
2
3
  * Get the container as a child of body, or create one if it doesn't exist.
3
4
  * Mostly used for dynamic components like Modal or Toast.
@@ -16,3 +17,8 @@ export declare const getDocument: () => Document | undefined;
16
17
  * Used to support SSR/SSG applications.
17
18
  */
18
19
  export declare const getWindow: () => (Window & typeof globalThis) | undefined;
20
+ /**
21
+ * Merges multiple event handlers into one, while making sure that
22
+ * `defaultPrevented` is respected for each callback.
23
+ */
24
+ export declare const mergeEventHandlers: <E extends import("react").SyntheticEvent<Element, Event>>(...callbacks: (((event: E) => void) | undefined)[]) => (event: E) => void;
@@ -34,3 +34,15 @@ export const getDocument = () => {
34
34
  export const getWindow = () => {
35
35
  return typeof window === 'undefined' ? undefined : window;
36
36
  };
37
+ /**
38
+ * Merges multiple event handlers into one, while making sure that
39
+ * `defaultPrevented` is respected for each callback.
40
+ */
41
+ export const mergeEventHandlers = (...callbacks) => (event) => {
42
+ for (const cb of callbacks) {
43
+ cb === null || cb === void 0 ? void 0 : cb(event);
44
+ if (event === null || event === void 0 ? void 0 : event.defaultPrevented) {
45
+ return;
46
+ }
47
+ }
48
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/itwinui-react",
3
- "version": "2.11.1",
3
+ "version": "2.11.3",
4
4
  "author": "Bentley Systems",
5
5
  "license": "MIT",
6
6
  "main": "cjs/index.js",
@@ -67,7 +67,7 @@
67
67
  "dev:types": "concurrently \"tsc -p tsconfig.cjs.json --emitDeclarationOnly --watch --preserveWatchOutput\" \"tsc -p tsconfig.esm.json --emitDeclarationOnly --watch --preserveWatchOutput\""
68
68
  },
69
69
  "dependencies": {
70
- "@itwin/itwinui-css": "^1.11.0",
70
+ "@itwin/itwinui-css": "^1.11.1",
71
71
  "@itwin/itwinui-illustrations-react": "^2.0.0",
72
72
  "@itwin/itwinui-variables": "^2.0.0",
73
73
  "@tippyjs/react": "^4.2.6",