@itwin/itwinui-react 2.4.0-dev.2 → 2.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 054bc3ba: `<Avatar>`'s `image` now supports passing `<svg>` too
8
+
9
+ ```tsx
10
+ <Avatar image={<SvgUser />} />
11
+ ```
12
+
13
+ - 06476ada: Added new `Flex` utility component and optional `Flex.Spacer`/`Flex.Item` subcomponents to make it easier to work with CSS flexbox and use iTwinUI design tokens for gap.
14
+
15
+ ```jsx
16
+ <Flex gap='xl' justifyContent='center'>
17
+ <div>...</div>
18
+ <div>...</div>
19
+ </Flex>
20
+ ```
21
+
22
+ ```jsx
23
+ <Flex>
24
+ <Flex.Item>...</Flex.Item>
25
+ <Flex.Spacer />
26
+ <Flex.Item>...</Flex.Item>
27
+ <Flex.Item>...</Flex.Item>
28
+ </Flex>
29
+ ```
30
+
31
+ - 44446e50: `DropdownButton` now exposes `dropdownMenuProps` to allow control over all popover props, such as `placement`.
32
+
33
+ ### Patch Changes
34
+
35
+ - Updated dependencies
36
+ - @itwin/itwinui-css@1.5.0
37
+
3
38
  ## 2.3.0
4
39
 
5
40
  ### Minor Changes
@@ -28,12 +28,11 @@ export declare type AvatarProps = {
28
28
  */
29
29
  abbreviation?: string;
30
30
  /**
31
- * User image to be displayed. MUST be an `<img>` element!
31
+ * User image to be displayed. Can be `<img>` or `<svg>` or anything else.
32
32
  */
33
33
  image?: JSX.Element;
34
34
  /**
35
- * Color of the icon. You can use `getUserColor` function to generate color from user name or email.
36
- * @default 'white'
35
+ * Color of the icon. You can use `getUserColor` function to generate color from user name or email. If not provided, default background color from CSS styling will be used (hsl(72, 51%, 56%) / olive green).
37
36
  */
38
37
  backgroundColor?: string;
39
38
  /**
@@ -34,10 +34,12 @@ exports.defaultStatusTitles = {
34
34
  * <Avatar size='x-large' title='Terry Rivers' abbreviation='TR' backgroundColor='green' image={<img src="https://cdn.example.com/user/profile/pic.png" />}/>
35
35
  */
36
36
  const Avatar = (props) => {
37
- const { size = 'small', status, abbreviation, image, backgroundColor = 'white', title, translatedStatusTitles, className, style, ...rest } = props;
37
+ const { size = 'small', status, abbreviation, image, backgroundColor, title, translatedStatusTitles, className, style, ...rest } = props;
38
38
  (0, utils_1.useTheme)();
39
39
  const statusTitles = { ...exports.defaultStatusTitles, ...translatedStatusTitles };
40
- return (react_1.default.createElement("span", { className: (0, classnames_1.default)('iui-avatar', { [`iui-${size}`]: size !== 'medium' }, className), title: title, style: style, ...rest }, image !== null && image !== void 0 ? image : (react_1.default.createElement("abbr", { className: 'iui-initials', style: { backgroundColor } }, abbreviation === null || abbreviation === void 0 ? void 0 : abbreviation.substring(0, 2))),
40
+ return (react_1.default.createElement("span", { className: (0, classnames_1.default)('iui-avatar', { [`iui-${size}`]: size !== 'medium' }, className), title: title, style: { backgroundColor, ...style }, ...rest },
41
+ !image && (react_1.default.createElement("abbr", { className: 'iui-initials' }, abbreviation === null || abbreviation === void 0 ? void 0 : abbreviation.substring(0, 2))),
42
+ image,
41
43
  react_1.default.createElement("span", { className: 'iui-stroke' }),
42
44
  status && (react_1.default.createElement("span", { title: statusTitles[status], className: (0, classnames_1.default)('iui-status', {
43
45
  [`iui-${status}`]: !!status,
@@ -3,7 +3,7 @@ import type { PolymorphicComponentProps, PolymorphicForwardRefComponent, ThemeOp
3
3
  import '@itwin/itwinui-css/css/global.css';
4
4
  import '@itwin/itwinui-variables/index.css';
5
5
  export declare type ThemeProviderProps<T extends React.ElementType = 'div'> = PolymorphicComponentProps<T, ThemeProviderOwnProps>;
6
- declare type RootWithThemeProps = {
6
+ declare type RootProps = {
7
7
  /**
8
8
  * Theme to be applied. Can be 'light' or 'dark' or 'os'.
9
9
  *
@@ -27,8 +27,8 @@ declare type RootWithThemeProps = {
27
27
  applyBackground?: boolean;
28
28
  };
29
29
  };
30
- declare type ThemeProviderOwnProps = Pick<RootWithThemeProps, 'theme'> & ({
31
- themeOptions?: RootWithThemeProps['themeOptions'];
30
+ declare type ThemeProviderOwnProps = Pick<RootProps, 'theme'> & ({
31
+ themeOptions?: RootProps['themeOptions'];
32
32
  children: Required<React.ReactNode>;
33
33
  } | {
34
34
  themeOptions?: ThemeOptions;
@@ -67,23 +67,3 @@ export declare const ThemeContext: React.Context<{
67
67
  themeOptions?: ThemeOptions | undefined;
68
68
  rootRef: React.RefObject<HTMLElement>;
69
69
  } | undefined>;
70
- /**
71
- * Root component that should wrap all iTwinUI components, preventing styles from leaking out of the tree.
72
- *
73
- * This is only needed when it's not possible to use ThemeProvider. For example, when building a package
74
- * using iTwinUI v2, the package should have no opinion on the app theme, but the components in the package
75
- * should probably still be scoped, to prevent potential conflicts with the rest of the page where it's used.
76
- *
77
- * @example
78
- * <Root>
79
- * // UI built using iTwinUI v2
80
- * </Root>
81
- */
82
- export declare const Root: PolymorphicForwardRefComponent<"div", RootProps>;
83
- export declare type RootProps = {
84
- /**
85
- * Whether or not the root should have the recommended `background-color`.
86
- * This is usually only relevant for the topmost root on the page.
87
- */
88
- withBackground?: boolean;
89
- } & React.ComponentProps<'div'>;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Root = exports.ThemeContext = exports.ThemeProvider = void 0;
6
+ exports.ThemeContext = exports.ThemeProvider = void 0;
7
7
  /*---------------------------------------------------------------------------------------------
8
8
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
9
9
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -51,14 +51,14 @@ exports.ThemeProvider = react_1.default.forwardRef((props, ref) => {
51
51
  return (react_1.default.createElement(ThemeLogicWrapper, { theme: theme !== null && theme !== void 0 ? theme : parentContext === null || parentContext === void 0 ? void 0 : parentContext.theme, themeOptions: themeOptions !== null && themeOptions !== void 0 ? themeOptions : parentContext === null || parentContext === void 0 ? void 0 : parentContext.themeOptions }));
52
52
  }
53
53
  // now that we know there are children, we can render the root and provide the context value
54
- return (react_1.default.createElement(RootWithTheme, { theme: theme, themeOptions: themeOptions, ref: mergedRefs, ...rest },
54
+ return (react_1.default.createElement(Root, { theme: theme, themeOptions: themeOptions, ref: mergedRefs, ...rest },
55
55
  react_1.default.createElement(exports.ThemeContext.Provider, { value: contextValue }, children)));
56
56
  });
57
57
  exports.default = exports.ThemeProvider;
58
58
  exports.ThemeContext = react_1.default.createContext(undefined);
59
- const RootWithTheme = react_1.default.forwardRef((props, forwardedRef) => {
59
+ const Root = react_1.default.forwardRef((props, forwardedRef) => {
60
60
  var _a, _b, _c;
61
- const { theme, children, themeOptions, ...rest } = props;
61
+ const { theme, children, themeOptions, as: Element = 'div', className, ...rest } = props;
62
62
  const ref = react_1.default.useRef(null);
63
63
  const mergedRefs = (0, utils_1.useMergedRefs)(ref, forwardedRef);
64
64
  const prefersDark = (0, utils_1.useMediaQuery)('(prefers-color-scheme: dark)');
@@ -67,25 +67,9 @@ const RootWithTheme = react_1.default.forwardRef((props, forwardedRef) => {
67
67
  const shouldApplyHC = (_a = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.highContrast) !== null && _a !== void 0 ? _a : prefersHighContrast;
68
68
  const isThemeAlreadySet = (0, utils_1.useIsThemeAlreadySet)((_b = ref.current) === null || _b === void 0 ? void 0 : _b.ownerDocument);
69
69
  const shouldApplyBackground = (_c = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.applyBackground) !== null && _c !== void 0 ? _c : !isThemeAlreadySet.current;
70
- return (react_1.default.createElement(exports.Root, { withBackground: shouldApplyBackground, "data-iui-theme": shouldApplyDark ? 'dark' : 'light', "data-iui-contrast": shouldApplyHC ? 'high' : 'default', ref: mergedRefs, ...rest }, children));
70
+ return (react_1.default.createElement(Element, { className: (0, classnames_1.default)('iui-root', { 'iui-root-background': shouldApplyBackground }, className), "data-iui-theme": shouldApplyDark ? 'dark' : 'light', "data-iui-contrast": shouldApplyHC ? 'high' : 'default', ref: mergedRefs, ...rest }, children));
71
71
  });
72
72
  const ThemeLogicWrapper = ({ theme, themeOptions }) => {
73
73
  (0, utils_1.useTheme)(theme, themeOptions);
74
74
  return react_1.default.createElement(react_1.default.Fragment, null);
75
75
  };
76
- /**
77
- * Root component that should wrap all iTwinUI components, preventing styles from leaking out of the tree.
78
- *
79
- * This is only needed when it's not possible to use ThemeProvider. For example, when building a package
80
- * using iTwinUI v2, the package should have no opinion on the app theme, but the components in the package
81
- * should probably still be scoped, to prevent potential conflicts with the rest of the page where it's used.
82
- *
83
- * @example
84
- * <Root>
85
- * // UI built using iTwinUI v2
86
- * </Root>
87
- */
88
- exports.Root = react_1.default.forwardRef((props, ref) => {
89
- const { as: Element = 'div', className, withBackground, ...rest } = props;
90
- return (react_1.default.createElement(Element, { className: (0, classnames_1.default)('iui-root', { 'iui-root-background': withBackground }, className), ref: ref, ...rest }));
91
- });
@@ -1,4 +1,4 @@
1
- export { ThemeProvider, Root } from './ThemeProvider';
2
- export type { ThemeProviderProps, RootProps } from './ThemeProvider';
1
+ export { ThemeProvider } from './ThemeProvider';
2
+ export type { ThemeProviderProps } from './ThemeProvider';
3
3
  declare const _default: "./ThemeProvider";
4
4
  export default _default;
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Root = exports.ThemeProvider = void 0;
3
+ exports.ThemeProvider = void 0;
4
4
  /*---------------------------------------------------------------------------------------------
5
5
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
6
6
  * See LICENSE.md in the project root for license terms and full copyright notice.
7
7
  *--------------------------------------------------------------------------------------------*/
8
8
  var ThemeProvider_1 = require("./ThemeProvider");
9
9
  Object.defineProperty(exports, "ThemeProvider", { enumerable: true, get: function () { return ThemeProvider_1.ThemeProvider; } });
10
- Object.defineProperty(exports, "Root", { enumerable: true, get: function () { return ThemeProvider_1.Root; } });
11
10
  exports.default = './ThemeProvider';
@@ -92,8 +92,8 @@ export { TimePicker } from './TimePicker';
92
92
  export type { MeridiemType, TimePickerProps } from './TimePicker';
93
93
  export { default as toaster } from './Toast';
94
94
  export type { ToastOptions } from './Toast';
95
- export { ThemeProvider, Root } from './ThemeProvider';
96
- export type { ThemeProviderProps, RootProps } from './ThemeProvider';
95
+ export { ThemeProvider } from './ThemeProvider';
96
+ export type { ThemeProviderProps } from './ThemeProvider';
97
97
  export { ToggleSwitch } from './ToggleSwitch';
98
98
  export type { ToggleSwitchProps } from './ToggleSwitch';
99
99
  export { Tooltip } from './Tooltip';
@@ -104,5 +104,5 @@ export { Anchor, Body, Headline, Leading, Small, Subheading, Title, Blockquote,
104
104
  export type { AnchorProps, BodyProps, HeadlineProps, LeadingProps, SmallProps, SubheadingProps, TitleProps, BlockquoteProps, CodeProps, KbdProps, TextProps, } from './Typography';
105
105
  export { Wizard, Stepper, WorkflowDiagram } from './Stepper';
106
106
  export type { WizardProps, StepProperties, WizardType, WizardLocalization, StepperProps, StepperLocalization, WorkflowDiagramProps, } from './Stepper';
107
- export { getUserColor, useTheme, ColorValue, MiddleTextTruncation, Icon, } from './utils';
108
- export type { ThemeType, MiddleTextTruncationProps, IconProps } from './utils';
107
+ export { getUserColor, useTheme, ColorValue, MiddleTextTruncation, Icon, Flex, } from './utils';
108
+ export type { ThemeType, MiddleTextTruncationProps, IconProps, FlexProps, FlexItemProps, FlexSpacerProps, } from './utils';
package/cjs/core/index.js CHANGED
@@ -4,8 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.LabeledInput = exports.Label = exports.Input = exports.InformationPanelContent = exports.InformationPanelBody = exports.InformationPanelHeader = exports.InformationPanelWrapper = exports.InformationPanel = exports.HorizontalTabs = exports.Tab = exports.Tabs = exports.VerticalTabs = exports.HeaderLogo = exports.HeaderButton = exports.HeaderBreadcrumbs = exports.Header = exports.defaultFooterElements = exports.Footer = exports.FileUploadTemplate = exports.FileUpload = exports.Fieldset = exports.ExpandableBlock = exports.NonIdealState = exports.ErrorPage = exports.DropdownMenu = exports.Dialog = exports.generateLocalizedStrings = exports.DatePicker = exports.ComboBox = exports.ColorPalette = exports.ColorInputPanel = exports.ColorBuilder = exports.ColorSwatch = exports.ColorPicker = exports.Checkbox = exports.Carousel = exports.ButtonGroup = exports.SplitButton = exports.IdeasButton = exports.IconButton = exports.DropdownButton = exports.Button = exports.Breadcrumbs = exports.Badge = exports.Backdrop = exports.UserIconGroup = exports.AvatarGroup = exports.UserIcon = exports.Avatar = exports.Alert = void 0;
7
- exports.Anchor = exports.TreeNodeExpander = exports.TreeNode = exports.Tree = exports.Tooltip = exports.ToggleSwitch = exports.Root = exports.ThemeProvider = exports.toaster = exports.TimePicker = exports.Tile = exports.Textarea = exports.TagContainer = exports.Tag = exports.SelectionColumn = exports.ExpanderColumn = exports.ActionColumn = exports.TablePaginator = exports.EditableCell = exports.DefaultCell = exports.FilterButtonBar = exports.BaseFilter = exports.tableFilters = exports.Table = exports.Surface = exports.StatusMessage = exports.Slider = exports.SkipToContentLink = exports.SidenavSubmenuHeader = exports.SidenavSubmenu = exports.SidenavButton = exports.SideNavigation = exports.Select = exports.RadioTileGroup = exports.RadioTile = exports.Radio = exports.ProgressRadial = exports.ProgressLinear = exports.NotificationMarker = exports.ModalContent = exports.ModalButtonBar = exports.Modal = exports.MenuItemSkeleton = exports.MenuExtraContent = exports.MenuDivider = exports.MenuItem = exports.Menu = exports.LabeledTextarea = exports.LabeledSelect = exports.InputGroup = void 0;
8
- exports.Icon = exports.MiddleTextTruncation = exports.ColorValue = exports.useTheme = exports.getUserColor = exports.WorkflowDiagram = exports.Stepper = exports.Wizard = exports.Text = exports.KbdKeys = exports.Kbd = exports.Code = exports.Blockquote = exports.Title = exports.Subheading = exports.Small = exports.Leading = exports.Headline = exports.Body = void 0;
7
+ exports.Body = exports.Anchor = exports.TreeNodeExpander = exports.TreeNode = exports.Tree = exports.Tooltip = exports.ToggleSwitch = exports.ThemeProvider = exports.toaster = exports.TimePicker = exports.Tile = exports.Textarea = exports.TagContainer = exports.Tag = exports.SelectionColumn = exports.ExpanderColumn = exports.ActionColumn = exports.TablePaginator = exports.EditableCell = exports.DefaultCell = exports.FilterButtonBar = exports.BaseFilter = exports.tableFilters = exports.Table = exports.Surface = exports.StatusMessage = exports.Slider = exports.SkipToContentLink = exports.SidenavSubmenuHeader = exports.SidenavSubmenu = exports.SidenavButton = exports.SideNavigation = exports.Select = exports.RadioTileGroup = exports.RadioTile = exports.Radio = exports.ProgressRadial = exports.ProgressLinear = exports.NotificationMarker = exports.ModalContent = exports.ModalButtonBar = exports.Modal = exports.MenuItemSkeleton = exports.MenuExtraContent = exports.MenuDivider = exports.MenuItem = exports.Menu = exports.LabeledTextarea = exports.LabeledSelect = exports.InputGroup = void 0;
8
+ exports.Flex = exports.Icon = exports.MiddleTextTruncation = exports.ColorValue = exports.useTheme = exports.getUserColor = exports.WorkflowDiagram = exports.Stepper = exports.Wizard = exports.Text = exports.KbdKeys = exports.Kbd = exports.Code = exports.Blockquote = exports.Title = exports.Subheading = exports.Small = exports.Leading = exports.Headline = void 0;
9
9
  /*---------------------------------------------------------------------------------------------
10
10
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
11
11
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -151,7 +151,6 @@ var Toast_1 = require("./Toast");
151
151
  Object.defineProperty(exports, "toaster", { enumerable: true, get: function () { return __importDefault(Toast_1).default; } });
152
152
  var ThemeProvider_1 = require("./ThemeProvider");
153
153
  Object.defineProperty(exports, "ThemeProvider", { enumerable: true, get: function () { return ThemeProvider_1.ThemeProvider; } });
154
- Object.defineProperty(exports, "Root", { enumerable: true, get: function () { return ThemeProvider_1.Root; } });
155
154
  var ToggleSwitch_1 = require("./ToggleSwitch");
156
155
  Object.defineProperty(exports, "ToggleSwitch", { enumerable: true, get: function () { return ToggleSwitch_1.ToggleSwitch; } });
157
156
  var Tooltip_1 = require("./Tooltip");
@@ -183,3 +182,4 @@ Object.defineProperty(exports, "useTheme", { enumerable: true, get: function ()
183
182
  Object.defineProperty(exports, "ColorValue", { enumerable: true, get: function () { return utils_1.ColorValue; } });
184
183
  Object.defineProperty(exports, "MiddleTextTruncation", { enumerable: true, get: function () { return utils_1.MiddleTextTruncation; } });
185
184
  Object.defineProperty(exports, "Icon", { enumerable: true, get: function () { return utils_1.Icon; } });
185
+ Object.defineProperty(exports, "Flex", { enumerable: true, get: function () { return utils_1.Flex; } });
@@ -0,0 +1,142 @@
1
+ import React from 'react';
2
+ import type { AnyString } from '../types';
3
+ import type { PolymorphicComponentProps, PolymorphicForwardRefComponent } from '../props';
4
+ import '@itwin/itwinui-css/css/utils.css';
5
+ declare const sizeTokens: readonly ["3xs", "2xs", "xs", "s", "m", "l", "xl", "2xl", "3xl"];
6
+ /**
7
+ * String literal shorthands that correspond to the size tokens in [itwinui-variables](https://github.com/iTwin/iTwinUI/blob/main/packages/itwinui-variables/src/sizes.scss).
8
+ */
9
+ declare type SizeToken = typeof sizeTokens[number];
10
+ declare type FlexOwnProps = {
11
+ /**
12
+ * Value of the `display` property.
13
+ * @default 'flex'
14
+ */
15
+ display?: 'flex' | 'inline-flex';
16
+ /**
17
+ * Value of the `justify-content` property.
18
+ * @default 'flex-start'
19
+ */
20
+ justifyContent?: React.CSSProperties['justifyContent'];
21
+ /**
22
+ * Value of the `align-items` property. Defaults to 'center' but you
23
+ * might want to use 'flex-start' in some cases.
24
+ * @default 'center'
25
+ */
26
+ alignItems?: React.CSSProperties['alignItems'];
27
+ /**
28
+ * Value of the `gap` property.
29
+ *
30
+ * Supports aliases for iTwinUI size tokens:
31
+ * 3xs, 2xs, xs, s, m, l, xl, 2xl, 3xl
32
+ *
33
+ * Also accepts any valid css value (e.g. "1rem" or "2px")
34
+ *
35
+ * @default 'xs'
36
+ */
37
+ gap?: SizeToken | AnyString;
38
+ /**
39
+ * Value of the `direction` property.
40
+ * @default 'row'
41
+ */
42
+ flexDirection?: React.CSSProperties['flexDirection'];
43
+ /**
44
+ * Value of the `flex-wrap` property.
45
+ * @default 'nowrap'
46
+ */
47
+ flexWrap?: React.CSSProperties['flexWrap'];
48
+ };
49
+ declare type FlexSpacerOwnProps = {
50
+ /**
51
+ * Value of the `flex` css property.
52
+ *
53
+ * This may need to be adjusted if you're also setting `flex` on
54
+ * other `Flex.Item`s.
55
+ *
56
+ * @default 999
57
+ */
58
+ flex?: React.CSSProperties['flex'];
59
+ };
60
+ declare type FlexItemOwnProps = {
61
+ /**
62
+ * Gap before the flex item, if different from the `gap` set on `Flex` component.
63
+ */
64
+ gapBefore?: SizeToken | AnyString;
65
+ /**
66
+ * Gap after the flex item, if different from the `gap` set on `Flex` component.
67
+ */
68
+ gapAfter?: SizeToken | AnyString;
69
+ /**
70
+ * Value of the `flex` css property.
71
+ * @default 'auto'
72
+ */
73
+ flex?: React.CSSProperties['flex'];
74
+ /**
75
+ * Value of the `align-self` css property.
76
+ * @default 'auto'
77
+ */
78
+ alignSelf?: React.CSSProperties['alignSelf'];
79
+ };
80
+ /**
81
+ * A utility component that makes it easier to work with CSS flexbox
82
+ * and iTwinUI design tokens. Supports all flex properties.
83
+ * Can be used with or without `Flex.Item` and `Flex.Spacer` subcomponents.
84
+ *
85
+ * @example
86
+ * <Flex>
87
+ * <Icon>...</Icon>
88
+ * <Text>...</Text>
89
+ * <Flex.Spacer />
90
+ * <IconButton>...</IconButton>
91
+ * </Flex>
92
+ *
93
+ * @example
94
+ * <Flex gap='m' flexWrap='wrap'>
95
+ * <Flex.Item>...</Flex.Item>
96
+ * <Flex.Item>...</Flex.Item>
97
+ * ...
98
+ * </Flex>
99
+ *
100
+ * @example
101
+ * <Flex gap='l'>
102
+ * <Flex.Item>...</Flex.Item>
103
+ * <Flex.Item>...</Flex.Item>
104
+ * <Flex.Item gapBefore='s'>...</Flex.Item>
105
+ * <Flex.Item>...</Flex.Item>
106
+ * </Flex>
107
+ */
108
+ export declare const Flex: PolymorphicForwardRefComponent<"div", FlexOwnProps> & {
109
+ /**
110
+ * Subcomponent that allows customizing flex items through the
111
+ * `flex`, `alignSelf` and `gapBefore`/`gapAfter` props.
112
+ *
113
+ * The `gapBefore`/`gapAfter` props can used to override the gap at an
114
+ * individual level, for when you need a different gap than the one
115
+ * set in the parent `Flex`.
116
+ *
117
+ * @example
118
+ * <Flex gap='l'>
119
+ * <Flex.Item>...</Flex.Item>
120
+ * <Flex.Item>...</Flex.Item>
121
+ * <Flex.Item gapBefore='s'>...</Flex.Item>
122
+ * <Flex.Item>...</Flex.Item>
123
+ * </Flex>
124
+ */
125
+ Item: PolymorphicForwardRefComponent<"div", FlexItemOwnProps>;
126
+ /**
127
+ * Subcomponent that fills up the available space using a really large `flex` value.
128
+ * Useful when you want to push certain items to one edge.
129
+ *
130
+ * @example
131
+ * <Flex>
132
+ * <div>this stays on the left</div>
133
+ * <Flex.Spacer /> // this fills up the available empty space
134
+ * <div>this gets pushed all the way to the end</div>
135
+ * </Flex>
136
+ */
137
+ Spacer: PolymorphicForwardRefComponent<"div", FlexSpacerOwnProps>;
138
+ };
139
+ export declare type FlexProps = PolymorphicComponentProps<'div', FlexOwnProps>;
140
+ export declare type FlexItemProps = PolymorphicComponentProps<'div', FlexItemOwnProps>;
141
+ export declare type FlexSpacerProps = PolymorphicComponentProps<'div', FlexSpacerOwnProps>;
142
+ export default Flex;
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Flex = void 0;
7
+ /*---------------------------------------------------------------------------------------------
8
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
9
+ * See LICENSE.md in the project root for license terms and full copyright notice.
10
+ *--------------------------------------------------------------------------------------------*/
11
+ const react_1 = __importDefault(require("react"));
12
+ const classnames_1 = __importDefault(require("classnames"));
13
+ require("@itwin/itwinui-css/css/utils.css");
14
+ const sizeTokens = [
15
+ '3xs',
16
+ '2xs',
17
+ 'xs',
18
+ 's',
19
+ 'm',
20
+ 'l',
21
+ 'xl',
22
+ '2xl',
23
+ '3xl',
24
+ ];
25
+ const getValueForToken = (token) => {
26
+ if (sizeTokens.includes(token)) {
27
+ return `var(--iui-size-${token})`;
28
+ }
29
+ return token;
30
+ };
31
+ // ----------------------------------------------------------------------------
32
+ // Main Flex component
33
+ const FlexComponent = react_1.default.forwardRef((props, ref) => {
34
+ const { as: Element = 'div', display, flexDirection, justifyContent, alignItems, gap, flexWrap, className, style, ...rest } = props;
35
+ return (react_1.default.createElement(Element, { className: (0, classnames_1.default)('iui-flex', className), style: {
36
+ '--iui-flex-display': display,
37
+ '--iui-flex-direction': flexDirection,
38
+ '--iui-flex-justify': justifyContent,
39
+ '--iui-flex-align': alignItems,
40
+ '--iui-flex-gap': getValueForToken(gap),
41
+ '--iui-flex-wrap': flexWrap,
42
+ ...style,
43
+ }, ref: ref, ...rest }));
44
+ });
45
+ // ----------------------------------------------------------------------------
46
+ // Flex.Spacer component
47
+ const FlexSpacer = react_1.default.forwardRef((props, ref) => {
48
+ const { as: Element = 'div', flex, className, style, ...rest } = props;
49
+ return (react_1.default.createElement(Element, { className: (0, classnames_1.default)('iui-flex-spacer', className), style: { '--iui-flex-spacer-flex': flex, ...style }, ref: ref, ...rest }));
50
+ });
51
+ // ----------------------------------------------------------------------------
52
+ // Flex.Item subcomponent
53
+ const FlexItem = react_1.default.forwardRef((props, ref) => {
54
+ const { as: Element = 'div', gapBefore, gapAfter, flex, alignSelf, className, style, ...rest } = props;
55
+ const _style = {
56
+ '--iui-flex-item-flex': flex,
57
+ '--iui-flex-item-align': alignSelf,
58
+ '--iui-flex-item-gap-before': getValueForToken(gapBefore),
59
+ '--iui-flex-item-gap-after': getValueForToken(gapAfter),
60
+ ...(gapBefore !== undefined && {
61
+ '--iui-flex-item-gap-before-toggle': 'var(--iui-on)',
62
+ }),
63
+ ...(gapAfter !== undefined && {
64
+ '--iui-flex-item-gap-after-toggle': 'var(--iui-on)',
65
+ }),
66
+ ...style,
67
+ };
68
+ return (react_1.default.createElement(Element, { className: (0, classnames_1.default)('iui-flex-item', className), ref: ref, style: _style, ...rest }));
69
+ });
70
+ // ----------------------------------------------------------------------------
71
+ // Exported compound component
72
+ /**
73
+ * A utility component that makes it easier to work with CSS flexbox
74
+ * and iTwinUI design tokens. Supports all flex properties.
75
+ * Can be used with or without `Flex.Item` and `Flex.Spacer` subcomponents.
76
+ *
77
+ * @example
78
+ * <Flex>
79
+ * <Icon>...</Icon>
80
+ * <Text>...</Text>
81
+ * <Flex.Spacer />
82
+ * <IconButton>...</IconButton>
83
+ * </Flex>
84
+ *
85
+ * @example
86
+ * <Flex gap='m' flexWrap='wrap'>
87
+ * <Flex.Item>...</Flex.Item>
88
+ * <Flex.Item>...</Flex.Item>
89
+ * ...
90
+ * </Flex>
91
+ *
92
+ * @example
93
+ * <Flex gap='l'>
94
+ * <Flex.Item>...</Flex.Item>
95
+ * <Flex.Item>...</Flex.Item>
96
+ * <Flex.Item gapBefore='s'>...</Flex.Item>
97
+ * <Flex.Item>...</Flex.Item>
98
+ * </Flex>
99
+ */
100
+ exports.Flex = Object.assign(FlexComponent, {
101
+ /**
102
+ * Subcomponent that allows customizing flex items through the
103
+ * `flex`, `alignSelf` and `gapBefore`/`gapAfter` props.
104
+ *
105
+ * The `gapBefore`/`gapAfter` props can used to override the gap at an
106
+ * individual level, for when you need a different gap than the one
107
+ * set in the parent `Flex`.
108
+ *
109
+ * @example
110
+ * <Flex gap='l'>
111
+ * <Flex.Item>...</Flex.Item>
112
+ * <Flex.Item>...</Flex.Item>
113
+ * <Flex.Item gapBefore='s'>...</Flex.Item>
114
+ * <Flex.Item>...</Flex.Item>
115
+ * </Flex>
116
+ */
117
+ Item: FlexItem,
118
+ /**
119
+ * Subcomponent that fills up the available space using a really large `flex` value.
120
+ * Useful when you want to push certain items to one edge.
121
+ *
122
+ * @example
123
+ * <Flex>
124
+ * <div>this stays on the left</div>
125
+ * <Flex.Spacer /> // this fills up the available empty space
126
+ * <div>this gets pushed all the way to the end</div>
127
+ * </Flex>
128
+ */
129
+ Spacer: FlexSpacer,
130
+ });
131
+ exports.default = exports.Flex;
@@ -7,3 +7,4 @@ export * from './MiddleTextTruncation';
7
7
  export * from './VirtualScroll';
8
8
  export * from './VisuallyHidden';
9
9
  export * from './Icon';
10
+ export * from './Flex';
@@ -27,3 +27,4 @@ __exportStar(require("./MiddleTextTruncation"), exports);
27
27
  __exportStar(require("./VirtualScroll"), exports);
28
28
  __exportStar(require("./VisuallyHidden"), exports);
29
29
  __exportStar(require("./Icon"), exports);
30
+ __exportStar(require("./Flex"), exports);
@@ -28,12 +28,11 @@ export declare type AvatarProps = {
28
28
  */
29
29
  abbreviation?: string;
30
30
  /**
31
- * User image to be displayed. MUST be an `<img>` element!
31
+ * User image to be displayed. Can be `<img>` or `<svg>` or anything else.
32
32
  */
33
33
  image?: JSX.Element;
34
34
  /**
35
- * Color of the icon. You can use `getUserColor` function to generate color from user name or email.
36
- * @default 'white'
35
+ * Color of the icon. You can use `getUserColor` function to generate color from user name or email. If not provided, default background color from CSS styling will be used (hsl(72, 51%, 56%) / olive green).
37
36
  */
38
37
  backgroundColor?: string;
39
38
  /**
@@ -28,10 +28,12 @@ export const defaultStatusTitles = {
28
28
  * <Avatar size='x-large' title='Terry Rivers' abbreviation='TR' backgroundColor='green' image={<img src="https://cdn.example.com/user/profile/pic.png" />}/>
29
29
  */
30
30
  export const Avatar = (props) => {
31
- const { size = 'small', status, abbreviation, image, backgroundColor = 'white', title, translatedStatusTitles, className, style, ...rest } = props;
31
+ const { size = 'small', status, abbreviation, image, backgroundColor, title, translatedStatusTitles, className, style, ...rest } = props;
32
32
  useTheme();
33
33
  const statusTitles = { ...defaultStatusTitles, ...translatedStatusTitles };
34
- return (React.createElement("span", { className: cx('iui-avatar', { [`iui-${size}`]: size !== 'medium' }, className), title: title, style: style, ...rest }, image !== null && image !== void 0 ? image : (React.createElement("abbr", { className: 'iui-initials', style: { backgroundColor } }, abbreviation === null || abbreviation === void 0 ? void 0 : abbreviation.substring(0, 2))),
34
+ return (React.createElement("span", { className: cx('iui-avatar', { [`iui-${size}`]: size !== 'medium' }, className), title: title, style: { backgroundColor, ...style }, ...rest },
35
+ !image && (React.createElement("abbr", { className: 'iui-initials' }, abbreviation === null || abbreviation === void 0 ? void 0 : abbreviation.substring(0, 2))),
36
+ image,
35
37
  React.createElement("span", { className: 'iui-stroke' }),
36
38
  status && (React.createElement("span", { title: statusTitles[status], className: cx('iui-status', {
37
39
  [`iui-${status}`]: !!status,
@@ -3,7 +3,7 @@ import type { PolymorphicComponentProps, PolymorphicForwardRefComponent, ThemeOp
3
3
  import '@itwin/itwinui-css/css/global.css';
4
4
  import '@itwin/itwinui-variables/index.css';
5
5
  export declare type ThemeProviderProps<T extends React.ElementType = 'div'> = PolymorphicComponentProps<T, ThemeProviderOwnProps>;
6
- declare type RootWithThemeProps = {
6
+ declare type RootProps = {
7
7
  /**
8
8
  * Theme to be applied. Can be 'light' or 'dark' or 'os'.
9
9
  *
@@ -27,8 +27,8 @@ declare type RootWithThemeProps = {
27
27
  applyBackground?: boolean;
28
28
  };
29
29
  };
30
- declare type ThemeProviderOwnProps = Pick<RootWithThemeProps, 'theme'> & ({
31
- themeOptions?: RootWithThemeProps['themeOptions'];
30
+ declare type ThemeProviderOwnProps = Pick<RootProps, 'theme'> & ({
31
+ themeOptions?: RootProps['themeOptions'];
32
32
  children: Required<React.ReactNode>;
33
33
  } | {
34
34
  themeOptions?: ThemeOptions;
@@ -67,23 +67,3 @@ export declare const ThemeContext: React.Context<{
67
67
  themeOptions?: ThemeOptions | undefined;
68
68
  rootRef: React.RefObject<HTMLElement>;
69
69
  } | undefined>;
70
- /**
71
- * Root component that should wrap all iTwinUI components, preventing styles from leaking out of the tree.
72
- *
73
- * This is only needed when it's not possible to use ThemeProvider. For example, when building a package
74
- * using iTwinUI v2, the package should have no opinion on the app theme, but the components in the package
75
- * should probably still be scoped, to prevent potential conflicts with the rest of the page where it's used.
76
- *
77
- * @example
78
- * <Root>
79
- * // UI built using iTwinUI v2
80
- * </Root>
81
- */
82
- export declare const Root: PolymorphicForwardRefComponent<"div", RootProps>;
83
- export declare type RootProps = {
84
- /**
85
- * Whether or not the root should have the recommended `background-color`.
86
- * This is usually only relevant for the topmost root on the page.
87
- */
88
- withBackground?: boolean;
89
- } & React.ComponentProps<'div'>;
@@ -45,14 +45,14 @@ export const ThemeProvider = React.forwardRef((props, ref) => {
45
45
  return (React.createElement(ThemeLogicWrapper, { theme: theme !== null && theme !== void 0 ? theme : parentContext === null || parentContext === void 0 ? void 0 : parentContext.theme, themeOptions: themeOptions !== null && themeOptions !== void 0 ? themeOptions : parentContext === null || parentContext === void 0 ? void 0 : parentContext.themeOptions }));
46
46
  }
47
47
  // now that we know there are children, we can render the root and provide the context value
48
- return (React.createElement(RootWithTheme, { theme: theme, themeOptions: themeOptions, ref: mergedRefs, ...rest },
48
+ return (React.createElement(Root, { theme: theme, themeOptions: themeOptions, ref: mergedRefs, ...rest },
49
49
  React.createElement(ThemeContext.Provider, { value: contextValue }, children)));
50
50
  });
51
51
  export default ThemeProvider;
52
52
  export const ThemeContext = React.createContext(undefined);
53
- const RootWithTheme = React.forwardRef((props, forwardedRef) => {
53
+ const Root = React.forwardRef((props, forwardedRef) => {
54
54
  var _a, _b, _c;
55
- const { theme, children, themeOptions, ...rest } = props;
55
+ const { theme, children, themeOptions, as: Element = 'div', className, ...rest } = props;
56
56
  const ref = React.useRef(null);
57
57
  const mergedRefs = useMergedRefs(ref, forwardedRef);
58
58
  const prefersDark = useMediaQuery('(prefers-color-scheme: dark)');
@@ -61,25 +61,9 @@ const RootWithTheme = React.forwardRef((props, forwardedRef) => {
61
61
  const shouldApplyHC = (_a = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.highContrast) !== null && _a !== void 0 ? _a : prefersHighContrast;
62
62
  const isThemeAlreadySet = useIsThemeAlreadySet((_b = ref.current) === null || _b === void 0 ? void 0 : _b.ownerDocument);
63
63
  const shouldApplyBackground = (_c = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.applyBackground) !== null && _c !== void 0 ? _c : !isThemeAlreadySet.current;
64
- return (React.createElement(Root, { withBackground: shouldApplyBackground, "data-iui-theme": shouldApplyDark ? 'dark' : 'light', "data-iui-contrast": shouldApplyHC ? 'high' : 'default', ref: mergedRefs, ...rest }, children));
64
+ return (React.createElement(Element, { className: cx('iui-root', { 'iui-root-background': shouldApplyBackground }, className), "data-iui-theme": shouldApplyDark ? 'dark' : 'light', "data-iui-contrast": shouldApplyHC ? 'high' : 'default', ref: mergedRefs, ...rest }, children));
65
65
  });
66
66
  const ThemeLogicWrapper = ({ theme, themeOptions }) => {
67
67
  useTheme(theme, themeOptions);
68
68
  return React.createElement(React.Fragment, null);
69
69
  };
70
- /**
71
- * Root component that should wrap all iTwinUI components, preventing styles from leaking out of the tree.
72
- *
73
- * This is only needed when it's not possible to use ThemeProvider. For example, when building a package
74
- * using iTwinUI v2, the package should have no opinion on the app theme, but the components in the package
75
- * should probably still be scoped, to prevent potential conflicts with the rest of the page where it's used.
76
- *
77
- * @example
78
- * <Root>
79
- * // UI built using iTwinUI v2
80
- * </Root>
81
- */
82
- export const Root = React.forwardRef((props, ref) => {
83
- const { as: Element = 'div', className, withBackground, ...rest } = props;
84
- return (React.createElement(Element, { className: cx('iui-root', { 'iui-root-background': withBackground }, className), ref: ref, ...rest }));
85
- });
@@ -1,4 +1,4 @@
1
- export { ThemeProvider, Root } from './ThemeProvider';
2
- export type { ThemeProviderProps, RootProps } from './ThemeProvider';
1
+ export { ThemeProvider } from './ThemeProvider';
2
+ export type { ThemeProviderProps } from './ThemeProvider';
3
3
  declare const _default: "./ThemeProvider";
4
4
  export default _default;
@@ -2,5 +2,5 @@
2
2
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
3
  * See LICENSE.md in the project root for license terms and full copyright notice.
4
4
  *--------------------------------------------------------------------------------------------*/
5
- export { ThemeProvider, Root } from './ThemeProvider';
5
+ export { ThemeProvider } from './ThemeProvider';
6
6
  export default './ThemeProvider';
@@ -92,8 +92,8 @@ export { TimePicker } from './TimePicker';
92
92
  export type { MeridiemType, TimePickerProps } from './TimePicker';
93
93
  export { default as toaster } from './Toast';
94
94
  export type { ToastOptions } from './Toast';
95
- export { ThemeProvider, Root } from './ThemeProvider';
96
- export type { ThemeProviderProps, RootProps } from './ThemeProvider';
95
+ export { ThemeProvider } from './ThemeProvider';
96
+ export type { ThemeProviderProps } from './ThemeProvider';
97
97
  export { ToggleSwitch } from './ToggleSwitch';
98
98
  export type { ToggleSwitchProps } from './ToggleSwitch';
99
99
  export { Tooltip } from './Tooltip';
@@ -104,5 +104,5 @@ export { Anchor, Body, Headline, Leading, Small, Subheading, Title, Blockquote,
104
104
  export type { AnchorProps, BodyProps, HeadlineProps, LeadingProps, SmallProps, SubheadingProps, TitleProps, BlockquoteProps, CodeProps, KbdProps, TextProps, } from './Typography';
105
105
  export { Wizard, Stepper, WorkflowDiagram } from './Stepper';
106
106
  export type { WizardProps, StepProperties, WizardType, WizardLocalization, StepperProps, StepperLocalization, WorkflowDiagramProps, } from './Stepper';
107
- export { getUserColor, useTheme, ColorValue, MiddleTextTruncation, Icon, } from './utils';
108
- export type { ThemeType, MiddleTextTruncationProps, IconProps } from './utils';
107
+ export { getUserColor, useTheme, ColorValue, MiddleTextTruncation, Icon, Flex, } from './utils';
108
+ export type { ThemeType, MiddleTextTruncationProps, IconProps, FlexProps, FlexItemProps, FlexSpacerProps, } from './utils';
package/esm/core/index.js CHANGED
@@ -49,10 +49,10 @@ export { Textarea } from './Textarea';
49
49
  export { Tile } from './Tile';
50
50
  export { TimePicker } from './TimePicker';
51
51
  export { default as toaster } from './Toast';
52
- export { ThemeProvider, Root } from './ThemeProvider';
52
+ export { ThemeProvider } from './ThemeProvider';
53
53
  export { ToggleSwitch } from './ToggleSwitch';
54
54
  export { Tooltip } from './Tooltip';
55
55
  export { Tree, TreeNode, TreeNodeExpander } from './Tree';
56
56
  export { Anchor, Body, Headline, Leading, Small, Subheading, Title, Blockquote, Code, Kbd, KbdKeys, Text, } from './Typography';
57
57
  export { Wizard, Stepper, WorkflowDiagram } from './Stepper';
58
- export { getUserColor, useTheme, ColorValue, MiddleTextTruncation, Icon, } from './utils';
58
+ export { getUserColor, useTheme, ColorValue, MiddleTextTruncation, Icon, Flex, } from './utils';
@@ -0,0 +1,142 @@
1
+ import React from 'react';
2
+ import type { AnyString } from '../types';
3
+ import type { PolymorphicComponentProps, PolymorphicForwardRefComponent } from '../props';
4
+ import '@itwin/itwinui-css/css/utils.css';
5
+ declare const sizeTokens: readonly ["3xs", "2xs", "xs", "s", "m", "l", "xl", "2xl", "3xl"];
6
+ /**
7
+ * String literal shorthands that correspond to the size tokens in [itwinui-variables](https://github.com/iTwin/iTwinUI/blob/main/packages/itwinui-variables/src/sizes.scss).
8
+ */
9
+ declare type SizeToken = typeof sizeTokens[number];
10
+ declare type FlexOwnProps = {
11
+ /**
12
+ * Value of the `display` property.
13
+ * @default 'flex'
14
+ */
15
+ display?: 'flex' | 'inline-flex';
16
+ /**
17
+ * Value of the `justify-content` property.
18
+ * @default 'flex-start'
19
+ */
20
+ justifyContent?: React.CSSProperties['justifyContent'];
21
+ /**
22
+ * Value of the `align-items` property. Defaults to 'center' but you
23
+ * might want to use 'flex-start' in some cases.
24
+ * @default 'center'
25
+ */
26
+ alignItems?: React.CSSProperties['alignItems'];
27
+ /**
28
+ * Value of the `gap` property.
29
+ *
30
+ * Supports aliases for iTwinUI size tokens:
31
+ * 3xs, 2xs, xs, s, m, l, xl, 2xl, 3xl
32
+ *
33
+ * Also accepts any valid css value (e.g. "1rem" or "2px")
34
+ *
35
+ * @default 'xs'
36
+ */
37
+ gap?: SizeToken | AnyString;
38
+ /**
39
+ * Value of the `direction` property.
40
+ * @default 'row'
41
+ */
42
+ flexDirection?: React.CSSProperties['flexDirection'];
43
+ /**
44
+ * Value of the `flex-wrap` property.
45
+ * @default 'nowrap'
46
+ */
47
+ flexWrap?: React.CSSProperties['flexWrap'];
48
+ };
49
+ declare type FlexSpacerOwnProps = {
50
+ /**
51
+ * Value of the `flex` css property.
52
+ *
53
+ * This may need to be adjusted if you're also setting `flex` on
54
+ * other `Flex.Item`s.
55
+ *
56
+ * @default 999
57
+ */
58
+ flex?: React.CSSProperties['flex'];
59
+ };
60
+ declare type FlexItemOwnProps = {
61
+ /**
62
+ * Gap before the flex item, if different from the `gap` set on `Flex` component.
63
+ */
64
+ gapBefore?: SizeToken | AnyString;
65
+ /**
66
+ * Gap after the flex item, if different from the `gap` set on `Flex` component.
67
+ */
68
+ gapAfter?: SizeToken | AnyString;
69
+ /**
70
+ * Value of the `flex` css property.
71
+ * @default 'auto'
72
+ */
73
+ flex?: React.CSSProperties['flex'];
74
+ /**
75
+ * Value of the `align-self` css property.
76
+ * @default 'auto'
77
+ */
78
+ alignSelf?: React.CSSProperties['alignSelf'];
79
+ };
80
+ /**
81
+ * A utility component that makes it easier to work with CSS flexbox
82
+ * and iTwinUI design tokens. Supports all flex properties.
83
+ * Can be used with or without `Flex.Item` and `Flex.Spacer` subcomponents.
84
+ *
85
+ * @example
86
+ * <Flex>
87
+ * <Icon>...</Icon>
88
+ * <Text>...</Text>
89
+ * <Flex.Spacer />
90
+ * <IconButton>...</IconButton>
91
+ * </Flex>
92
+ *
93
+ * @example
94
+ * <Flex gap='m' flexWrap='wrap'>
95
+ * <Flex.Item>...</Flex.Item>
96
+ * <Flex.Item>...</Flex.Item>
97
+ * ...
98
+ * </Flex>
99
+ *
100
+ * @example
101
+ * <Flex gap='l'>
102
+ * <Flex.Item>...</Flex.Item>
103
+ * <Flex.Item>...</Flex.Item>
104
+ * <Flex.Item gapBefore='s'>...</Flex.Item>
105
+ * <Flex.Item>...</Flex.Item>
106
+ * </Flex>
107
+ */
108
+ export declare const Flex: PolymorphicForwardRefComponent<"div", FlexOwnProps> & {
109
+ /**
110
+ * Subcomponent that allows customizing flex items through the
111
+ * `flex`, `alignSelf` and `gapBefore`/`gapAfter` props.
112
+ *
113
+ * The `gapBefore`/`gapAfter` props can used to override the gap at an
114
+ * individual level, for when you need a different gap than the one
115
+ * set in the parent `Flex`.
116
+ *
117
+ * @example
118
+ * <Flex gap='l'>
119
+ * <Flex.Item>...</Flex.Item>
120
+ * <Flex.Item>...</Flex.Item>
121
+ * <Flex.Item gapBefore='s'>...</Flex.Item>
122
+ * <Flex.Item>...</Flex.Item>
123
+ * </Flex>
124
+ */
125
+ Item: PolymorphicForwardRefComponent<"div", FlexItemOwnProps>;
126
+ /**
127
+ * Subcomponent that fills up the available space using a really large `flex` value.
128
+ * Useful when you want to push certain items to one edge.
129
+ *
130
+ * @example
131
+ * <Flex>
132
+ * <div>this stays on the left</div>
133
+ * <Flex.Spacer /> // this fills up the available empty space
134
+ * <div>this gets pushed all the way to the end</div>
135
+ * </Flex>
136
+ */
137
+ Spacer: PolymorphicForwardRefComponent<"div", FlexSpacerOwnProps>;
138
+ };
139
+ export declare type FlexProps = PolymorphicComponentProps<'div', FlexOwnProps>;
140
+ export declare type FlexItemProps = PolymorphicComponentProps<'div', FlexItemOwnProps>;
141
+ export declare type FlexSpacerProps = PolymorphicComponentProps<'div', FlexSpacerOwnProps>;
142
+ export default Flex;
@@ -0,0 +1,125 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import React from 'react';
6
+ import cx from 'classnames';
7
+ import '@itwin/itwinui-css/css/utils.css';
8
+ const sizeTokens = [
9
+ '3xs',
10
+ '2xs',
11
+ 'xs',
12
+ 's',
13
+ 'm',
14
+ 'l',
15
+ 'xl',
16
+ '2xl',
17
+ '3xl',
18
+ ];
19
+ const getValueForToken = (token) => {
20
+ if (sizeTokens.includes(token)) {
21
+ return `var(--iui-size-${token})`;
22
+ }
23
+ return token;
24
+ };
25
+ // ----------------------------------------------------------------------------
26
+ // Main Flex component
27
+ const FlexComponent = React.forwardRef((props, ref) => {
28
+ const { as: Element = 'div', display, flexDirection, justifyContent, alignItems, gap, flexWrap, className, style, ...rest } = props;
29
+ return (React.createElement(Element, { className: cx('iui-flex', className), style: {
30
+ '--iui-flex-display': display,
31
+ '--iui-flex-direction': flexDirection,
32
+ '--iui-flex-justify': justifyContent,
33
+ '--iui-flex-align': alignItems,
34
+ '--iui-flex-gap': getValueForToken(gap),
35
+ '--iui-flex-wrap': flexWrap,
36
+ ...style,
37
+ }, ref: ref, ...rest }));
38
+ });
39
+ // ----------------------------------------------------------------------------
40
+ // Flex.Spacer component
41
+ const FlexSpacer = React.forwardRef((props, ref) => {
42
+ const { as: Element = 'div', flex, className, style, ...rest } = props;
43
+ return (React.createElement(Element, { className: cx('iui-flex-spacer', className), style: { '--iui-flex-spacer-flex': flex, ...style }, ref: ref, ...rest }));
44
+ });
45
+ // ----------------------------------------------------------------------------
46
+ // Flex.Item subcomponent
47
+ const FlexItem = React.forwardRef((props, ref) => {
48
+ const { as: Element = 'div', gapBefore, gapAfter, flex, alignSelf, className, style, ...rest } = props;
49
+ const _style = {
50
+ '--iui-flex-item-flex': flex,
51
+ '--iui-flex-item-align': alignSelf,
52
+ '--iui-flex-item-gap-before': getValueForToken(gapBefore),
53
+ '--iui-flex-item-gap-after': getValueForToken(gapAfter),
54
+ ...(gapBefore !== undefined && {
55
+ '--iui-flex-item-gap-before-toggle': 'var(--iui-on)',
56
+ }),
57
+ ...(gapAfter !== undefined && {
58
+ '--iui-flex-item-gap-after-toggle': 'var(--iui-on)',
59
+ }),
60
+ ...style,
61
+ };
62
+ return (React.createElement(Element, { className: cx('iui-flex-item', className), ref: ref, style: _style, ...rest }));
63
+ });
64
+ // ----------------------------------------------------------------------------
65
+ // Exported compound component
66
+ /**
67
+ * A utility component that makes it easier to work with CSS flexbox
68
+ * and iTwinUI design tokens. Supports all flex properties.
69
+ * Can be used with or without `Flex.Item` and `Flex.Spacer` subcomponents.
70
+ *
71
+ * @example
72
+ * <Flex>
73
+ * <Icon>...</Icon>
74
+ * <Text>...</Text>
75
+ * <Flex.Spacer />
76
+ * <IconButton>...</IconButton>
77
+ * </Flex>
78
+ *
79
+ * @example
80
+ * <Flex gap='m' flexWrap='wrap'>
81
+ * <Flex.Item>...</Flex.Item>
82
+ * <Flex.Item>...</Flex.Item>
83
+ * ...
84
+ * </Flex>
85
+ *
86
+ * @example
87
+ * <Flex gap='l'>
88
+ * <Flex.Item>...</Flex.Item>
89
+ * <Flex.Item>...</Flex.Item>
90
+ * <Flex.Item gapBefore='s'>...</Flex.Item>
91
+ * <Flex.Item>...</Flex.Item>
92
+ * </Flex>
93
+ */
94
+ export const Flex = Object.assign(FlexComponent, {
95
+ /**
96
+ * Subcomponent that allows customizing flex items through the
97
+ * `flex`, `alignSelf` and `gapBefore`/`gapAfter` props.
98
+ *
99
+ * The `gapBefore`/`gapAfter` props can used to override the gap at an
100
+ * individual level, for when you need a different gap than the one
101
+ * set in the parent `Flex`.
102
+ *
103
+ * @example
104
+ * <Flex gap='l'>
105
+ * <Flex.Item>...</Flex.Item>
106
+ * <Flex.Item>...</Flex.Item>
107
+ * <Flex.Item gapBefore='s'>...</Flex.Item>
108
+ * <Flex.Item>...</Flex.Item>
109
+ * </Flex>
110
+ */
111
+ Item: FlexItem,
112
+ /**
113
+ * Subcomponent that fills up the available space using a really large `flex` value.
114
+ * Useful when you want to push certain items to one edge.
115
+ *
116
+ * @example
117
+ * <Flex>
118
+ * <div>this stays on the left</div>
119
+ * <Flex.Spacer /> // this fills up the available empty space
120
+ * <div>this gets pushed all the way to the end</div>
121
+ * </Flex>
122
+ */
123
+ Spacer: FlexSpacer,
124
+ });
125
+ export default Flex;
@@ -7,3 +7,4 @@ export * from './MiddleTextTruncation';
7
7
  export * from './VirtualScroll';
8
8
  export * from './VisuallyHidden';
9
9
  export * from './Icon';
10
+ export * from './Flex';
@@ -11,3 +11,4 @@ export * from './MiddleTextTruncation';
11
11
  export * from './VirtualScroll';
12
12
  export * from './VisuallyHidden';
13
13
  export * from './Icon';
14
+ export * from './Flex';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/itwinui-react",
3
- "version": "2.4.0-dev.2",
3
+ "version": "2.4.0",
4
4
  "author": "Bentley Systems",
5
5
  "license": "MIT",
6
6
  "main": "cjs/index.js",
@@ -62,9 +62,9 @@
62
62
  "dev:types": "concurrently \"tsc -p tsconfig.cjs.json --emitDeclarationOnly --watch --preserveWatchOutput\" \"tsc -p tsconfig.esm.json --emitDeclarationOnly --watch --preserveWatchOutput\""
63
63
  },
64
64
  "dependencies": {
65
- "@itwin/itwinui-css": "1.5.0-dev.1",
65
+ "@itwin/itwinui-css": "^1.5.0",
66
66
  "@itwin/itwinui-illustrations-react": "^2.0.0",
67
- "@itwin/itwinui-variables": "2.0.0-dev.0",
67
+ "@itwin/itwinui-variables": "^1.0.0",
68
68
  "@tippyjs/react": "^4.2.6",
69
69
  "@types/react-table": "^7.0.18",
70
70
  "classnames": "^2.2.6",