@itwin/itwinui-react 1.32.0 → 1.33.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 +9 -0
- package/cjs/core/ButtonGroup/ButtonGroup.d.ts +8 -1
- package/cjs/core/ButtonGroup/ButtonGroup.js +7 -3
- package/cjs/core/ComboBox/ComboBox.d.ts +6 -1
- package/cjs/core/ComboBox/ComboBox.js +4 -2
- package/cjs/core/Footer/Footer.d.ts +14 -2
- package/cjs/core/Footer/Footer.js +40 -17
- package/cjs/core/InputGroup/InputGroup.js +12 -2
- package/cjs/core/LabeledSelect/LabeledSelect.js +10 -4
- package/cjs/core/StatusMessage/StatusMessage.d.ts +24 -0
- package/cjs/core/StatusMessage/StatusMessage.js +39 -0
- package/cjs/core/StatusMessage/index.d.ts +4 -0
- package/cjs/core/StatusMessage/index.js +10 -0
- package/cjs/core/index.d.ts +2 -0
- package/cjs/core/index.js +3 -1
- package/cjs/core/utils/components/InputContainer.d.ts +1 -0
- package/cjs/core/utils/components/InputContainer.js +8 -7
- package/esm/core/ButtonGroup/ButtonGroup.d.ts +8 -1
- package/esm/core/ButtonGroup/ButtonGroup.js +7 -3
- package/esm/core/ComboBox/ComboBox.d.ts +6 -1
- package/esm/core/ComboBox/ComboBox.js +4 -2
- package/esm/core/Footer/Footer.d.ts +14 -2
- package/esm/core/Footer/Footer.js +40 -17
- package/esm/core/InputGroup/InputGroup.js +12 -2
- package/esm/core/LabeledSelect/LabeledSelect.js +10 -4
- package/esm/core/StatusMessage/StatusMessage.d.ts +24 -0
- package/esm/core/StatusMessage/StatusMessage.js +32 -0
- package/esm/core/StatusMessage/index.d.ts +4 -0
- package/esm/core/StatusMessage/index.js +6 -0
- package/esm/core/index.d.ts +2 -0
- package/esm/core/index.js +1 -0
- package/esm/core/utils/components/InputContainer.d.ts +1 -0
- package/esm/core/utils/components/InputContainer.js +8 -7
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.33.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.32.0...v1.33.0) (2022-03-07)
|
|
4
|
+
|
|
5
|
+
### What's new
|
|
6
|
+
|
|
7
|
+
* **ButtonGroup:** Add new `orientation` prop to allow showing vertical group ([#577](https://www.github.com/iTwin/iTwinUI-react/issues/577)) ([f6cd52f](https://www.github.com/iTwin/iTwinUI-react/commit/f6cd52f39dd139439281114d3ade99e486ab6bfb))
|
|
8
|
+
* **ComboBox:** Add new `message` prop ([#554](https://www.github.com/iTwin/iTwinUI-react/issues/554)) ([8113860](https://www.github.com/iTwin/iTwinUI-react/commit/8113860499e6156d97992919204b3b8c7e46197b))
|
|
9
|
+
* This new prop can accept a string or the new `StatusMessage` component for customizing icon.
|
|
10
|
+
* **Footer:** Allow overriding and removing default footer elements ([#544](https://www.github.com/iTwin/iTwinUI-react/issues/544)) ([76396a4](https://www.github.com/iTwin/iTwinUI-react/commit/76396a4cc0a88bb7680316cf4642b732729abd7a))
|
|
11
|
+
|
|
3
12
|
## [1.32.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.31.0...v1.32.0) (2022-02-25)
|
|
4
13
|
|
|
5
14
|
### What's new
|
|
@@ -13,6 +13,8 @@ export declare type ButtonGroupProps = {
|
|
|
13
13
|
* and returns the `ReactNode` to render.
|
|
14
14
|
*
|
|
15
15
|
* The placement of this button can be controlled using the `overflowPlacement` prop.
|
|
16
|
+
*
|
|
17
|
+
* *Note: this will not work with `orientation='vertical'`.*
|
|
16
18
|
*/
|
|
17
19
|
overflowButton?: (firstOverflowingIndex: number) => React.ReactNode;
|
|
18
20
|
/**
|
|
@@ -20,6 +22,11 @@ export declare type ButtonGroupProps = {
|
|
|
20
22
|
* @default 'end'
|
|
21
23
|
*/
|
|
22
24
|
overflowPlacement?: 'start' | 'end';
|
|
25
|
+
/**
|
|
26
|
+
* Should the buttons be placed in a horizontal or vertical layout?
|
|
27
|
+
* @default 'horizontal'
|
|
28
|
+
*/
|
|
29
|
+
orientation?: 'horizontal' | 'vertical';
|
|
23
30
|
} & React.ComponentPropsWithRef<'div'>;
|
|
24
31
|
/**
|
|
25
32
|
* Group buttons together for common actions.
|
|
@@ -49,5 +56,5 @@ export declare type ButtonGroupProps = {
|
|
|
49
56
|
* {buttons}
|
|
50
57
|
* </ButtonGroup>
|
|
51
58
|
*/
|
|
52
|
-
export declare const ButtonGroup: React.ForwardRefExoticComponent<Pick<ButtonGroupProps, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "overflowButton" | "overflowPlacement"> & React.RefAttributes<HTMLDivElement>>;
|
|
59
|
+
export declare const ButtonGroup: React.ForwardRefExoticComponent<Pick<ButtonGroupProps, "orientation" | "key" | keyof React.HTMLAttributes<HTMLDivElement> | "overflowButton" | "overflowPlacement"> & React.RefAttributes<HTMLDivElement>>;
|
|
53
60
|
export default ButtonGroup;
|
|
@@ -63,12 +63,16 @@ require("@itwin/itwinui-css/css/button.css");
|
|
|
63
63
|
* </ButtonGroup>
|
|
64
64
|
*/
|
|
65
65
|
exports.ButtonGroup = react_1.default.forwardRef(function (props, ref) {
|
|
66
|
-
var children = props.children, className = props.className, style = props.style, overflowButton = props.overflowButton, _a = props.overflowPlacement, overflowPlacement = _a === void 0 ? 'end' : _a, rest = __rest(props, ["children", "className", "style", "overflowButton", "overflowPlacement"]);
|
|
66
|
+
var children = props.children, className = props.className, style = props.style, overflowButton = props.overflowButton, _a = props.overflowPlacement, overflowPlacement = _a === void 0 ? 'end' : _a, _b = props.orientation, orientation = _b === void 0 ? 'horizontal' : _b, rest = __rest(props, ["children", "className", "style", "overflowButton", "overflowPlacement", "orientation"]);
|
|
67
67
|
var items = react_1.default.useMemo(function () { var _a; return (_a = react_1.default.Children.map(children, function (child) { return react_1.default.createElement("div", null, child); })) !== null && _a !== void 0 ? _a : []; }, [children]);
|
|
68
68
|
(0, utils_1.useTheme)();
|
|
69
|
-
var
|
|
69
|
+
var _c = (0, utils_1.useOverflow)(items, !overflowButton), overflowRef = _c[0], visibleCount = _c[1];
|
|
70
70
|
var refs = (0, utils_1.useMergedRefs)(overflowRef, ref);
|
|
71
|
-
return (react_1.default.createElement("div", __assign({ className: (0, classnames_1.default)(
|
|
71
|
+
return (react_1.default.createElement("div", __assign({ className: (0, classnames_1.default)({
|
|
72
|
+
'iui-button-group': orientation === 'horizontal',
|
|
73
|
+
'iui-button-group-vertical': orientation === 'vertical',
|
|
74
|
+
}, className), style: __assign(__assign({}, (!!overflowButton &&
|
|
75
|
+
orientation === 'horizontal' && { width: '100%' })), style), "aria-orientation": orientation, ref: refs }, rest), !!overflowButton && visibleCount < items.length ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
72
76
|
overflowButton && overflowPlacement === 'start' && (react_1.default.createElement("div", null, overflowButton(visibleCount))),
|
|
73
77
|
items.slice(0, visibleCount - 1),
|
|
74
78
|
overflowButton && overflowPlacement === 'end' && (react_1.default.createElement("div", null, overflowButton(visibleCount))))) : (items)));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { InputProps } from '../Input';
|
|
3
3
|
import { SelectOption } from '../Select';
|
|
4
4
|
import { PopoverProps, CommonProps, InputContainerProps } from '../utils';
|
|
@@ -12,6 +12,11 @@ export declare type ComboBoxProps<T> = {
|
|
|
12
12
|
* Controlled value of ComboBox.
|
|
13
13
|
*/
|
|
14
14
|
value?: T;
|
|
15
|
+
/**
|
|
16
|
+
* Message shown below the combobox.
|
|
17
|
+
* Use `StatusMessage` component.
|
|
18
|
+
*/
|
|
19
|
+
message?: React.ReactNode;
|
|
15
20
|
/**
|
|
16
21
|
* Callback fired when selected value changes.
|
|
17
22
|
*/
|
|
@@ -38,6 +38,7 @@ var Typography_1 = require("../Typography");
|
|
|
38
38
|
var utils_1 = require("../utils");
|
|
39
39
|
var CaretDownSmall_1 = __importDefault(require("@itwin/itwinui-icons-react/cjs/icons/CaretDownSmall"));
|
|
40
40
|
require("tippy.js/animations/shift-away.css");
|
|
41
|
+
var StatusMessage_1 = require("../StatusMessage");
|
|
41
42
|
/**
|
|
42
43
|
* ComboBox component that allows typing a value to filter the options in dropdown list.
|
|
43
44
|
* Values can be selected either using mouse clicks or using the Enter key.
|
|
@@ -52,7 +53,7 @@ require("tippy.js/animations/shift-away.css");
|
|
|
52
53
|
* />
|
|
53
54
|
*/
|
|
54
55
|
var ComboBox = function (props) {
|
|
55
|
-
var options = props.options, value = props.value, onChange = props.onChange, filterFunction = props.filterFunction, className = props.className, inputProps = props.inputProps, dropdownMenuProps = props.dropdownMenuProps, _a = props.emptyStateMessage, emptyStateMessage = _a === void 0 ? 'No options found' : _a, itemRenderer = props.itemRenderer, rest = __rest(props, ["options", "value", "onChange", "filterFunction", "className", "inputProps", "dropdownMenuProps", "emptyStateMessage", "itemRenderer"]);
|
|
56
|
+
var options = props.options, value = props.value, onChange = props.onChange, filterFunction = props.filterFunction, className = props.className, inputProps = props.inputProps, dropdownMenuProps = props.dropdownMenuProps, message = props.message, status = props.status, _a = props.emptyStateMessage, emptyStateMessage = _a === void 0 ? 'No options found' : _a, itemRenderer = props.itemRenderer, rest = __rest(props, ["options", "value", "onChange", "filterFunction", "className", "inputProps", "dropdownMenuProps", "message", "status", "emptyStateMessage", "itemRenderer"]);
|
|
56
57
|
// Generate a stateful random id if not specified
|
|
57
58
|
var id = react_1.default.useState(function () {
|
|
58
59
|
var _a, _b;
|
|
@@ -274,7 +275,8 @@ var ComboBox = function (props) {
|
|
|
274
275
|
itemRenderer,
|
|
275
276
|
memoizedItems,
|
|
276
277
|
]);
|
|
277
|
-
return (react_1.default.createElement(utils_1.InputContainer, __assign({ className: className,
|
|
278
|
+
return (react_1.default.createElement(utils_1.InputContainer, __assign({ className: className, status: status, statusMessage: typeof message === 'string' ? (react_1.default.createElement(StatusMessage_1.StatusMessage, { status: status }, message)) : (react_1.default.isValidElement(message) &&
|
|
279
|
+
react_1.default.cloneElement(message, { status: status })) }, rest, { id: id }),
|
|
278
280
|
react_1.default.createElement("div", { className: 'iui-input-with-icon' },
|
|
279
281
|
react_1.default.createElement(utils_1.Popover, __assign({ placement: 'bottom-start', visible: isOpen, onClickOutside: function (_, _a) {
|
|
280
282
|
var _b;
|
|
@@ -11,8 +11,10 @@ export declare type TitleTranslations = {
|
|
|
11
11
|
export declare type FooterProps = {
|
|
12
12
|
/**
|
|
13
13
|
* Customize footer elements.
|
|
14
|
+
* Providing a `FooterElement[]` will append the custom elements to the end of the default elements.
|
|
15
|
+
* Providing a function that returns a `FooterElement[]` allows further customization - whatever is returned from the function is displayed in the footer with no amendments.
|
|
14
16
|
*/
|
|
15
|
-
customElements?: FooterElement[];
|
|
17
|
+
customElements?: FooterElement[] | ((defaultElements: FooterElement[]) => FooterElement[]);
|
|
16
18
|
/**
|
|
17
19
|
* Provide localized strings.
|
|
18
20
|
*/
|
|
@@ -27,13 +29,23 @@ export declare type FooterElement = {
|
|
|
27
29
|
* URL of the footer element.
|
|
28
30
|
*/
|
|
29
31
|
url?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Key of the footer element.
|
|
34
|
+
*/
|
|
35
|
+
key?: keyof TitleTranslations | 'copyright' | (string & Record<never, never>);
|
|
30
36
|
};
|
|
31
37
|
/**
|
|
32
38
|
* Footer element with all needed legal and info links.
|
|
33
39
|
* Be sure to place it manually at the bottom of your page.
|
|
34
40
|
* You can use position 'absolute' with relative body or set the height of the content and place footer at the end.
|
|
35
|
-
* @example
|
|
41
|
+
* @example <caption>Appending custom element after default elements</caption>
|
|
36
42
|
* <Footer customElements={[{title: 'Bentley', url: 'https://www.bentley.com/'}]} />
|
|
43
|
+
* @example <caption>Returning only custom elements</caption>
|
|
44
|
+
* <Footer customElements={() => newFooterElements)} />
|
|
45
|
+
* @example <caption>Filtering out a specific element</caption>
|
|
46
|
+
* <Footer customElements={(defaultElements) => defaultElements.filter(({ key }) => key !== 'privacy' )} />
|
|
47
|
+
* @example <caption>Changing a url</caption>
|
|
48
|
+
* <Footer customElements={(defaultElements) => defaultElements.map(element => ({ ...element, url: element.key === 'privacy' ? customPrivacyUrl : element.url }))} />
|
|
37
49
|
*/
|
|
38
50
|
export declare const Footer: (props: FooterProps) => JSX.Element;
|
|
39
51
|
export default Footer;
|
|
@@ -54,40 +54,63 @@ var footerTranslations = {
|
|
|
54
54
|
* Footer element with all needed legal and info links.
|
|
55
55
|
* Be sure to place it manually at the bottom of your page.
|
|
56
56
|
* You can use position 'absolute' with relative body or set the height of the content and place footer at the end.
|
|
57
|
-
* @example
|
|
57
|
+
* @example <caption>Appending custom element after default elements</caption>
|
|
58
58
|
* <Footer customElements={[{title: 'Bentley', url: 'https://www.bentley.com/'}]} />
|
|
59
|
+
* @example <caption>Returning only custom elements</caption>
|
|
60
|
+
* <Footer customElements={() => newFooterElements)} />
|
|
61
|
+
* @example <caption>Filtering out a specific element</caption>
|
|
62
|
+
* <Footer customElements={(defaultElements) => defaultElements.filter(({ key }) => key !== 'privacy' )} />
|
|
63
|
+
* @example <caption>Changing a url</caption>
|
|
64
|
+
* <Footer customElements={(defaultElements) => defaultElements.map(element => ({ ...element, url: element.key === 'privacy' ? customPrivacyUrl : element.url }))} />
|
|
59
65
|
*/
|
|
60
66
|
var Footer = function (props) {
|
|
61
67
|
var customElements = props.customElements, translatedTitles = props.translatedTitles, className = props.className, rest = __rest(props, ["customElements", "translatedTitles", "className"]);
|
|
62
68
|
(0, utils_1.useTheme)();
|
|
63
|
-
var today = new Date();
|
|
64
69
|
var titles = __assign(__assign({}, footerTranslations), translatedTitles);
|
|
65
70
|
var defaultElements = [
|
|
66
71
|
{
|
|
72
|
+
key: 'copyright',
|
|
73
|
+
title: "\u00A9 " + new Date().getFullYear() + " Bentley Systems, Incorporated",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
key: 'termsOfService',
|
|
67
77
|
title: titles.termsOfService,
|
|
68
78
|
url: 'https://connect-agreementportal.bentley.com/AgreementApp/Home/Eula/view/readonly/BentleyConnect',
|
|
69
79
|
},
|
|
70
|
-
{ title: titles.privacy, url: 'https://www.bentley.com/en/privacy-policy' },
|
|
71
80
|
{
|
|
81
|
+
key: 'privacy',
|
|
82
|
+
title: titles.privacy,
|
|
83
|
+
url: 'https://www.bentley.com/en/privacy-policy',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
key: 'termsOfUse',
|
|
72
87
|
title: titles.termsOfUse,
|
|
73
88
|
url: 'https://www.bentley.com/en/terms-of-use-and-select-online-agreement',
|
|
74
89
|
},
|
|
75
|
-
{
|
|
76
|
-
|
|
90
|
+
{
|
|
91
|
+
key: 'cookies',
|
|
92
|
+
title: titles.cookies,
|
|
93
|
+
url: 'https://www.bentley.com/en/cookie-policy',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
key: 'legalNotices',
|
|
97
|
+
title: titles.legalNotices,
|
|
98
|
+
url: 'https://connect.bentley.com/Legal',
|
|
99
|
+
},
|
|
77
100
|
];
|
|
78
|
-
var elements =
|
|
79
|
-
|
|
101
|
+
var elements = defaultElements;
|
|
102
|
+
if (customElements) {
|
|
103
|
+
elements =
|
|
104
|
+
typeof customElements === 'function'
|
|
105
|
+
? customElements(defaultElements)
|
|
106
|
+
: __spreadArray(__spreadArray([], defaultElements, true), customElements, true);
|
|
107
|
+
}
|
|
80
108
|
return (react_1.default.createElement("footer", __assign({ className: (0, classnames_1.default)('iui-legal-footer', className) }, rest),
|
|
81
|
-
react_1.default.createElement("ul", null,
|
|
82
|
-
react_1.default.createElement("li",
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
elements.map(function (element, index) {
|
|
87
|
-
return (react_1.default.createElement("li", { key: element.title + "-" + index },
|
|
88
|
-
react_1.default.createElement("span", { className: 'iui-separator' }),
|
|
89
|
-
element.url ? (react_1.default.createElement("a", { href: element.url, target: '_blank', rel: 'noreferrer' }, element.title)) : (element.title)));
|
|
90
|
-
}))));
|
|
109
|
+
react_1.default.createElement("ul", null, elements.map(function (element, index) {
|
|
110
|
+
return (react_1.default.createElement("li", { key: element.key || element.title + "-" + index },
|
|
111
|
+
index > 0 && react_1.default.createElement("span", { className: 'iui-separator' }),
|
|
112
|
+
element.url ? (react_1.default.createElement("a", { href: element.url, target: '_blank', rel: 'noreferrer' }, element.title)) : (element.title)));
|
|
113
|
+
}))));
|
|
91
114
|
};
|
|
92
115
|
exports.Footer = Footer;
|
|
93
116
|
exports.default = exports.Footer;
|
|
@@ -51,8 +51,18 @@ require("@itwin/itwinui-css/css/inputs.css");
|
|
|
51
51
|
var InputGroup = function (props) {
|
|
52
52
|
var children = props.children, _a = props.disabled, disabled = _a === void 0 ? false : _a, _b = props.displayStyle, displayStyle = _b === void 0 ? 'default' : _b, label = props.label, message = props.message, status = props.status, svgIcon = props.svgIcon, className = props.className, style = props.style, _c = props.required, required = _c === void 0 ? false : _c, rest = __rest(props, ["children", "disabled", "displayStyle", "label", "message", "status", "svgIcon", "className", "style", "required"]);
|
|
53
53
|
(0, utils_1.useTheme)();
|
|
54
|
-
var icon =
|
|
55
|
-
|
|
54
|
+
var icon = function () {
|
|
55
|
+
if (svgIcon) {
|
|
56
|
+
return react_1.default.cloneElement(svgIcon, { 'aria-hidden': true });
|
|
57
|
+
}
|
|
58
|
+
if (status && message) {
|
|
59
|
+
return react_1.default.cloneElement(utils_1.StatusIconMap[status](), {
|
|
60
|
+
'aria-hidden': true,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
};
|
|
65
|
+
return (react_1.default.createElement(utils_1.InputContainer, __assign({ label: label, disabled: disabled, required: required, status: status, message: message, icon: icon(), isLabelInline: displayStyle === 'inline', className: className, style: style }, rest),
|
|
56
66
|
react_1.default.createElement("div", { className: 'iui-input-group' }, children)));
|
|
57
67
|
};
|
|
58
68
|
exports.InputGroup = InputGroup;
|
|
@@ -70,10 +70,16 @@ require("@itwin/itwinui-css/css/inputs.css");
|
|
|
70
70
|
var LabeledSelect = function (props) {
|
|
71
71
|
var className = props.className, _a = props.disabled, disabled = _a === void 0 ? false : _a, label = props.label, message = props.message, status = props.status, svgIcon = props.svgIcon, _b = props.displayStyle, displayStyle = _b === void 0 ? 'default' : _b, style = props.style, selectClassName = props.selectClassName, selectStyle = props.selectStyle, _c = props.required, required = _c === void 0 ? false : _c, rest = __rest(props, ["className", "disabled", "label", "message", "status", "svgIcon", "displayStyle", "style", "selectClassName", "selectStyle", "required"]);
|
|
72
72
|
(0, utils_1.useTheme)();
|
|
73
|
-
var icon =
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
var icon = function () {
|
|
74
|
+
if (svgIcon) {
|
|
75
|
+
return react_1.default.cloneElement(svgIcon, { 'aria-hidden': true });
|
|
76
|
+
}
|
|
77
|
+
if (status && message) {
|
|
78
|
+
return utils_1.StatusIconMap[status]();
|
|
79
|
+
}
|
|
80
|
+
return undefined;
|
|
81
|
+
};
|
|
82
|
+
return (react_1.default.createElement(utils_1.InputContainer, { label: label, disabled: disabled, required: required, status: status, message: message, icon: displayStyle === 'default' ? icon() : undefined, isLabelInline: displayStyle === 'inline', className: className, style: style },
|
|
77
83
|
react_1.default.createElement(Select_1.Select, __assign({ disabled: disabled, className: selectClassName, style: selectStyle }, rest))));
|
|
78
84
|
};
|
|
79
85
|
exports.LabeledSelect = LabeledSelect;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export declare type StatusMessageProps = {
|
|
3
|
+
/**
|
|
4
|
+
* Custom icon to be displayed at the beginning.
|
|
5
|
+
* It will default to the `status` icon, if it's set.
|
|
6
|
+
*/
|
|
7
|
+
startIcon?: JSX.Element;
|
|
8
|
+
/**
|
|
9
|
+
* Message content.
|
|
10
|
+
*/
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* Status of the message.
|
|
14
|
+
*/
|
|
15
|
+
status?: 'positive' | 'warning' | 'negative';
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Component to display icon and text below the `Combobox` component.
|
|
19
|
+
* @example
|
|
20
|
+
* <StatusMessage>This is the text</StatusMessage>
|
|
21
|
+
* <StatusMessage startIcon={<SvgStar />}>This is the text</StatusMessage>
|
|
22
|
+
*/
|
|
23
|
+
export declare const StatusMessage: ({ startIcon: userStartIcon, children, status, }: StatusMessageProps) => JSX.Element;
|
|
24
|
+
export default StatusMessage;
|
|
@@ -0,0 +1,39 @@
|
|
|
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.StatusMessage = 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
|
+
var react_1 = __importDefault(require("react"));
|
|
12
|
+
var utils_1 = require("../utils");
|
|
13
|
+
var classnames_1 = __importDefault(require("classnames"));
|
|
14
|
+
/**
|
|
15
|
+
* Component to display icon and text below the `Combobox` component.
|
|
16
|
+
* @example
|
|
17
|
+
* <StatusMessage>This is the text</StatusMessage>
|
|
18
|
+
* <StatusMessage startIcon={<SvgStar />}>This is the text</StatusMessage>
|
|
19
|
+
*/
|
|
20
|
+
var StatusMessage = function (_a) {
|
|
21
|
+
var userStartIcon = _a.startIcon, children = _a.children, status = _a.status;
|
|
22
|
+
(0, utils_1.useTheme)();
|
|
23
|
+
var StartIcon = function () {
|
|
24
|
+
var _a;
|
|
25
|
+
var icon = userStartIcon !== null && userStartIcon !== void 0 ? userStartIcon : (status && utils_1.StatusIconMap[status]());
|
|
26
|
+
if (!icon) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
return react_1.default.cloneElement(icon, {
|
|
30
|
+
className: (0, classnames_1.default)('iui-input-icon', (_a = icon.props) === null || _a === void 0 ? void 0 : _a.className),
|
|
31
|
+
'aria-hidden': true,
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
35
|
+
react_1.default.createElement(StartIcon, null),
|
|
36
|
+
react_1.default.createElement("div", { className: 'iui-message' }, children)));
|
|
37
|
+
};
|
|
38
|
+
exports.StatusMessage = StatusMessage;
|
|
39
|
+
exports.default = exports.StatusMessage;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StatusMessage = void 0;
|
|
4
|
+
/*---------------------------------------------------------------------------------------------
|
|
5
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
6
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
7
|
+
*--------------------------------------------------------------------------------------------*/
|
|
8
|
+
var StatusMessage_1 = require("./StatusMessage");
|
|
9
|
+
Object.defineProperty(exports, "StatusMessage", { enumerable: true, get: function () { return StatusMessage_1.StatusMessage; } });
|
|
10
|
+
exports.default = './StatusMessage';
|
package/cjs/core/index.d.ts
CHANGED
|
@@ -62,6 +62,8 @@ export { SideNavigation, SidenavButton, SidenavSubmenu, SidenavSubmenuHeader, }
|
|
|
62
62
|
export type { SideNavigationProps, SidenavButtonProps, SidenavSubmenuProps, SidenavSubmenuHeaderProps, } from './SideNavigation';
|
|
63
63
|
export { Slider } from './Slider';
|
|
64
64
|
export type { SliderProps } from './Slider';
|
|
65
|
+
export { StatusMessage } from './StatusMessage';
|
|
66
|
+
export type { StatusMessageProps } from './StatusMessage';
|
|
65
67
|
export { Table, tableFilters, FilterButtonBar, DefaultCell, EditableCell, TablePaginator, } from './Table';
|
|
66
68
|
export type { TableProps, TableFilterProps, TableFilterValue, DateRangeFilterOptions, FilterButtonBarProps, DefaultCellProps, EditableCellProps, TablePaginatorProps, TablePaginatorRendererProps, } from './Table';
|
|
67
69
|
export { Tag, TagContainer } from './Tag';
|
package/cjs/core/index.js
CHANGED
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ModalButtonBar = exports.Modal = exports.MenuExtraContent = exports.MenuDivider = exports.MenuItem = exports.Menu = exports.LabeledTextarea = exports.LabeledSelect = exports.InputGroup = exports.LabeledInput = exports.Label = exports.Input = exports.InformationPanelContent = exports.InformationPanelBody = exports.InformationPanelHeader = exports.InformationPanelWrapper = exports.InformationPanel = exports.HorizontalTab = exports.HorizontalTabs = exports.Tab = exports.VerticalTabs = exports.HeaderLogo = exports.HeaderButton = exports.HeaderBreadcrumbs = exports.Header = exports.Footer = exports.FileUploadTemplate = exports.FileUpload = exports.Fieldset = exports.ExpandableBlock = exports.ErrorPage = exports.DropdownMenu = exports.generateLocalizedStrings = exports.DatePicker = exports.ComboBox = exports.ColorPalette = exports.ColorInputPanel = exports.ColorBuilder = exports.ColorSwatch = exports.ColorPicker = exports.Checkbox = exports.ButtonGroup = exports.SplitButton = exports.IdeasButton = exports.IconButton = exports.DropdownButton = exports.Button = exports.Breadcrumbs = exports.Badge = exports.Alert = void 0;
|
|
7
|
-
exports.MiddleTextTruncation = exports.ColorValue = exports.useTheme = exports.getUserColor = exports.Wizard = exports.UserIconGroup = exports.UserIcon = exports.Text = exports.KbdKeys = exports.Kbd = exports.Code = exports.Blockquote = exports.Title = exports.Subheading = exports.Small = exports.Leading = exports.Headline = 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.TablePaginator = exports.EditableCell = exports.DefaultCell = exports.FilterButtonBar = exports.tableFilters = exports.Table = exports.Slider = exports.SidenavSubmenuHeader = exports.SidenavSubmenu = exports.SidenavButton = exports.SideNavigation = exports.Select = exports.RadioTileGroup = exports.RadioTile = exports.Radio = exports.ProgressRadial = exports.ProgressLinear = void 0;
|
|
7
|
+
exports.MiddleTextTruncation = exports.ColorValue = exports.useTheme = exports.getUserColor = exports.Wizard = exports.UserIconGroup = exports.UserIcon = exports.Text = exports.KbdKeys = exports.Kbd = exports.Code = exports.Blockquote = exports.Title = exports.Subheading = exports.Small = exports.Leading = exports.Headline = 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.TablePaginator = exports.EditableCell = exports.DefaultCell = exports.FilterButtonBar = exports.tableFilters = exports.Table = exports.StatusMessage = exports.Slider = exports.SidenavSubmenuHeader = exports.SidenavSubmenu = exports.SidenavButton = exports.SideNavigation = exports.Select = exports.RadioTileGroup = exports.RadioTile = exports.Radio = exports.ProgressRadial = exports.ProgressLinear = void 0;
|
|
8
8
|
/*---------------------------------------------------------------------------------------------
|
|
9
9
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
10
10
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
@@ -102,6 +102,8 @@ Object.defineProperty(exports, "SidenavSubmenu", { enumerable: true, get: functi
|
|
|
102
102
|
Object.defineProperty(exports, "SidenavSubmenuHeader", { enumerable: true, get: function () { return SideNavigation_1.SidenavSubmenuHeader; } });
|
|
103
103
|
var Slider_1 = require("./Slider");
|
|
104
104
|
Object.defineProperty(exports, "Slider", { enumerable: true, get: function () { return Slider_1.Slider; } });
|
|
105
|
+
var StatusMessage_1 = require("./StatusMessage");
|
|
106
|
+
Object.defineProperty(exports, "StatusMessage", { enumerable: true, get: function () { return StatusMessage_1.StatusMessage; } });
|
|
105
107
|
var Table_1 = require("./Table");
|
|
106
108
|
Object.defineProperty(exports, "Table", { enumerable: true, get: function () { return Table_1.Table; } });
|
|
107
109
|
Object.defineProperty(exports, "tableFilters", { enumerable: true, get: function () { return Table_1.tableFilters; } });
|
|
@@ -9,6 +9,7 @@ export declare type InputContainerProps<T extends React.ElementType = 'div'> = {
|
|
|
9
9
|
icon?: JSX.Element;
|
|
10
10
|
isLabelInline?: boolean;
|
|
11
11
|
isIconInline?: boolean;
|
|
12
|
+
statusMessage?: React.ReactNode;
|
|
12
13
|
} & React.ComponentPropsWithoutRef<T>;
|
|
13
14
|
/**
|
|
14
15
|
* Input container to wrap inputs with label, and add optional message and icon.
|
|
@@ -39,23 +39,24 @@ var classnames_1 = __importDefault(require("classnames"));
|
|
|
39
39
|
var InputContainer = function (props) {
|
|
40
40
|
var _a;
|
|
41
41
|
var _b;
|
|
42
|
-
var _c = props.as, Element = _c === void 0 ? 'div' : _c, label = props.label, disabled = props.disabled, required = props.required, status = props.status, message = props.message, icon = props.icon, isLabelInline = props.isLabelInline, isIconInline = props.isIconInline, children = props.children, className = props.className, style = props.style, rest = __rest(props, ["as", "label", "disabled", "required", "status", "message", "icon", "isLabelInline", "isIconInline", "children", "className", "style"]);
|
|
42
|
+
var _c = props.as, Element = _c === void 0 ? 'div' : _c, label = props.label, disabled = props.disabled, required = props.required, status = props.status, message = props.message, icon = props.icon, isLabelInline = props.isLabelInline, isIconInline = props.isIconInline, children = props.children, className = props.className, style = props.style, statusMessage = props.statusMessage, rest = __rest(props, ["as", "label", "disabled", "required", "status", "message", "icon", "isLabelInline", "isIconInline", "children", "className", "style", "statusMessage"]);
|
|
43
43
|
return (react_1.default.createElement(Element, __assign({ className: (0, classnames_1.default)('iui-input-container', (_a = {
|
|
44
44
|
'iui-disabled': disabled
|
|
45
45
|
},
|
|
46
46
|
_a["iui-" + status] = !!status,
|
|
47
47
|
_a['iui-inline-label'] = isLabelInline,
|
|
48
48
|
_a['iui-inline-icon'] = isIconInline,
|
|
49
|
-
_a['iui-with-message'] = !!message && !isLabelInline,
|
|
49
|
+
_a['iui-with-message'] = (!!message || !!icon || !!statusMessage) && !isLabelInline,
|
|
50
50
|
_a), className), style: style }, rest),
|
|
51
51
|
label && (react_1.default.createElement("div", { className: (0, classnames_1.default)('iui-label', {
|
|
52
52
|
'iui-required': required,
|
|
53
53
|
}) }, label)),
|
|
54
54
|
children,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
statusMessage ? (statusMessage) : (react_1.default.createElement(react_1.default.Fragment, null,
|
|
56
|
+
icon &&
|
|
57
|
+
react_1.default.cloneElement(icon, {
|
|
58
|
+
className: (0, classnames_1.default)('iui-input-icon', (_b = icon.props) === null || _b === void 0 ? void 0 : _b.className),
|
|
59
|
+
}),
|
|
60
|
+
message && !isLabelInline && (react_1.default.createElement("div", { className: 'iui-message' }, message))))));
|
|
60
61
|
};
|
|
61
62
|
exports.InputContainer = InputContainer;
|
|
@@ -13,6 +13,8 @@ export declare type ButtonGroupProps = {
|
|
|
13
13
|
* and returns the `ReactNode` to render.
|
|
14
14
|
*
|
|
15
15
|
* The placement of this button can be controlled using the `overflowPlacement` prop.
|
|
16
|
+
*
|
|
17
|
+
* *Note: this will not work with `orientation='vertical'`.*
|
|
16
18
|
*/
|
|
17
19
|
overflowButton?: (firstOverflowingIndex: number) => React.ReactNode;
|
|
18
20
|
/**
|
|
@@ -20,6 +22,11 @@ export declare type ButtonGroupProps = {
|
|
|
20
22
|
* @default 'end'
|
|
21
23
|
*/
|
|
22
24
|
overflowPlacement?: 'start' | 'end';
|
|
25
|
+
/**
|
|
26
|
+
* Should the buttons be placed in a horizontal or vertical layout?
|
|
27
|
+
* @default 'horizontal'
|
|
28
|
+
*/
|
|
29
|
+
orientation?: 'horizontal' | 'vertical';
|
|
23
30
|
} & React.ComponentPropsWithRef<'div'>;
|
|
24
31
|
/**
|
|
25
32
|
* Group buttons together for common actions.
|
|
@@ -49,5 +56,5 @@ export declare type ButtonGroupProps = {
|
|
|
49
56
|
* {buttons}
|
|
50
57
|
* </ButtonGroup>
|
|
51
58
|
*/
|
|
52
|
-
export declare const ButtonGroup: React.ForwardRefExoticComponent<Pick<ButtonGroupProps, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "overflowButton" | "overflowPlacement"> & React.RefAttributes<HTMLDivElement>>;
|
|
59
|
+
export declare const ButtonGroup: React.ForwardRefExoticComponent<Pick<ButtonGroupProps, "orientation" | "key" | keyof React.HTMLAttributes<HTMLDivElement> | "overflowButton" | "overflowPlacement"> & React.RefAttributes<HTMLDivElement>>;
|
|
53
60
|
export default ButtonGroup;
|
|
@@ -57,12 +57,16 @@ import '@itwin/itwinui-css/css/button.css';
|
|
|
57
57
|
* </ButtonGroup>
|
|
58
58
|
*/
|
|
59
59
|
export var ButtonGroup = React.forwardRef(function (props, ref) {
|
|
60
|
-
var children = props.children, className = props.className, style = props.style, overflowButton = props.overflowButton, _a = props.overflowPlacement, overflowPlacement = _a === void 0 ? 'end' : _a, rest = __rest(props, ["children", "className", "style", "overflowButton", "overflowPlacement"]);
|
|
60
|
+
var children = props.children, className = props.className, style = props.style, overflowButton = props.overflowButton, _a = props.overflowPlacement, overflowPlacement = _a === void 0 ? 'end' : _a, _b = props.orientation, orientation = _b === void 0 ? 'horizontal' : _b, rest = __rest(props, ["children", "className", "style", "overflowButton", "overflowPlacement", "orientation"]);
|
|
61
61
|
var items = React.useMemo(function () { var _a; return (_a = React.Children.map(children, function (child) { return React.createElement("div", null, child); })) !== null && _a !== void 0 ? _a : []; }, [children]);
|
|
62
62
|
useTheme();
|
|
63
|
-
var
|
|
63
|
+
var _c = useOverflow(items, !overflowButton), overflowRef = _c[0], visibleCount = _c[1];
|
|
64
64
|
var refs = useMergedRefs(overflowRef, ref);
|
|
65
|
-
return (React.createElement("div", __assign({ className: cx(
|
|
65
|
+
return (React.createElement("div", __assign({ className: cx({
|
|
66
|
+
'iui-button-group': orientation === 'horizontal',
|
|
67
|
+
'iui-button-group-vertical': orientation === 'vertical',
|
|
68
|
+
}, className), style: __assign(__assign({}, (!!overflowButton &&
|
|
69
|
+
orientation === 'horizontal' && { width: '100%' })), style), "aria-orientation": orientation, ref: refs }, rest), !!overflowButton && visibleCount < items.length ? (React.createElement(React.Fragment, null,
|
|
66
70
|
overflowButton && overflowPlacement === 'start' && (React.createElement("div", null, overflowButton(visibleCount))),
|
|
67
71
|
items.slice(0, visibleCount - 1),
|
|
68
72
|
overflowButton && overflowPlacement === 'end' && (React.createElement("div", null, overflowButton(visibleCount))))) : (items)));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { InputProps } from '../Input';
|
|
3
3
|
import { SelectOption } from '../Select';
|
|
4
4
|
import { PopoverProps, CommonProps, InputContainerProps } from '../utils';
|
|
@@ -12,6 +12,11 @@ export declare type ComboBoxProps<T> = {
|
|
|
12
12
|
* Controlled value of ComboBox.
|
|
13
13
|
*/
|
|
14
14
|
value?: T;
|
|
15
|
+
/**
|
|
16
|
+
* Message shown below the combobox.
|
|
17
|
+
* Use `StatusMessage` component.
|
|
18
|
+
*/
|
|
19
|
+
message?: React.ReactNode;
|
|
15
20
|
/**
|
|
16
21
|
* Callback fired when selected value changes.
|
|
17
22
|
*/
|
|
@@ -32,6 +32,7 @@ import { Text } from '../Typography';
|
|
|
32
32
|
import { InputContainer, useTheme, Popover, getFocusableElements, getRandomValue, mergeRefs, } from '../utils';
|
|
33
33
|
import SvgCaretDownSmall from '@itwin/itwinui-icons-react/cjs/icons/CaretDownSmall';
|
|
34
34
|
import 'tippy.js/animations/shift-away.css';
|
|
35
|
+
import { StatusMessage } from '../StatusMessage';
|
|
35
36
|
/**
|
|
36
37
|
* ComboBox component that allows typing a value to filter the options in dropdown list.
|
|
37
38
|
* Values can be selected either using mouse clicks or using the Enter key.
|
|
@@ -46,7 +47,7 @@ import 'tippy.js/animations/shift-away.css';
|
|
|
46
47
|
* />
|
|
47
48
|
*/
|
|
48
49
|
export var ComboBox = function (props) {
|
|
49
|
-
var options = props.options, value = props.value, onChange = props.onChange, filterFunction = props.filterFunction, className = props.className, inputProps = props.inputProps, dropdownMenuProps = props.dropdownMenuProps, _a = props.emptyStateMessage, emptyStateMessage = _a === void 0 ? 'No options found' : _a, itemRenderer = props.itemRenderer, rest = __rest(props, ["options", "value", "onChange", "filterFunction", "className", "inputProps", "dropdownMenuProps", "emptyStateMessage", "itemRenderer"]);
|
|
50
|
+
var options = props.options, value = props.value, onChange = props.onChange, filterFunction = props.filterFunction, className = props.className, inputProps = props.inputProps, dropdownMenuProps = props.dropdownMenuProps, message = props.message, status = props.status, _a = props.emptyStateMessage, emptyStateMessage = _a === void 0 ? 'No options found' : _a, itemRenderer = props.itemRenderer, rest = __rest(props, ["options", "value", "onChange", "filterFunction", "className", "inputProps", "dropdownMenuProps", "message", "status", "emptyStateMessage", "itemRenderer"]);
|
|
50
51
|
// Generate a stateful random id if not specified
|
|
51
52
|
var id = React.useState(function () {
|
|
52
53
|
var _a, _b;
|
|
@@ -268,7 +269,8 @@ export var ComboBox = function (props) {
|
|
|
268
269
|
itemRenderer,
|
|
269
270
|
memoizedItems,
|
|
270
271
|
]);
|
|
271
|
-
return (React.createElement(InputContainer, __assign({ className: className,
|
|
272
|
+
return (React.createElement(InputContainer, __assign({ className: className, status: status, statusMessage: typeof message === 'string' ? (React.createElement(StatusMessage, { status: status }, message)) : (React.isValidElement(message) &&
|
|
273
|
+
React.cloneElement(message, { status: status })) }, rest, { id: id }),
|
|
272
274
|
React.createElement("div", { className: 'iui-input-with-icon' },
|
|
273
275
|
React.createElement(Popover, __assign({ placement: 'bottom-start', visible: isOpen, onClickOutside: function (_, _a) {
|
|
274
276
|
var _b;
|
|
@@ -11,8 +11,10 @@ export declare type TitleTranslations = {
|
|
|
11
11
|
export declare type FooterProps = {
|
|
12
12
|
/**
|
|
13
13
|
* Customize footer elements.
|
|
14
|
+
* Providing a `FooterElement[]` will append the custom elements to the end of the default elements.
|
|
15
|
+
* Providing a function that returns a `FooterElement[]` allows further customization - whatever is returned from the function is displayed in the footer with no amendments.
|
|
14
16
|
*/
|
|
15
|
-
customElements?: FooterElement[];
|
|
17
|
+
customElements?: FooterElement[] | ((defaultElements: FooterElement[]) => FooterElement[]);
|
|
16
18
|
/**
|
|
17
19
|
* Provide localized strings.
|
|
18
20
|
*/
|
|
@@ -27,13 +29,23 @@ export declare type FooterElement = {
|
|
|
27
29
|
* URL of the footer element.
|
|
28
30
|
*/
|
|
29
31
|
url?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Key of the footer element.
|
|
34
|
+
*/
|
|
35
|
+
key?: keyof TitleTranslations | 'copyright' | (string & Record<never, never>);
|
|
30
36
|
};
|
|
31
37
|
/**
|
|
32
38
|
* Footer element with all needed legal and info links.
|
|
33
39
|
* Be sure to place it manually at the bottom of your page.
|
|
34
40
|
* You can use position 'absolute' with relative body or set the height of the content and place footer at the end.
|
|
35
|
-
* @example
|
|
41
|
+
* @example <caption>Appending custom element after default elements</caption>
|
|
36
42
|
* <Footer customElements={[{title: 'Bentley', url: 'https://www.bentley.com/'}]} />
|
|
43
|
+
* @example <caption>Returning only custom elements</caption>
|
|
44
|
+
* <Footer customElements={() => newFooterElements)} />
|
|
45
|
+
* @example <caption>Filtering out a specific element</caption>
|
|
46
|
+
* <Footer customElements={(defaultElements) => defaultElements.filter(({ key }) => key !== 'privacy' )} />
|
|
47
|
+
* @example <caption>Changing a url</caption>
|
|
48
|
+
* <Footer customElements={(defaultElements) => defaultElements.map(element => ({ ...element, url: element.key === 'privacy' ? customPrivacyUrl : element.url }))} />
|
|
37
49
|
*/
|
|
38
50
|
export declare const Footer: (props: FooterProps) => JSX.Element;
|
|
39
51
|
export default Footer;
|
|
@@ -48,39 +48,62 @@ var footerTranslations = {
|
|
|
48
48
|
* Footer element with all needed legal and info links.
|
|
49
49
|
* Be sure to place it manually at the bottom of your page.
|
|
50
50
|
* You can use position 'absolute' with relative body or set the height of the content and place footer at the end.
|
|
51
|
-
* @example
|
|
51
|
+
* @example <caption>Appending custom element after default elements</caption>
|
|
52
52
|
* <Footer customElements={[{title: 'Bentley', url: 'https://www.bentley.com/'}]} />
|
|
53
|
+
* @example <caption>Returning only custom elements</caption>
|
|
54
|
+
* <Footer customElements={() => newFooterElements)} />
|
|
55
|
+
* @example <caption>Filtering out a specific element</caption>
|
|
56
|
+
* <Footer customElements={(defaultElements) => defaultElements.filter(({ key }) => key !== 'privacy' )} />
|
|
57
|
+
* @example <caption>Changing a url</caption>
|
|
58
|
+
* <Footer customElements={(defaultElements) => defaultElements.map(element => ({ ...element, url: element.key === 'privacy' ? customPrivacyUrl : element.url }))} />
|
|
53
59
|
*/
|
|
54
60
|
export var Footer = function (props) {
|
|
55
61
|
var customElements = props.customElements, translatedTitles = props.translatedTitles, className = props.className, rest = __rest(props, ["customElements", "translatedTitles", "className"]);
|
|
56
62
|
useTheme();
|
|
57
|
-
var today = new Date();
|
|
58
63
|
var titles = __assign(__assign({}, footerTranslations), translatedTitles);
|
|
59
64
|
var defaultElements = [
|
|
60
65
|
{
|
|
66
|
+
key: 'copyright',
|
|
67
|
+
title: "\u00A9 " + new Date().getFullYear() + " Bentley Systems, Incorporated",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
key: 'termsOfService',
|
|
61
71
|
title: titles.termsOfService,
|
|
62
72
|
url: 'https://connect-agreementportal.bentley.com/AgreementApp/Home/Eula/view/readonly/BentleyConnect',
|
|
63
73
|
},
|
|
64
|
-
{ title: titles.privacy, url: 'https://www.bentley.com/en/privacy-policy' },
|
|
65
74
|
{
|
|
75
|
+
key: 'privacy',
|
|
76
|
+
title: titles.privacy,
|
|
77
|
+
url: 'https://www.bentley.com/en/privacy-policy',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
key: 'termsOfUse',
|
|
66
81
|
title: titles.termsOfUse,
|
|
67
82
|
url: 'https://www.bentley.com/en/terms-of-use-and-select-online-agreement',
|
|
68
83
|
},
|
|
69
|
-
{
|
|
70
|
-
|
|
84
|
+
{
|
|
85
|
+
key: 'cookies',
|
|
86
|
+
title: titles.cookies,
|
|
87
|
+
url: 'https://www.bentley.com/en/cookie-policy',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
key: 'legalNotices',
|
|
91
|
+
title: titles.legalNotices,
|
|
92
|
+
url: 'https://connect.bentley.com/Legal',
|
|
93
|
+
},
|
|
71
94
|
];
|
|
72
|
-
var elements =
|
|
73
|
-
|
|
95
|
+
var elements = defaultElements;
|
|
96
|
+
if (customElements) {
|
|
97
|
+
elements =
|
|
98
|
+
typeof customElements === 'function'
|
|
99
|
+
? customElements(defaultElements)
|
|
100
|
+
: __spreadArray(__spreadArray([], defaultElements, true), customElements, true);
|
|
101
|
+
}
|
|
74
102
|
return (React.createElement("footer", __assign({ className: cx('iui-legal-footer', className) }, rest),
|
|
75
|
-
React.createElement("ul", null,
|
|
76
|
-
React.createElement("li",
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
elements.map(function (element, index) {
|
|
81
|
-
return (React.createElement("li", { key: element.title + "-" + index },
|
|
82
|
-
React.createElement("span", { className: 'iui-separator' }),
|
|
83
|
-
element.url ? (React.createElement("a", { href: element.url, target: '_blank', rel: 'noreferrer' }, element.title)) : (element.title)));
|
|
84
|
-
}))));
|
|
103
|
+
React.createElement("ul", null, elements.map(function (element, index) {
|
|
104
|
+
return (React.createElement("li", { key: element.key || element.title + "-" + index },
|
|
105
|
+
index > 0 && React.createElement("span", { className: 'iui-separator' }),
|
|
106
|
+
element.url ? (React.createElement("a", { href: element.url, target: '_blank', rel: 'noreferrer' }, element.title)) : (element.title)));
|
|
107
|
+
}))));
|
|
85
108
|
};
|
|
86
109
|
export default Footer;
|
|
@@ -45,8 +45,18 @@ import '@itwin/itwinui-css/css/inputs.css';
|
|
|
45
45
|
export var InputGroup = function (props) {
|
|
46
46
|
var children = props.children, _a = props.disabled, disabled = _a === void 0 ? false : _a, _b = props.displayStyle, displayStyle = _b === void 0 ? 'default' : _b, label = props.label, message = props.message, status = props.status, svgIcon = props.svgIcon, className = props.className, style = props.style, _c = props.required, required = _c === void 0 ? false : _c, rest = __rest(props, ["children", "disabled", "displayStyle", "label", "message", "status", "svgIcon", "className", "style", "required"]);
|
|
47
47
|
useTheme();
|
|
48
|
-
var icon =
|
|
49
|
-
|
|
48
|
+
var icon = function () {
|
|
49
|
+
if (svgIcon) {
|
|
50
|
+
return React.cloneElement(svgIcon, { 'aria-hidden': true });
|
|
51
|
+
}
|
|
52
|
+
if (status && message) {
|
|
53
|
+
return React.cloneElement(StatusIconMap[status](), {
|
|
54
|
+
'aria-hidden': true,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
};
|
|
59
|
+
return (React.createElement(InputContainer, __assign({ label: label, disabled: disabled, required: required, status: status, message: message, icon: icon(), isLabelInline: displayStyle === 'inline', className: className, style: style }, rest),
|
|
50
60
|
React.createElement("div", { className: 'iui-input-group' }, children)));
|
|
51
61
|
};
|
|
52
62
|
export default InputGroup;
|
|
@@ -64,10 +64,16 @@ import '@itwin/itwinui-css/css/inputs.css';
|
|
|
64
64
|
export var LabeledSelect = function (props) {
|
|
65
65
|
var className = props.className, _a = props.disabled, disabled = _a === void 0 ? false : _a, label = props.label, message = props.message, status = props.status, svgIcon = props.svgIcon, _b = props.displayStyle, displayStyle = _b === void 0 ? 'default' : _b, style = props.style, selectClassName = props.selectClassName, selectStyle = props.selectStyle, _c = props.required, required = _c === void 0 ? false : _c, rest = __rest(props, ["className", "disabled", "label", "message", "status", "svgIcon", "displayStyle", "style", "selectClassName", "selectStyle", "required"]);
|
|
66
66
|
useTheme();
|
|
67
|
-
var icon =
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
var icon = function () {
|
|
68
|
+
if (svgIcon) {
|
|
69
|
+
return React.cloneElement(svgIcon, { 'aria-hidden': true });
|
|
70
|
+
}
|
|
71
|
+
if (status && message) {
|
|
72
|
+
return StatusIconMap[status]();
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
};
|
|
76
|
+
return (React.createElement(InputContainer, { label: label, disabled: disabled, required: required, status: status, message: message, icon: displayStyle === 'default' ? icon() : undefined, isLabelInline: displayStyle === 'inline', className: className, style: style },
|
|
71
77
|
React.createElement(Select, __assign({ disabled: disabled, className: selectClassName, style: selectStyle }, rest))));
|
|
72
78
|
};
|
|
73
79
|
export default LabeledSelect;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export declare type StatusMessageProps = {
|
|
3
|
+
/**
|
|
4
|
+
* Custom icon to be displayed at the beginning.
|
|
5
|
+
* It will default to the `status` icon, if it's set.
|
|
6
|
+
*/
|
|
7
|
+
startIcon?: JSX.Element;
|
|
8
|
+
/**
|
|
9
|
+
* Message content.
|
|
10
|
+
*/
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* Status of the message.
|
|
14
|
+
*/
|
|
15
|
+
status?: 'positive' | 'warning' | 'negative';
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Component to display icon and text below the `Combobox` component.
|
|
19
|
+
* @example
|
|
20
|
+
* <StatusMessage>This is the text</StatusMessage>
|
|
21
|
+
* <StatusMessage startIcon={<SvgStar />}>This is the text</StatusMessage>
|
|
22
|
+
*/
|
|
23
|
+
export declare const StatusMessage: ({ startIcon: userStartIcon, children, status, }: StatusMessageProps) => JSX.Element;
|
|
24
|
+
export default StatusMessage;
|
|
@@ -0,0 +1,32 @@
|
|
|
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 { StatusIconMap, useTheme } from '../utils';
|
|
7
|
+
import cx from 'classnames';
|
|
8
|
+
/**
|
|
9
|
+
* Component to display icon and text below the `Combobox` component.
|
|
10
|
+
* @example
|
|
11
|
+
* <StatusMessage>This is the text</StatusMessage>
|
|
12
|
+
* <StatusMessage startIcon={<SvgStar />}>This is the text</StatusMessage>
|
|
13
|
+
*/
|
|
14
|
+
export var StatusMessage = function (_a) {
|
|
15
|
+
var userStartIcon = _a.startIcon, children = _a.children, status = _a.status;
|
|
16
|
+
useTheme();
|
|
17
|
+
var StartIcon = function () {
|
|
18
|
+
var _a;
|
|
19
|
+
var icon = userStartIcon !== null && userStartIcon !== void 0 ? userStartIcon : (status && StatusIconMap[status]());
|
|
20
|
+
if (!icon) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return React.cloneElement(icon, {
|
|
24
|
+
className: cx('iui-input-icon', (_a = icon.props) === null || _a === void 0 ? void 0 : _a.className),
|
|
25
|
+
'aria-hidden': true,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
return (React.createElement(React.Fragment, null,
|
|
29
|
+
React.createElement(StartIcon, null),
|
|
30
|
+
React.createElement("div", { className: 'iui-message' }, children)));
|
|
31
|
+
};
|
|
32
|
+
export default StatusMessage;
|
|
@@ -0,0 +1,6 @@
|
|
|
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
|
+
export { StatusMessage } from './StatusMessage';
|
|
6
|
+
export default './StatusMessage';
|
package/esm/core/index.d.ts
CHANGED
|
@@ -62,6 +62,8 @@ export { SideNavigation, SidenavButton, SidenavSubmenu, SidenavSubmenuHeader, }
|
|
|
62
62
|
export type { SideNavigationProps, SidenavButtonProps, SidenavSubmenuProps, SidenavSubmenuHeaderProps, } from './SideNavigation';
|
|
63
63
|
export { Slider } from './Slider';
|
|
64
64
|
export type { SliderProps } from './Slider';
|
|
65
|
+
export { StatusMessage } from './StatusMessage';
|
|
66
|
+
export type { StatusMessageProps } from './StatusMessage';
|
|
65
67
|
export { Table, tableFilters, FilterButtonBar, DefaultCell, EditableCell, TablePaginator, } from './Table';
|
|
66
68
|
export type { TableProps, TableFilterProps, TableFilterValue, DateRangeFilterOptions, FilterButtonBarProps, DefaultCellProps, EditableCellProps, TablePaginatorProps, TablePaginatorRendererProps, } from './Table';
|
|
67
69
|
export { Tag, TagContainer } from './Tag';
|
package/esm/core/index.js
CHANGED
|
@@ -34,6 +34,7 @@ export { RadioTile, RadioTileGroup } from './RadioTiles';
|
|
|
34
34
|
export { Select } from './Select';
|
|
35
35
|
export { SideNavigation, SidenavButton, SidenavSubmenu, SidenavSubmenuHeader, } from './SideNavigation';
|
|
36
36
|
export { Slider } from './Slider';
|
|
37
|
+
export { StatusMessage } from './StatusMessage';
|
|
37
38
|
export { Table, tableFilters, FilterButtonBar, DefaultCell, EditableCell, TablePaginator, } from './Table';
|
|
38
39
|
export { Tag, TagContainer } from './Tag';
|
|
39
40
|
export { Textarea } from './Textarea';
|
|
@@ -9,6 +9,7 @@ export declare type InputContainerProps<T extends React.ElementType = 'div'> = {
|
|
|
9
9
|
icon?: JSX.Element;
|
|
10
10
|
isLabelInline?: boolean;
|
|
11
11
|
isIconInline?: boolean;
|
|
12
|
+
statusMessage?: React.ReactNode;
|
|
12
13
|
} & React.ComponentPropsWithoutRef<T>;
|
|
13
14
|
/**
|
|
14
15
|
* Input container to wrap inputs with label, and add optional message and icon.
|
|
@@ -33,22 +33,23 @@ import cx from 'classnames';
|
|
|
33
33
|
export var InputContainer = function (props) {
|
|
34
34
|
var _a;
|
|
35
35
|
var _b;
|
|
36
|
-
var _c = props.as, Element = _c === void 0 ? 'div' : _c, label = props.label, disabled = props.disabled, required = props.required, status = props.status, message = props.message, icon = props.icon, isLabelInline = props.isLabelInline, isIconInline = props.isIconInline, children = props.children, className = props.className, style = props.style, rest = __rest(props, ["as", "label", "disabled", "required", "status", "message", "icon", "isLabelInline", "isIconInline", "children", "className", "style"]);
|
|
36
|
+
var _c = props.as, Element = _c === void 0 ? 'div' : _c, label = props.label, disabled = props.disabled, required = props.required, status = props.status, message = props.message, icon = props.icon, isLabelInline = props.isLabelInline, isIconInline = props.isIconInline, children = props.children, className = props.className, style = props.style, statusMessage = props.statusMessage, rest = __rest(props, ["as", "label", "disabled", "required", "status", "message", "icon", "isLabelInline", "isIconInline", "children", "className", "style", "statusMessage"]);
|
|
37
37
|
return (React.createElement(Element, __assign({ className: cx('iui-input-container', (_a = {
|
|
38
38
|
'iui-disabled': disabled
|
|
39
39
|
},
|
|
40
40
|
_a["iui-" + status] = !!status,
|
|
41
41
|
_a['iui-inline-label'] = isLabelInline,
|
|
42
42
|
_a['iui-inline-icon'] = isIconInline,
|
|
43
|
-
_a['iui-with-message'] = !!message && !isLabelInline,
|
|
43
|
+
_a['iui-with-message'] = (!!message || !!icon || !!statusMessage) && !isLabelInline,
|
|
44
44
|
_a), className), style: style }, rest),
|
|
45
45
|
label && (React.createElement("div", { className: cx('iui-label', {
|
|
46
46
|
'iui-required': required,
|
|
47
47
|
}) }, label)),
|
|
48
48
|
children,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
statusMessage ? (statusMessage) : (React.createElement(React.Fragment, null,
|
|
50
|
+
icon &&
|
|
51
|
+
React.cloneElement(icon, {
|
|
52
|
+
className: cx('iui-input-icon', (_b = icon.props) === null || _b === void 0 ? void 0 : _b.className),
|
|
53
|
+
}),
|
|
54
|
+
message && !isLabelInline && (React.createElement("div", { className: 'iui-message' }, message))))));
|
|
54
55
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/itwinui-react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.33.0",
|
|
4
4
|
"author": "Bentley Systems",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "cjs/index.js",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"build-storybook": "build-storybook"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@itwin/itwinui-css": "^0.
|
|
43
|
+
"@itwin/itwinui-css": "^0.50.0",
|
|
44
44
|
"@itwin/itwinui-icons-react": "^1.5.0",
|
|
45
45
|
"@itwin/itwinui-illustrations-react": "^1.0.1",
|
|
46
46
|
"@tippyjs/react": "^4.2.5",
|