@itwin/core-react 3.2.0-dev.7 → 3.2.0-dev.70
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 +36 -1
- package/lib/cjs/core-react/UiCore.d.ts.map +1 -1
- package/lib/cjs/core-react/UiCore.js +3 -0
- package/lib/cjs/core-react/UiCore.js.map +1 -1
- package/lib/cjs/core-react/badge/Badge.d.ts.map +1 -1
- package/lib/cjs/core-react/badge/Badge.js +4 -2
- package/lib/cjs/core-react/badge/Badge.js.map +1 -1
- package/lib/cjs/core-react/badge/BetaBadge.js +2 -2
- package/lib/cjs/core-react/badge/BetaBadge.js.map +1 -1
- package/lib/cjs/core-react/badge/NewBadge.js +2 -2
- package/lib/cjs/core-react/badge/NewBadge.js.map +1 -1
- package/lib/cjs/core-react/colorvariables.scss +4 -0
- package/lib/cjs/core-react/icons/IconComponent.d.ts.map +1 -1
- package/lib/cjs/core-react/icons/IconComponent.js +16 -0
- package/lib/cjs/core-react/icons/IconComponent.js.map +1 -1
- package/lib/cjs/core-react/icons/IconComponent.scss +5 -0
- package/lib/cjs/core-react/icons/SvgSprite.d.ts +3 -2
- package/lib/cjs/core-react/icons/SvgSprite.d.ts.map +1 -1
- package/lib/cjs/core-react/icons/SvgSprite.js +3 -1
- package/lib/cjs/core-react/icons/SvgSprite.js.map +1 -1
- package/lib/cjs/core-react/inputs/Input.js +1 -1
- package/lib/cjs/core-react/inputs/Input.js.map +1 -1
- package/lib/cjs/core-react/inputs/Textarea.js +1 -1
- package/lib/cjs/core-react/inputs/Textarea.js.map +1 -1
- package/lib/cjs/core-react/listbox/Listbox.js +4 -4
- package/lib/cjs/core-react/listbox/Listbox.js.map +1 -1
- package/lib/cjs/core-react/notification/MessageRenderer.d.ts.map +1 -1
- package/lib/cjs/core-react/notification/MessageRenderer.js +7 -4
- package/lib/cjs/core-react/notification/MessageRenderer.js.map +1 -1
- package/lib/cjs/core-react/utils/IconHelper.d.ts +2 -1
- package/lib/cjs/core-react/utils/IconHelper.d.ts.map +1 -1
- package/lib/cjs/core-react/utils/IconHelper.js.map +1 -1
- package/lib/cjs/core-react/utils/IconWebComponent.d.ts +11 -0
- package/lib/cjs/core-react/utils/IconWebComponent.d.ts.map +1 -0
- package/lib/cjs/core-react/utils/IconWebComponent.js +49 -0
- package/lib/cjs/core-react/utils/IconWebComponent.js.map +1 -0
- package/lib/cjs/core-react/utils/hooks/useResizeObserver.js +2 -2
- package/lib/cjs/core-react/utils/hooks/useResizeObserver.js.map +1 -1
- package/lib/esm/core-react/UiCore.d.ts.map +1 -1
- package/lib/esm/core-react/UiCore.js +3 -0
- package/lib/esm/core-react/UiCore.js.map +1 -1
- package/lib/esm/core-react/badge/Badge.d.ts.map +1 -1
- package/lib/esm/core-react/badge/Badge.js +4 -2
- package/lib/esm/core-react/badge/Badge.js.map +1 -1
- package/lib/esm/core-react/badge/BetaBadge.js +1 -1
- package/lib/esm/core-react/badge/BetaBadge.js.map +1 -1
- package/lib/esm/core-react/badge/NewBadge.js +1 -1
- package/lib/esm/core-react/badge/NewBadge.js.map +1 -1
- package/lib/esm/core-react/colorvariables.scss +4 -0
- package/lib/esm/core-react/icons/IconComponent.d.ts.map +1 -1
- package/lib/esm/core-react/icons/IconComponent.js +16 -0
- package/lib/esm/core-react/icons/IconComponent.js.map +1 -1
- package/lib/esm/core-react/icons/IconComponent.scss +5 -0
- package/lib/esm/core-react/icons/SvgSprite.d.ts +3 -2
- package/lib/esm/core-react/icons/SvgSprite.d.ts.map +1 -1
- package/lib/esm/core-react/icons/SvgSprite.js +3 -1
- package/lib/esm/core-react/icons/SvgSprite.js.map +1 -1
- package/lib/esm/core-react/inputs/Input.js +1 -1
- package/lib/esm/core-react/inputs/Input.js.map +1 -1
- package/lib/esm/core-react/inputs/Textarea.js +1 -1
- package/lib/esm/core-react/inputs/Textarea.js.map +1 -1
- package/lib/esm/core-react/listbox/Listbox.js +4 -4
- package/lib/esm/core-react/listbox/Listbox.js.map +1 -1
- package/lib/esm/core-react/notification/MessageRenderer.d.ts.map +1 -1
- package/lib/esm/core-react/notification/MessageRenderer.js +7 -4
- package/lib/esm/core-react/notification/MessageRenderer.js.map +1 -1
- package/lib/esm/core-react/utils/IconHelper.d.ts +2 -1
- package/lib/esm/core-react/utils/IconHelper.d.ts.map +1 -1
- package/lib/esm/core-react/utils/IconHelper.js.map +1 -1
- package/lib/esm/core-react/utils/IconWebComponent.d.ts +11 -0
- package/lib/esm/core-react/utils/IconWebComponent.d.ts.map +1 -0
- package/lib/esm/core-react/utils/IconWebComponent.js +45 -0
- package/lib/esm/core-react/utils/IconWebComponent.js.map +1 -0
- package/lib/esm/core-react/utils/hooks/useResizeObserver.js +2 -2
- package/lib/esm/core-react/utils/hooks/useResizeObserver.js.map +1 -1
- package/package.json +13 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.js","sourceRoot":"","sources":["../../../../src/core-react/inputs/Input.tsx"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAEH,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAgBjD,0GAA0G;AAC1G,MAAM,eAAe,GAAG,KAAK,CAAC,UAAU,CAAkC,8CAA8C;AACtH,SAAS,eAAe,CAAC,KAAK,EAAE,GAAG;IACjC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,IAAI,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,wDAAwD;IAC7I,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"Input.js","sourceRoot":"","sources":["../../../../src/core-react/inputs/Input.tsx"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAEH,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAgBjD,0GAA0G;AAC1G,MAAM,eAAe,GAAG,KAAK,CAAC,UAAU,CAAkC,8CAA8C;AACtH,SAAS,eAAe,CAAC,KAAK,EAAE,GAAG;IACjC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,IAAI,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,wDAAwD;IAC7I,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM,CAAmB,IAAI,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,CAAE,uGAAuG;IAEpJ,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,cAAc,GAAG,eAAe,CAAC,OAAO,CAAC;QAC/C,MAAM,cAAc,GAAG,gBAAgB,CAAC;QAExC,IAAI,cAAc,IAAI,cAAc,EAAE;YACpC,cAAc,CAAC,gBAAgB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;SAC5D;QACD,OAAO,GAAG,EAAE;YACV,IAAI,cAAc,IAAI,cAAc,EAAE;gBACpC,cAAc,CAAC,mBAAmB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;aAC/D;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,eAAe,CAAC,OAAO,IAAI,QAAQ;YACrC,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACpC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,KAAyC,EAAE,EAAE;QAClF,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;IAC/B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,oBAAC,aAAa,IAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAC,MAAM,KAAK,UAAU,EAAE,OAAO,EAAE,WAAW,EACxE,SAAS,EAAE,UAAU,CAAC,qBAAqB,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,GAAI,CAC5E,CAAC;AACJ,CAAC,CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAA8C,eAAe,CAAC,CAAE,8CAA8C","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Inputs\r\n */\r\n\r\nimport classnames from \"classnames\";\r\nimport * as React from \"react\";\r\nimport { Input as ITwinUI_Input } from \"@itwin/itwinui-react\";\r\nimport { useRefs } from \"../utils/hooks/useRefs\";\r\nimport { CommonProps } from \"../utils/Props\";\r\n\r\n/** Properties for the [[Input]] component\r\n * @public\r\n * @deprecated Use InputProps in itwinui-react instead\r\n */\r\nexport interface InputProps extends React.InputHTMLAttributes<HTMLInputElement>, CommonProps {\r\n /** Indicates whether to set focus to the input element */\r\n setFocus?: boolean;\r\n /** Native keydown event handler */\r\n nativeKeyHandler?: (e: KeyboardEvent) => void;\r\n /** Provides ability to return reference to HTMLInputElement */\r\n ref?: React.Ref<HTMLInputElement>;\r\n}\r\n\r\n// Defined using following pattern (const Input at bottom) to ensure useful API documentation is extracted\r\nconst ForwardRefInput = React.forwardRef<HTMLInputElement, InputProps>( // eslint-disable-line deprecation/deprecation\r\n function ForwardRefInput(props, ref) {\r\n const { className, style, setFocus, nativeKeyHandler, size, ...otherProps } = props; // eslint-disable-line @typescript-eslint/no-unused-vars\r\n const inputElementRef = React.useRef<HTMLInputElement>(null);\r\n const refs = useRefs(inputElementRef, ref); // combine ref needed for target with the forwardRef needed by the Parent when parent is a Type Editor.\r\n\r\n React.useEffect(() => {\r\n const currentElement = inputElementRef.current;\r\n const currentHandler = nativeKeyHandler;\r\n\r\n if (currentElement && currentHandler) {\r\n currentElement.addEventListener(\"keydown\", currentHandler);\r\n }\r\n return () => {\r\n if (currentHandler && currentElement) {\r\n currentElement.removeEventListener(\"keydown\", currentHandler);\r\n }\r\n };\r\n }, [nativeKeyHandler]);\r\n\r\n React.useEffect(() => {\r\n if (inputElementRef.current && setFocus)\r\n inputElementRef.current.focus();\r\n }, [setFocus]);\r\n\r\n const handleFocus = React.useCallback((event: React.FocusEvent<HTMLInputElement>) => {\r\n event.currentTarget.select();\r\n }, []);\r\n\r\n return (\r\n <ITwinUI_Input ref={refs} type=\"text\" {...otherProps} onFocus={handleFocus}\r\n className={classnames(\"uicore-inputs-input\", className)} style={style} />\r\n );\r\n }\r\n);\r\n\r\n/** Basic text input, is a wrapper for the `<input type=\"text\">` HTML element.\r\n * @public\r\n * @deprecated Use Input in itwinui-react instead\r\n */\r\nexport const Input: (props: InputProps) => JSX.Element | null = ForwardRefInput; // eslint-disable-line deprecation/deprecation\r\n"]}
|
|
@@ -14,7 +14,7 @@ const ForwardRefTextarea = React.forwardRef(// eslint-disable-line deprecation/d
|
|
|
14
14
|
function ForwardRefTextarea(props, ref) {
|
|
15
15
|
const { className, style, rows, setFocus, ...otherProps } = props; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
16
16
|
const textRows = undefined !== rows ? rows : 3;
|
|
17
|
-
const textAreaElementRef = React.useRef();
|
|
17
|
+
const textAreaElementRef = React.useRef(null);
|
|
18
18
|
const refs = useRefs(textAreaElementRef, ref); // combine ref needed for target with the forwardRef needed by the Parent when parent is a Type Editor.
|
|
19
19
|
React.useEffect(() => {
|
|
20
20
|
if (textAreaElementRef.current && setFocus)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Textarea.js","sourceRoot":"","sources":["../../../../src/core-react/inputs/Textarea.tsx"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAEH,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAgBjD,0GAA0G;AAC1G,MAAM,kBAAkB,GAAG,KAAK,CAAC,UAAU,CAAyC,8CAA8C;AAChI,SAAS,kBAAkB,CAAC,KAAK,EAAE,GAAG;IACpC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,wDAAwD;IAC3H,MAAM,QAAQ,GAAG,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"Textarea.js","sourceRoot":"","sources":["../../../../src/core-react/inputs/Textarea.tsx"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAEH,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAgBjD,0GAA0G;AAC1G,MAAM,kBAAkB,GAAG,KAAK,CAAC,UAAU,CAAyC,8CAA8C;AAChI,SAAS,kBAAkB,CAAC,KAAK,EAAE,GAAG;IACpC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,wDAAwD;IAC3H,MAAM,QAAQ,GAAG,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,CAAsB,IAAI,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC,CAAE,uGAAuG;IAEvJ,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,kBAAkB,CAAC,OAAO,IAAI,QAAQ;YACxC,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,KAA4C,EAAE,EAAE;QACrF,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;IAC/B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,oBAAC,gBAAgB,OAAK,UAAU,EAC9B,GAAG,EAAE,IAAI,EACT,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,UAAU,CAAC,wBAAwB,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,GAAI,CAC/E,CAAC;AACJ,CAAC,CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAiD,kBAAkB,CAAC,CAAG,8CAA8C","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Inputs\r\n */\r\n\r\nimport classnames from \"classnames\";\r\nimport * as React from \"react\";\r\nimport { Textarea as ITwinUI_Textarea } from \"@itwin/itwinui-react\";\r\nimport { useRefs } from \"../utils/hooks/useRefs\";\r\nimport { CommonProps } from \"../utils/Props\";\r\n\r\n/** Properties for [[Textarea]] component\r\n * @public\r\n * @deprecated Use TextareaProps in itwinui-react instead\r\n */\r\nexport interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement>, CommonProps {\r\n /** Number of textarea rows. Default is 3. */\r\n rows?: number;\r\n /** Indicates whether to set focus to the textarea element */\r\n setFocus?: boolean;\r\n /** Provides ability to return reference to HTMLInputElement */\r\n ref?: React.Ref<HTMLTextAreaElement>;\r\n}\r\n\r\n// Defined using following pattern (const Input at bottom) to ensure useful API documentation is extracted\r\nconst ForwardRefTextarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>( // eslint-disable-line deprecation/deprecation\r\n function ForwardRefTextarea(props, ref) {\r\n const { className, style, rows, setFocus, ...otherProps } = props; // eslint-disable-line @typescript-eslint/no-unused-vars\r\n const textRows = undefined !== rows ? rows : 3;\r\n const textAreaElementRef = React.useRef<HTMLTextAreaElement>(null);\r\n const refs = useRefs(textAreaElementRef, ref); // combine ref needed for target with the forwardRef needed by the Parent when parent is a Type Editor.\r\n\r\n React.useEffect(() => {\r\n if (textAreaElementRef.current && setFocus)\r\n textAreaElementRef.current.focus();\r\n }, [setFocus]);\r\n\r\n const handleFocus = React.useCallback((event: React.FocusEvent<HTMLTextAreaElement>) => {\r\n event.currentTarget.select();\r\n }, []);\r\n\r\n return (\r\n <ITwinUI_Textarea {...otherProps}\r\n ref={refs}\r\n rows={textRows}\r\n onFocus={handleFocus}\r\n className={classnames(\"uicore-inputs-textarea\", className)} style={style} />\r\n );\r\n }\r\n);\r\n\r\n/** Basic textarea component\r\n * @public\r\n * @deprecated Use Textarea in itwinui-react instead\r\n */\r\nexport const Textarea: (props: TextareaProps) => JSX.Element | null = ForwardRefTextarea; // eslint-disable-line deprecation/deprecation\r\n"]}
|
|
@@ -66,7 +66,7 @@ function processKeyboardNavigation(optionValues, itemIndex, key) {
|
|
|
66
66
|
* @alpha
|
|
67
67
|
*/
|
|
68
68
|
export function Listbox(props) {
|
|
69
|
-
const { ariaLabel, ariaLabelledBy, id, children, selectedValue, className, onListboxValueChange,
|
|
69
|
+
const { ariaLabel, ariaLabelledBy, id, children, selectedValue, className, onListboxValueChange, onKeyDown, ...otherProps } = props;
|
|
70
70
|
const listRef = React.useRef(null);
|
|
71
71
|
const [listId] = React.useState(() => { return id !== null && id !== void 0 ? id : Guid.createValue(); });
|
|
72
72
|
const optionValues = React.useMemo(() => getOptionValueArray(children), [children]);
|
|
@@ -134,9 +134,9 @@ export function Listbox(props) {
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
// istanbul ignore else
|
|
137
|
-
if (
|
|
138
|
-
|
|
139
|
-
}, [focusValue, optionValues, focusOption,
|
|
137
|
+
if (onKeyDown)
|
|
138
|
+
onKeyDown(event);
|
|
139
|
+
}, [focusValue, optionValues, focusOption, onKeyDown, handleValueChange]);
|
|
140
140
|
const isInitialMount = React.useRef(true);
|
|
141
141
|
React.useEffect(() => {
|
|
142
142
|
const list = listRef.current;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Listbox.js","sourceRoot":"","sources":["../../../../src/core-react/listbox/Listbox.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport * as React from \"react\";\r\nimport classnames from \"classnames\";\r\n\r\nimport \"./Listbox.scss\";\r\nimport { Guid } from \"@itwin/core-bentley\";\r\nimport { SpecialKey } from \"@itwin/appui-abstract\";\r\n\r\n/** Ideas borrowed from https://reacttraining.com/reach-ui/listbox */\r\n\r\n/**\r\n * `Listbox` value.\r\n * @alpha\r\n */\r\nexport type ListboxValue = string;\r\n\r\n/**\r\n * `Listbox` Props.\r\n * @alpha\r\n */\r\nexport interface ListboxProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement> {\r\n id?: string;\r\n selectedValue?: ListboxValue;\r\n ariaLabel?: any;\r\n ariaLabelledBy?: any;\r\n onListboxValueChange?: ((newValue: ListboxValue, isControlOrCommandPressed?: boolean) => void);\r\n}\r\n\r\n/**\r\n * `ListboxItem` Props.\r\n * @alpha\r\n */\r\nexport interface ListboxItemProps extends React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement> {\r\n /** The unique item's value. */\r\n value: ListboxValue;\r\n /** set if item is disabled. */\r\n disabled?: boolean;\r\n}\r\n\r\n/**\r\n * `Listbox` Context.\r\n * @alpha\r\n */\r\nexport interface ListboxContextProps {\r\n listboxId?: string;\r\n listboxValue?: ListboxValue;\r\n focusValue?: ListboxValue;\r\n onListboxValueChange: ((newValue: ListboxValue, isControlOrCommandPressed?: boolean) => void);\r\n listboxRef?: React.RefObject<HTMLUListElement>;\r\n}\r\n\r\n/**\r\n * Context set up by listbox for use by `ListboxItems` .\r\n * @alpha\r\n */\r\n// istanbul ignore next\r\nexport const ListboxContext = React.createContext<ListboxContextProps>({ onListboxValueChange: (_newValue: ListboxValue | undefined) => { } }); // eslint-disable-line @typescript-eslint/naming-convention\r\n\r\nfunction makeId(...args: Array<string | number | null | undefined>) {\r\n return args.filter((val) => val != null).join(\"--\");\r\n}\r\n\r\nfunction getOptionValueArray(childNodes: React.ReactNode): ListboxItemProps[] {\r\n return React.Children.toArray(childNodes).filter((node) => React.isValidElement(node) && node.props.value).map((optionNode) => ((optionNode as React.ReactElement).props as ListboxItemProps));\r\n}\r\n\r\nfunction processKeyboardNavigation(optionValues: ListboxItemProps[], itemIndex: number, key: string): [number, boolean] {\r\n let keyProcessed = false;\r\n let newIndex = itemIndex >= 0 ? itemIndex : 0;\r\n\r\n // Note: In aria example Page Up/Down just moves up or down by one item. See https://www.w3.org/TR/wai-aria-practices-1.1/examples/listbox/js/listbox.js\r\n if (key === SpecialKey.ArrowDown || key === SpecialKey.PageDown) {\r\n for (let i = itemIndex + 1; i < optionValues.length; i++) {\r\n if (!optionValues[i].disabled) {\r\n newIndex = i;\r\n break;\r\n }\r\n }\r\n keyProcessed = true;\r\n } else if (key === SpecialKey.ArrowUp || key === SpecialKey.PageUp) {\r\n for (let i = itemIndex - 1; i >= 0; i--) {\r\n if (!optionValues[i].disabled) {\r\n newIndex = i;\r\n break;\r\n }\r\n }\r\n keyProcessed = true;\r\n } else if (key === SpecialKey.Home) {\r\n for (let i = 0; i < optionValues.length; i++) {\r\n if (!optionValues[i].disabled) {\r\n newIndex = i;\r\n break;\r\n }\r\n }\r\n keyProcessed = true;\r\n } else if (key === SpecialKey.End) {\r\n for (let i = optionValues.length - 1; i >= 0; i--) {\r\n if (!optionValues[i].disabled) {\r\n newIndex = i;\r\n break;\r\n }\r\n }\r\n keyProcessed = true;\r\n }\r\n return [newIndex, keyProcessed];\r\n}\r\n\r\n/**\r\n * Single select `Listbox` component\r\n * @alpha\r\n */\r\nexport function Listbox(props: ListboxProps) {\r\n const { ariaLabel, ariaLabelledBy, id, children, selectedValue, className, onListboxValueChange, onKeyPress, ...otherProps } = props;\r\n const listRef = React.useRef<HTMLUListElement>(null);\r\n const [listId] = React.useState(() => { return id ?? Guid.createValue(); });\r\n const optionValues = React.useMemo(() => getOptionValueArray(children), [children]);\r\n const classes = React.useMemo(() => classnames(\"core-listbox\", className), [className]);\r\n const [currentValue, setCurrentValue] = React.useState<ListboxValue | undefined>(selectedValue);\r\n const [focusValue, setFocusValue] = React.useState<ListboxValue | undefined>(currentValue);\r\n\r\n React.useEffect(() => {\r\n setCurrentValue(selectedValue);\r\n setFocusValue(selectedValue);\r\n }, [selectedValue]);\r\n\r\n const scrollTopRef = React.useRef(0);\r\n const handleValueChange = React.useCallback((newValue: ListboxValue, isControlOrCommandPressed?: boolean) => {\r\n // istanbul ignore else\r\n if (newValue !== currentValue) {\r\n setCurrentValue(newValue);\r\n setFocusValue(newValue);\r\n if (onListboxValueChange)\r\n onListboxValueChange(newValue, isControlOrCommandPressed);\r\n }\r\n }, [setCurrentValue, currentValue, onListboxValueChange]);\r\n\r\n const focusOption = React.useCallback((itemIndex: number) => {\r\n // istanbul ignore else\r\n if (itemIndex >= 0 && itemIndex < optionValues.length) {\r\n const newSelection = optionValues[itemIndex];\r\n const listElement = listRef.current as HTMLUListElement;\r\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\r\n const optionToFocus = listElement.querySelector(`li[data-value=\"${newSelection.value}\"]`) as HTMLLIElement | null;\r\n // istanbul ignore else\r\n if (optionToFocus && listElement) {\r\n let newScrollTop = listElement.scrollTop;\r\n\r\n // istanbul ignore next\r\n if (listElement.scrollHeight > listElement.clientHeight) {\r\n const scrollBottom = listElement.clientHeight + listElement.scrollTop;\r\n const elementBottom = optionToFocus.offsetTop + optionToFocus.offsetHeight;\r\n if (elementBottom > scrollBottom) {\r\n newScrollTop = elementBottom - listElement.clientHeight;\r\n } else if (optionToFocus.offsetTop < listElement.scrollTop) {\r\n newScrollTop = optionToFocus.offsetTop;\r\n }\r\n scrollTopRef.current = newScrollTop;\r\n }\r\n setFocusValue(newSelection.value);\r\n }\r\n }\r\n }, [optionValues]);\r\n\r\n const handleKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLUListElement>) => {\r\n if (optionValues.length < 1)\r\n return;\r\n\r\n const itemIndex = (undefined === focusValue) ? -1 : optionValues.findIndex((optionValue) => ((optionValue.value === focusValue)));\r\n\r\n if (event.key === SpecialKey.Space) {\r\n event.preventDefault();\r\n // istanbul ignore else\r\n if (focusValue)\r\n handleValueChange(focusValue, event.getModifierState(\"Control\") || event.getModifierState(\"Meta\")); // Control or Command\r\n return;\r\n } else {\r\n const [newItemIndex, keyProcessed] = processKeyboardNavigation(optionValues, itemIndex, event.key);\r\n // istanbul ignore else\r\n if (keyProcessed) {\r\n event.preventDefault();\r\n focusOption(newItemIndex);\r\n return;\r\n }\r\n }\r\n\r\n // istanbul ignore else\r\n if (onKeyPress)\r\n onKeyPress(event);\r\n }, [focusValue, optionValues, focusOption, onKeyPress, handleValueChange]);\r\n\r\n const isInitialMount = React.useRef(true);\r\n\r\n React.useEffect(() => {\r\n const list = listRef.current as HTMLUListElement;\r\n\r\n if (isInitialMount.current) {\r\n isInitialMount.current = false;\r\n\r\n if (undefined !== focusValue) {\r\n const itemIndex = optionValues.findIndex((optionValue) => (optionValue.value === focusValue));\r\n focusOption(itemIndex);\r\n }\r\n } else {\r\n list.scrollTop = scrollTopRef.current;\r\n }\r\n }, [focusValue, focusOption, optionValues]);\r\n\r\n // istanbul ignore next\r\n const handleOnScroll = React.useCallback((_event: React.UIEvent<HTMLUListElement, UIEvent>) => {\r\n if (listRef.current)\r\n scrollTopRef.current = listRef.current.scrollTop;\r\n }, []);\r\n\r\n // istanbul ignore next\r\n const handleOnFocus = React.useCallback((_event: React.FocusEvent<HTMLUListElement>) => {\r\n if (!focusValue || 0 === focusValue.length) {\r\n if (currentValue) {\r\n setFocusValue(currentValue);\r\n } else {\r\n if (optionValues.length > 0)\r\n setFocusValue(optionValues[0].value);\r\n }\r\n }\r\n }, [currentValue, focusValue, optionValues]);\r\n\r\n return <ul\r\n className={classes}\r\n // If the listbox is not part of another widget, then it has a visible\r\n // label referenced by `aria-labelledby` on the element with role\r\n // `listbox`.\r\n // https://www.w3.org/TR/wai-aria-practices-1.2/#Listbox\r\n // If an `aria-label` is passed, we should skip `aria-labelledby` to\r\n // avoid confusion.\r\n aria-labelledby={ariaLabel ? undefined : ariaLabelledBy}\r\n aria-label={ariaLabel}\r\n // An element that contains or owns all the listbox options has role\r\n // listbox.\r\n // https://www.w3.org/TR/wai-aria-practices-1.2/#Listbox\r\n role=\"listbox\"\r\n // https://www.w3.org/TR/wai-aria-practices-1.2/examples/listbox/listbox-collapsible.html\r\n tabIndex={0}\r\n // https://www.w3.org/TR/wai-aria-practices-1.2/examples/listbox/listbox-scrollable.html\r\n aria-activedescendant={makeId(currentValue, listId)}\r\n {...otherProps}\r\n ref={listRef}\r\n id={listId}\r\n onKeyDown={handleKeyDown}\r\n onScroll={handleOnScroll}\r\n data-value={currentValue}\r\n data-focusvalue={focusValue}\r\n onFocus={handleOnFocus}\r\n >\r\n <ListboxContext.Provider\r\n value={{\r\n listboxValue: currentValue,\r\n focusValue,\r\n listboxId: listId,\r\n onListboxValueChange: handleValueChange,\r\n listboxRef: listRef,\r\n }}\r\n >\r\n {children}\r\n </ListboxContext.Provider>\r\n </ul>;\r\n}\r\n\r\n/**\r\n * `ListboxItem` component.\r\n * @alpha\r\n */\r\nexport function ListboxItem(props: ListboxItemProps) {\r\n const {\r\n children,\r\n value,\r\n className,\r\n disabled,\r\n ...otherProps\r\n } = props;\r\n\r\n const {\r\n listboxValue,\r\n focusValue,\r\n listboxId,\r\n onListboxValueChange,\r\n } = React.useContext(ListboxContext);\r\n\r\n const hasFocus = focusValue === value;\r\n\r\n const classes = React.useMemo(() => classnames(\"core-listbox-item\", hasFocus && \"focused\", className), [className, hasFocus]);\r\n const itemRef = React.useRef<HTMLLIElement>(null);\r\n const isSelected = listboxValue === value;\r\n\r\n const handleClick = React.useCallback((event: React.MouseEvent<HTMLLIElement, MouseEvent>) => {\r\n event.preventDefault();\r\n // istanbul ignore next\r\n const selectedValue = event.currentTarget?.dataset?.value;\r\n // istanbul ignore else\r\n if (undefined !== selectedValue) {\r\n onListboxValueChange(selectedValue, event.ctrlKey);\r\n }\r\n }, [onListboxValueChange]);\r\n\r\n const getItemId = React.useCallback(() => {\r\n return makeId(value, listboxId);\r\n }, [listboxId, value]);\r\n\r\n return (\r\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events\r\n <li\r\n // In a single-select listbox, the selected option has `aria-selected`\r\n // set to `true`.\r\n // https://www.w3.org/TR/wai-aria-practices-1.2/#Listbox\r\n aria-selected={isSelected}\r\n // Applicable to all host language elements regardless of whether a\r\n // `role` is applied.\r\n // https://www.w3.org/WAI/PF/aria/states_and_properties#global_states_header\r\n aria-disabled={disabled || undefined}\r\n // Each option in the listbox has role `option` and is a DOM descendant\r\n // of the element with role `listbox`.\r\n // https://www.w3.org/TR/wai-aria-practices-1.2/#Listbox\r\n role=\"option\"\r\n className={classes}\r\n {...otherProps}\r\n ref={itemRef}\r\n id={getItemId()}\r\n // used for css styling\r\n data-value={value}\r\n onClick={handleClick}\r\n >\r\n {children}\r\n </li>\r\n );\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"Listbox.js","sourceRoot":"","sources":["../../../../src/core-react/listbox/Listbox.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport * as React from \"react\";\r\nimport classnames from \"classnames\";\r\n\r\nimport \"./Listbox.scss\";\r\nimport { Guid } from \"@itwin/core-bentley\";\r\nimport { SpecialKey } from \"@itwin/appui-abstract\";\r\n\r\n/** Ideas borrowed from https://reacttraining.com/reach-ui/listbox */\r\n\r\n/**\r\n * `Listbox` value.\r\n * @alpha\r\n */\r\nexport type ListboxValue = string;\r\n\r\n/**\r\n * `Listbox` Props.\r\n * @alpha\r\n */\r\nexport interface ListboxProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement> {\r\n id?: string;\r\n selectedValue?: ListboxValue;\r\n ariaLabel?: any;\r\n ariaLabelledBy?: any;\r\n onListboxValueChange?: ((newValue: ListboxValue, isControlOrCommandPressed?: boolean) => void);\r\n}\r\n\r\n/**\r\n * `ListboxItem` Props.\r\n * @alpha\r\n */\r\nexport interface ListboxItemProps extends React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement> {\r\n /** The unique item's value. */\r\n value: ListboxValue;\r\n /** set if item is disabled. */\r\n disabled?: boolean;\r\n}\r\n\r\n/**\r\n * `Listbox` Context.\r\n * @alpha\r\n */\r\nexport interface ListboxContextProps {\r\n listboxId?: string;\r\n listboxValue?: ListboxValue;\r\n focusValue?: ListboxValue;\r\n onListboxValueChange: ((newValue: ListboxValue, isControlOrCommandPressed?: boolean) => void);\r\n listboxRef?: React.RefObject<HTMLUListElement>;\r\n}\r\n\r\n/**\r\n * Context set up by listbox for use by `ListboxItems` .\r\n * @alpha\r\n */\r\n// istanbul ignore next\r\nexport const ListboxContext = React.createContext<ListboxContextProps>({ onListboxValueChange: (_newValue: ListboxValue | undefined) => { } }); // eslint-disable-line @typescript-eslint/naming-convention\r\n\r\nfunction makeId(...args: Array<string | number | null | undefined>) {\r\n return args.filter((val) => val != null).join(\"--\");\r\n}\r\n\r\nfunction getOptionValueArray(childNodes: React.ReactNode): ListboxItemProps[] {\r\n return React.Children.toArray(childNodes).filter((node) => React.isValidElement(node) && node.props.value).map((optionNode) => ((optionNode as React.ReactElement).props as ListboxItemProps));\r\n}\r\n\r\nfunction processKeyboardNavigation(optionValues: ListboxItemProps[], itemIndex: number, key: string): [number, boolean] {\r\n let keyProcessed = false;\r\n let newIndex = itemIndex >= 0 ? itemIndex : 0;\r\n\r\n // Note: In aria example Page Up/Down just moves up or down by one item. See https://www.w3.org/TR/wai-aria-practices-1.1/examples/listbox/js/listbox.js\r\n if (key === SpecialKey.ArrowDown || key === SpecialKey.PageDown) {\r\n for (let i = itemIndex + 1; i < optionValues.length; i++) {\r\n if (!optionValues[i].disabled) {\r\n newIndex = i;\r\n break;\r\n }\r\n }\r\n keyProcessed = true;\r\n } else if (key === SpecialKey.ArrowUp || key === SpecialKey.PageUp) {\r\n for (let i = itemIndex - 1; i >= 0; i--) {\r\n if (!optionValues[i].disabled) {\r\n newIndex = i;\r\n break;\r\n }\r\n }\r\n keyProcessed = true;\r\n } else if (key === SpecialKey.Home) {\r\n for (let i = 0; i < optionValues.length; i++) {\r\n if (!optionValues[i].disabled) {\r\n newIndex = i;\r\n break;\r\n }\r\n }\r\n keyProcessed = true;\r\n } else if (key === SpecialKey.End) {\r\n for (let i = optionValues.length - 1; i >= 0; i--) {\r\n if (!optionValues[i].disabled) {\r\n newIndex = i;\r\n break;\r\n }\r\n }\r\n keyProcessed = true;\r\n }\r\n return [newIndex, keyProcessed];\r\n}\r\n\r\n/**\r\n * Single select `Listbox` component\r\n * @alpha\r\n */\r\nexport function Listbox(props: ListboxProps) {\r\n const { ariaLabel, ariaLabelledBy, id, children, selectedValue, className, onListboxValueChange, onKeyDown, ...otherProps } = props;\r\n const listRef = React.useRef<HTMLUListElement>(null);\r\n const [listId] = React.useState(() => { return id ?? Guid.createValue(); });\r\n const optionValues = React.useMemo(() => getOptionValueArray(children), [children]);\r\n const classes = React.useMemo(() => classnames(\"core-listbox\", className), [className]);\r\n const [currentValue, setCurrentValue] = React.useState<ListboxValue | undefined>(selectedValue);\r\n const [focusValue, setFocusValue] = React.useState<ListboxValue | undefined>(currentValue);\r\n\r\n React.useEffect(() => {\r\n setCurrentValue(selectedValue);\r\n setFocusValue(selectedValue);\r\n }, [selectedValue]);\r\n\r\n const scrollTopRef = React.useRef(0);\r\n const handleValueChange = React.useCallback((newValue: ListboxValue, isControlOrCommandPressed?: boolean) => {\r\n // istanbul ignore else\r\n if (newValue !== currentValue) {\r\n setCurrentValue(newValue);\r\n setFocusValue(newValue);\r\n if (onListboxValueChange)\r\n onListboxValueChange(newValue, isControlOrCommandPressed);\r\n }\r\n }, [setCurrentValue, currentValue, onListboxValueChange]);\r\n\r\n const focusOption = React.useCallback((itemIndex: number) => {\r\n // istanbul ignore else\r\n if (itemIndex >= 0 && itemIndex < optionValues.length) {\r\n const newSelection = optionValues[itemIndex];\r\n const listElement = listRef.current as HTMLUListElement;\r\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\r\n const optionToFocus = listElement.querySelector(`li[data-value=\"${newSelection.value}\"]`) as HTMLLIElement | null;\r\n // istanbul ignore else\r\n if (optionToFocus && listElement) {\r\n let newScrollTop = listElement.scrollTop;\r\n\r\n // istanbul ignore next\r\n if (listElement.scrollHeight > listElement.clientHeight) {\r\n const scrollBottom = listElement.clientHeight + listElement.scrollTop;\r\n const elementBottom = optionToFocus.offsetTop + optionToFocus.offsetHeight;\r\n if (elementBottom > scrollBottom) {\r\n newScrollTop = elementBottom - listElement.clientHeight;\r\n } else if (optionToFocus.offsetTop < listElement.scrollTop) {\r\n newScrollTop = optionToFocus.offsetTop;\r\n }\r\n scrollTopRef.current = newScrollTop;\r\n }\r\n setFocusValue(newSelection.value);\r\n }\r\n }\r\n }, [optionValues]);\r\n\r\n const handleKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLUListElement>) => {\r\n if (optionValues.length < 1)\r\n return;\r\n\r\n const itemIndex = (undefined === focusValue) ? -1 : optionValues.findIndex((optionValue) => ((optionValue.value === focusValue)));\r\n\r\n if (event.key === SpecialKey.Space) {\r\n event.preventDefault();\r\n // istanbul ignore else\r\n if (focusValue)\r\n handleValueChange(focusValue, event.getModifierState(\"Control\") || event.getModifierState(\"Meta\")); // Control or Command\r\n return;\r\n } else {\r\n const [newItemIndex, keyProcessed] = processKeyboardNavigation(optionValues, itemIndex, event.key);\r\n // istanbul ignore else\r\n if (keyProcessed) {\r\n event.preventDefault();\r\n focusOption(newItemIndex);\r\n return;\r\n }\r\n }\r\n\r\n // istanbul ignore else\r\n if (onKeyDown)\r\n onKeyDown(event);\r\n }, [focusValue, optionValues, focusOption, onKeyDown, handleValueChange]);\r\n\r\n const isInitialMount = React.useRef(true);\r\n\r\n React.useEffect(() => {\r\n const list = listRef.current as HTMLUListElement;\r\n\r\n if (isInitialMount.current) {\r\n isInitialMount.current = false;\r\n\r\n if (undefined !== focusValue) {\r\n const itemIndex = optionValues.findIndex((optionValue) => (optionValue.value === focusValue));\r\n focusOption(itemIndex);\r\n }\r\n } else {\r\n list.scrollTop = scrollTopRef.current;\r\n }\r\n }, [focusValue, focusOption, optionValues]);\r\n\r\n // istanbul ignore next\r\n const handleOnScroll = React.useCallback((_event: React.UIEvent<HTMLUListElement, UIEvent>) => {\r\n if (listRef.current)\r\n scrollTopRef.current = listRef.current.scrollTop;\r\n }, []);\r\n\r\n // istanbul ignore next\r\n const handleOnFocus = React.useCallback((_event: React.FocusEvent<HTMLUListElement>) => {\r\n if (!focusValue || 0 === focusValue.length) {\r\n if (currentValue) {\r\n setFocusValue(currentValue);\r\n } else {\r\n if (optionValues.length > 0)\r\n setFocusValue(optionValues[0].value);\r\n }\r\n }\r\n }, [currentValue, focusValue, optionValues]);\r\n\r\n return <ul\r\n className={classes}\r\n // If the listbox is not part of another widget, then it has a visible\r\n // label referenced by `aria-labelledby` on the element with role\r\n // `listbox`.\r\n // https://www.w3.org/TR/wai-aria-practices-1.2/#Listbox\r\n // If an `aria-label` is passed, we should skip `aria-labelledby` to\r\n // avoid confusion.\r\n aria-labelledby={ariaLabel ? undefined : ariaLabelledBy}\r\n aria-label={ariaLabel}\r\n // An element that contains or owns all the listbox options has role\r\n // listbox.\r\n // https://www.w3.org/TR/wai-aria-practices-1.2/#Listbox\r\n role=\"listbox\"\r\n // https://www.w3.org/TR/wai-aria-practices-1.2/examples/listbox/listbox-collapsible.html\r\n tabIndex={0}\r\n // https://www.w3.org/TR/wai-aria-practices-1.2/examples/listbox/listbox-scrollable.html\r\n aria-activedescendant={makeId(currentValue, listId)}\r\n {...otherProps}\r\n ref={listRef}\r\n id={listId}\r\n onKeyDown={handleKeyDown}\r\n onScroll={handleOnScroll}\r\n data-value={currentValue}\r\n data-focusvalue={focusValue}\r\n onFocus={handleOnFocus}\r\n >\r\n <ListboxContext.Provider\r\n value={{\r\n listboxValue: currentValue,\r\n focusValue,\r\n listboxId: listId,\r\n onListboxValueChange: handleValueChange,\r\n listboxRef: listRef,\r\n }}\r\n >\r\n {children}\r\n </ListboxContext.Provider>\r\n </ul>;\r\n}\r\n\r\n/**\r\n * `ListboxItem` component.\r\n * @alpha\r\n */\r\nexport function ListboxItem(props: ListboxItemProps) {\r\n const {\r\n children,\r\n value,\r\n className,\r\n disabled,\r\n ...otherProps\r\n } = props;\r\n\r\n const {\r\n listboxValue,\r\n focusValue,\r\n listboxId,\r\n onListboxValueChange,\r\n } = React.useContext(ListboxContext);\r\n\r\n const hasFocus = focusValue === value;\r\n\r\n const classes = React.useMemo(() => classnames(\"core-listbox-item\", hasFocus && \"focused\", className), [className, hasFocus]);\r\n const itemRef = React.useRef<HTMLLIElement>(null);\r\n const isSelected = listboxValue === value;\r\n\r\n const handleClick = React.useCallback((event: React.MouseEvent<HTMLLIElement, MouseEvent>) => {\r\n event.preventDefault();\r\n // istanbul ignore next\r\n const selectedValue = event.currentTarget?.dataset?.value;\r\n // istanbul ignore else\r\n if (undefined !== selectedValue) {\r\n onListboxValueChange(selectedValue, event.ctrlKey);\r\n }\r\n }, [onListboxValueChange]);\r\n\r\n const getItemId = React.useCallback(() => {\r\n return makeId(value, listboxId);\r\n }, [listboxId, value]);\r\n\r\n return (\r\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events\r\n <li\r\n // In a single-select listbox, the selected option has `aria-selected`\r\n // set to `true`.\r\n // https://www.w3.org/TR/wai-aria-practices-1.2/#Listbox\r\n aria-selected={isSelected}\r\n // Applicable to all host language elements regardless of whether a\r\n // `role` is applied.\r\n // https://www.w3.org/WAI/PF/aria/states_and_properties#global_states_header\r\n aria-disabled={disabled || undefined}\r\n // Each option in the listbox has role `option` and is a DOM descendant\r\n // of the element with role `listbox`.\r\n // https://www.w3.org/TR/wai-aria-practices-1.2/#Listbox\r\n role=\"option\"\r\n className={classes}\r\n {...otherProps}\r\n ref={itemRef}\r\n id={getItemId()}\r\n // used for css styling\r\n data-value={value}\r\n onClick={handleClick}\r\n >\r\n {children}\r\n </li>\r\n );\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageRenderer.d.ts","sourceRoot":"","sources":["../../../../src/core-react/notification/MessageRenderer.tsx"],"names":[],"mappings":"AAIA;;GAEG;;AAIH,OAAO,EAAiC,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAIhD;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,wBAAwB;IACxB,OAAO,EAAE,WAAW,CAAC;IACrB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"MessageRenderer.d.ts","sourceRoot":"","sources":["../../../../src/core-react/notification/MessageRenderer.tsx"],"names":[],"mappings":"AAIA;;GAEG;;AAIH,OAAO,EAAiC,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAIhD;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,wBAAwB;IACxB,OAAO,EAAE,WAAW,CAAC;IACrB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,sBAmE1D"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @module Notification
|
|
7
7
|
*/
|
|
8
8
|
import * as React from "react";
|
|
9
|
-
import * as
|
|
9
|
+
import DOMPurify, * as DOMPurifyNS from "dompurify";
|
|
10
10
|
import { isHTMLElement, isReactMessage } from "./MessageType";
|
|
11
11
|
/** React component renders a string, HTMLElement or React node in a `div` or `span`
|
|
12
12
|
* @public
|
|
@@ -18,7 +18,10 @@ export function MessageRenderer(props) {
|
|
|
18
18
|
messageNode = React.createElement(OutElement, { className: props.className }, props.message);
|
|
19
19
|
}
|
|
20
20
|
else if (isHTMLElement(props.message)) {
|
|
21
|
-
|
|
21
|
+
// the esm build of dompurify has a default import but the cjs build does not
|
|
22
|
+
// if there is a default export, use it (likely esm), otherwise use the namespace
|
|
23
|
+
// istanbul ignore next
|
|
24
|
+
const sanitizer = DOMPurify !== null && DOMPurify !== void 0 ? DOMPurify : DOMPurifyNS; // `sanitizer` is default function name for "jam3/no-sanitizer-with-danger" ESLint rule
|
|
22
25
|
let validAnchors = false;
|
|
23
26
|
let hasAnchors = false;
|
|
24
27
|
// verify that the tag has proper relationships
|
|
@@ -56,10 +59,10 @@ export function MessageRenderer(props) {
|
|
|
56
59
|
let sanitizedHtml;
|
|
57
60
|
if (hasAnchors && validAnchors) {
|
|
58
61
|
// all anchors are valid. do not remove the target attr
|
|
59
|
-
sanitizedHtml = sanitizer(props.message.outerHTML, { ADD_ATTR: ["target"] });
|
|
62
|
+
sanitizedHtml = sanitizer.sanitize(props.message.outerHTML, { ADD_ATTR: ["target"] });
|
|
60
63
|
}
|
|
61
64
|
else {
|
|
62
|
-
sanitizedHtml = sanitizer(props.message.outerHTML);
|
|
65
|
+
sanitizedHtml = sanitizer.sanitize(props.message.outerHTML);
|
|
63
66
|
}
|
|
64
67
|
// we can safely disable jam3/no-sanitizer-with-danger as we are sanitizing above
|
|
65
68
|
// eslint-disable-next-line @typescript-eslint/naming-convention, jam3/no-sanitizer-with-danger
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageRenderer.js","sourceRoot":"","sources":["../../../../src/core-react/notification/MessageRenderer.tsx"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"MessageRenderer.js","sourceRoot":"","sources":["../../../../src/core-react/notification/MessageRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Notification\r\n */\r\n\r\nimport * as React from \"react\";\r\nimport DOMPurify, * as DOMPurifyNS from \"dompurify\";\r\nimport { isHTMLElement, isReactMessage, MessageType } from \"./MessageType\";\r\nimport { ClassNameProps } from \"../utils/Props\";\r\n\r\n// cSpell:ignore dompurify\r\n\r\n/** Properties for the [[MessageRenderer]] component\r\n * @public\r\n */\r\nexport interface MessageRendererProps extends ClassNameProps {\r\n /** Message to render */\r\n message: MessageType;\r\n /** Indicates whether to use a `span` or `div` element for rendering */\r\n useSpan?: boolean;\r\n}\r\n\r\n/** React component renders a string, HTMLElement or React node in a `div` or `span`\r\n * @public\r\n */\r\nexport function MessageRenderer(props: MessageRendererProps) {\r\n let messageNode = null;\r\n const OutElement = props.useSpan ? \"span\" : \"div\";\r\n\r\n if (typeof props.message === \"string\") {\r\n messageNode = <OutElement className={props.className}>{props.message}</OutElement>;\r\n } else if (isHTMLElement(props.message)) {\r\n // the esm build of dompurify has a default import but the cjs build does not\r\n // if there is a default export, use it (likely esm), otherwise use the namespace\r\n // istanbul ignore next\r\n const sanitizer = DOMPurify ?? DOMPurifyNS; // `sanitizer` is default function name for \"jam3/no-sanitizer-with-danger\" ESLint rule\r\n\r\n let validAnchors = false;\r\n let hasAnchors = false;\r\n\r\n // verify that the tag has proper relationships\r\n const isAnchorValid = (anchor: HTMLAnchorElement): boolean => {\r\n return anchor.hasAttribute(\"rel\") && (anchor.rel.includes(\"noopener\") || anchor.rel.includes(\"noreferrer\"));\r\n };\r\n\r\n // recursively check child elements for valid anchor tags\r\n const checkChildAnchors = (parent: Element) => {\r\n const children = Array.from(parent.children);\r\n for (const child of children){\r\n if (child.hasAttribute(\"target\") && (child as HTMLAnchorElement).target === \"_blank\") {\r\n hasAnchors = true;\r\n validAnchors = isAnchorValid(child as HTMLAnchorElement);\r\n if (!validAnchors) {\r\n return;\r\n }\r\n }\r\n checkChildAnchors(child);\r\n }\r\n };\r\n\r\n // check for anchor tags in the message that have target _blank also have a relationship that avoids security holes\r\n // https://web.dev/external-anchors-use-rel-noopener/\r\n // first check the message element\r\n /* istanbul ignore else */\r\n if (props.message.hasAttribute(\"target\") && (props.message as HTMLAnchorElement).target === \"_blank\") {\r\n hasAnchors = true;\r\n validAnchors = isAnchorValid(props.message as HTMLAnchorElement);\r\n } else {\r\n // if the message element is not an anchor, recursively verify it's children\r\n if (props.message.children) {\r\n checkChildAnchors(props.message);\r\n }\r\n }\r\n\r\n let sanitizedHtml;\r\n if (hasAnchors && validAnchors) {\r\n // all anchors are valid. do not remove the target attr\r\n sanitizedHtml = sanitizer.sanitize(props.message.outerHTML, {ADD_ATTR: [\"target\"]});\r\n } else {\r\n sanitizedHtml = sanitizer.sanitize(props.message.outerHTML);\r\n }\r\n\r\n // we can safely disable jam3/no-sanitizer-with-danger as we are sanitizing above\r\n // eslint-disable-next-line @typescript-eslint/naming-convention, jam3/no-sanitizer-with-danger\r\n messageNode = <OutElement className={props.className} dangerouslySetInnerHTML={{ __html: sanitizedHtml }} />;\r\n } else {\r\n /* istanbul ignore else */\r\n if (isReactMessage(props.message))\r\n messageNode = <OutElement className={props.className}>{props.message.reactNode}</OutElement>;\r\n }\r\n\r\n return messageNode;\r\n}\r\n"]}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import { ConditionalStringValue } from "@itwin/appui-abstract";
|
|
6
|
+
import { IconSpec } from "../icons/IconComponent";
|
|
6
7
|
/** Icon Helper Class used to store the data needed to generate an <Icon> for use in any control that shows an icon.
|
|
7
8
|
* @public
|
|
8
9
|
*/
|
|
@@ -18,6 +19,6 @@ export declare class IconHelper {
|
|
|
18
19
|
* @param iconSpec any supported variations of how an icon can be defined in an abstract item or IconProps.
|
|
19
20
|
* @param internalData a map supplied by the caller to store away react element if React.ReactNode
|
|
20
21
|
*/
|
|
21
|
-
static getIconData(iconSpec:
|
|
22
|
+
static getIconData(iconSpec: IconSpec, internalData?: Map<string, any>): string | ConditionalStringValue;
|
|
22
23
|
}
|
|
23
24
|
//# sourceMappingURL=IconHelper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconHelper.d.ts","sourceRoot":"","sources":["../../../../src/core-react/utils/IconHelper.tsx"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"IconHelper.d.ts","sourceRoot":"","sources":["../../../../src/core-react/utils/IconHelper.tsx"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAQ,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAExD;;GAEG;AACH,qBAAa,UAAU;IACrB,WAAkB,YAAY,IAAI,MAAM,CAEvC;IACD;;;OAGG;WACW,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,sBAAsB,GAAG,KAAK,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,SAAS;IA2BzI;;;;OAIG;WACW,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,GAAG,sBAAsB;CAYhH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconHelper.js","sourceRoot":"","sources":["../../../../src/core-react/utils/IconHelper.tsx"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"IconHelper.js","sourceRoot":"","sources":["../../../../src/core-react/utils/IconHelper.tsx"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAY,MAAM,wBAAwB,CAAC;AAExD;;GAEG;AACH,MAAM,OAAO,UAAU;IACd,MAAM,KAAK,YAAY;QAC5B,OAAO,yBAAyB,CAAC;IACnC,CAAC;IACD;;;OAGG;IACI,MAAM,CAAC,gBAAgB,CAAC,IAAuD,EAAE,YAA+B;QACrH,uBAAuB;QACvB,IAAI,CAAC,IAAI;YACP,OAAO,IAAI,CAAC;QAEd,uBAAuB;QACvB,IAAI,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC;YAC5B,OAAO,oBAAC,IAAI,IAAC,QAAQ,EAAE,IAAI,GAAI,CAAC;QAElC,qBAAqB;QACrB,IAAI,CAAC,CAAC,IAAI,YAAY,sBAAsB,CAAC,IAAI,OAAO,IAAI,KAAK,QAAQ;YACvE,OAAO,IAAI,CAAC;QAEd,MAAM,UAAU,GAAG,sBAAsB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACzD,IAAI,CAAC,UAAU;YACb,OAAO,IAAI,CAAC;QAEd,uBAAuB;QACvB,IAAI,UAAU,KAAK,UAAU,CAAC,YAAY,EAAE;YAC1C,uBAAuB;YACvB,IAAI,YAAY;gBACd,OAAO,oBAAC,IAAI,IAAC,QAAQ,EAAE,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAoB,GAAI,CAAC;YAC1F,OAAO,IAAI,CAAC;SACb;QACD,OAAO,oBAAC,IAAI,IAAC,QAAQ,EAAE,UAAU,GAAI,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,WAAW,CAAC,QAAkB,EAAE,YAA+B;QAC3E,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;QAEnF,IAAI,YAAY,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,UAAU,CAAC,YAAY,EAAE;YAChF,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;SACrD;QAED,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,YAAY,sBAAsB;YACpE,OAAO,IAAI,CAAC;QAEd,OAAO,EAAE,CAAC;IACZ,CAAC;CACF","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Utilities\r\n */\r\n\r\nimport * as React from \"react\";\r\nimport { ConditionalStringValue } from \"@itwin/appui-abstract\";\r\nimport { Icon, IconSpec } from \"../icons/IconComponent\";\r\n\r\n/** Icon Helper Class used to store the data needed to generate an <Icon> for use in any control that shows an icon.\r\n * @public\r\n */\r\nexport class IconHelper {\r\n public static get reactIconKey(): string {\r\n return \"#-react-iconspec-node-#\";\r\n }\r\n /** Returns an <Icon> ReactNode from the many ways an icon can be specified.\r\n * @param icon abstract icon specification.\r\n * @param internalData a map that may hold a React.ReactNode stored in an abstract item definition.\r\n */\r\n public static getIconReactNode(icon: string | ConditionalStringValue | React.ReactNode, internalData?: Map<string, any>): React.ReactNode {\r\n // istanbul ignore else\r\n if (!icon)\r\n return null;\r\n\r\n // istanbul ignore else\r\n if (React.isValidElement(icon))\r\n return <Icon iconSpec={icon} />;\r\n\r\n // istanbul ignore if\r\n if (!(icon instanceof ConditionalStringValue) && typeof icon !== \"string\")\r\n return null;\r\n\r\n const iconString = ConditionalStringValue.getValue(icon);\r\n if (!iconString)\r\n return null;\r\n\r\n // istanbul ignore else\r\n if (iconString === IconHelper.reactIconKey) {\r\n // istanbul ignore else\r\n if (internalData)\r\n return <Icon iconSpec={internalData.get(IconHelper.reactIconKey) as React.ReactNode} />;\r\n return null;\r\n }\r\n return <Icon iconSpec={iconString} />;\r\n }\r\n\r\n /** Returns an icon definition that can be stored in an abstract item definition. If the iconSpec specifies a ReactNode\r\n * then the react data is stored in the internalData map and the key to the react data is returned.\r\n * @param iconSpec any supported variations of how an icon can be defined in an abstract item or IconProps.\r\n * @param internalData a map supplied by the caller to store away react element if React.ReactNode\r\n */\r\n public static getIconData(iconSpec: IconSpec, internalData?: Map<string, any>): string | ConditionalStringValue {\r\n const icon = (React.isValidElement(iconSpec)) ? IconHelper.reactIconKey : iconSpec;\r\n\r\n if (internalData && typeof icon === \"string\" && icon === IconHelper.reactIconKey) {\r\n internalData.set(IconHelper.reactIconKey, iconSpec);\r\n }\r\n\r\n if (typeof icon === \"string\" || icon instanceof ConditionalStringValue)\r\n return icon;\r\n\r\n return \"\";\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** @packageDocumentation
|
|
2
|
+
* @module Utilities
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* IconWebComponent loads icon from an svg path
|
|
6
|
+
*/
|
|
7
|
+
export declare class IconWebComponent extends HTMLElement {
|
|
8
|
+
private connectedCallback;
|
|
9
|
+
private loadSvg;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=IconWebComponent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IconWebComponent.d.ts","sourceRoot":"","sources":["../../../../src/core-react/utils/IconWebComponent.ts"],"names":[],"mappings":"AAMA;;GAEG;AAMH;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,WAAW;YACjC,iBAAiB;YAKjB,OAAO;CAqBtB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
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
|
+
// istanbul ignore file
|
|
6
|
+
// IconWebComponent requires in-browser testing
|
|
7
|
+
/** @packageDocumentation
|
|
8
|
+
* @module Utilities
|
|
9
|
+
*/
|
|
10
|
+
import { UiError } from "@itwin/appui-abstract";
|
|
11
|
+
import { Logger } from "@itwin/core-bentley";
|
|
12
|
+
import { UiCore } from "../UiCore";
|
|
13
|
+
/**
|
|
14
|
+
* IconWebComponent loads icon from an svg path
|
|
15
|
+
*/
|
|
16
|
+
export class IconWebComponent extends HTMLElement {
|
|
17
|
+
async connectedCallback() {
|
|
18
|
+
await this.loadSvg();
|
|
19
|
+
this.dispatchEvent(new CustomEvent("load"));
|
|
20
|
+
}
|
|
21
|
+
async loadSvg() {
|
|
22
|
+
await fetch(this.getAttribute("src") || "")
|
|
23
|
+
.catch((_error) => {
|
|
24
|
+
Logger.logError(UiCore.loggerCategory(this), "Unable to load icon.");
|
|
25
|
+
})
|
|
26
|
+
.then(async (response) => {
|
|
27
|
+
if (response && response.ok) {
|
|
28
|
+
return response.text();
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
throw new UiError(UiCore.loggerCategory(this), "Unable to load icon.");
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
.then((str) => {
|
|
35
|
+
if (str !== undefined) {
|
|
36
|
+
return (new window.DOMParser()).parseFromString(str, "text/xml");
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
throw new UiError(UiCore.loggerCategory(this), "Unable to load icon.");
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
.then((data) => this.append(data.documentElement));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=IconWebComponent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IconWebComponent.js","sourceRoot":"","sources":["../../../../src/core-react/utils/IconWebComponent.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F,uBAAuB;AACvB,+CAA+C;AAC/C;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC;;GAEG;AACH,MAAM,OAAO,gBAAiB,SAAQ,WAAW;IACvC,KAAK,CAAC,iBAAiB;QAC7B,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,CAAC;IAEO,KAAK,CAAC,OAAO;QACnB,MAAM,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;aACxC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE;YAChB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,sBAAsB,CAAC,CAAC;QACvE,CAAC,CAAC;aACD,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;YACvB,IAAI,QAAQ,IAAI,QAAQ,CAAC,EAAE,EAAE;gBAC3B,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;aACxB;iBAAM;gBACL,MAAM,IAAI,OAAO,CAAE,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,sBAAsB,CAAC,CAAC;aACzE;QACH,CAAC,CAAC;aACD,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;YACZ,IAAI,GAAG,KAAK,SAAS,EAAE;gBACrB,OAAO,CAAC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;aAClE;iBAAM;gBACL,MAAM,IAAI,OAAO,CAAE,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,sBAAsB,CAAC,CAAC;aACzE;QACH,CAAC,CAAC;aACD,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IACvD,CAAC;CACF","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n// istanbul ignore file\r\n// IconWebComponent requires in-browser testing\r\n/** @packageDocumentation\r\n * @module Utilities\r\n */\r\n\r\nimport { UiError } from \"@itwin/appui-abstract\";\r\nimport { Logger } from \"@itwin/core-bentley\";\r\nimport { UiCore } from \"../UiCore\";\r\n\r\n/**\r\n * IconWebComponent loads icon from an svg path\r\n */\r\nexport class IconWebComponent extends HTMLElement {\r\n private async connectedCallback() {\r\n await this.loadSvg();\r\n this.dispatchEvent(new CustomEvent(\"load\"));\r\n }\r\n\r\n private async loadSvg() {\r\n await fetch(this.getAttribute(\"src\") || \"\")\r\n .catch((_error) => {\r\n Logger.logError(UiCore.loggerCategory(this), \"Unable to load icon.\");\r\n })\r\n .then(async (response) => {\r\n if (response && response.ok) {\r\n return response.text();\r\n } else {\r\n throw new UiError (UiCore.loggerCategory(this), \"Unable to load icon.\");\r\n }\r\n })\r\n .then((str) => {\r\n if (str !== undefined) {\r\n return (new window.DOMParser()).parseFromString(str, \"text/xml\");\r\n } else {\r\n throw new UiError (UiCore.loggerCategory(this), \"Unable to load icon.\");\r\n }\r\n })\r\n .then((data) => this.append(data.documentElement));\r\n }\r\n}\r\n"]}
|
|
@@ -55,7 +55,7 @@ export function useResizeObserver(onResize) {
|
|
|
55
55
|
owningWindowRef.current = target.ownerDocument.defaultView;
|
|
56
56
|
// istanbul ignore else
|
|
57
57
|
if (owningWindowRef.current) {
|
|
58
|
-
owningWindowRef.current.addEventListener("
|
|
58
|
+
owningWindowRef.current.addEventListener("unload", resizeObserverCleanup);
|
|
59
59
|
// using requestAnimationFrame to stop the "ResizeObserver loop completed with undelivered notifications." and
|
|
60
60
|
// "ResizeObserver loop limit exceeded" messages reported to window.onError
|
|
61
61
|
rafRef.current = owningWindowRef.current.requestAnimationFrame(() => processResize(target));
|
|
@@ -142,7 +142,7 @@ export function useLayoutResizeObserver(inElement, onResize) {
|
|
|
142
142
|
owningWindowRef.current = target.ownerDocument.defaultView;
|
|
143
143
|
// istanbul ignore else
|
|
144
144
|
if (owningWindowRef.current) {
|
|
145
|
-
owningWindowRef.current.addEventListener("
|
|
145
|
+
owningWindowRef.current.addEventListener("unload", resizeObserverCleanup);
|
|
146
146
|
// using requestAnimationFrame to stop the "ResizeObserver loop completed with undelivered notifications." and
|
|
147
147
|
// "ResizeObserver loop limit exceeded" messages reported to window.onError
|
|
148
148
|
rafRef.current = owningWindowRef.current.requestAnimationFrame(() => processResize(target));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useResizeObserver.js","sourceRoot":"","sources":["../../../../../src/core-react/utils/hooks/useResizeObserver.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Utilities\r\n */\r\nimport * as React from \"react\";\r\nimport { ResizeObserver } from \"./ResizeObserverPolyfill\";\r\nimport { useRefEffect } from \"./useRefEffect\";\r\nimport { useRefs } from \"./useRefs\";\r\n\r\n/** Uses ResizeObserver API to notify about element bound changes.\r\n * @internal\r\n */\r\nexport function useResizeObserver<T extends Element>(onResize?: (width: number, height: number) => void) {\r\n const [bounds, setBounds] = React.useState({ width: 0, height: 0 });\r\n const resizeObserver = React.useRef<ResizeObserver | null>(null);\r\n const rafRef = React.useRef(0); // set to non-zero when requestAnimationFrame processing is active\r\n const isMountedRef = React.useRef(false);\r\n const owningWindowRef = React.useRef<any>(null);\r\n\r\n // istanbul ignore next\r\n const resizeObserverCleanup = () => {\r\n if (rafRef.current)\r\n owningWindowRef.current.cancelAnimationFrame(rafRef.current);\r\n\r\n resizeObserver.current?.disconnect();\r\n resizeObserver.current = null;\r\n };\r\n\r\n React.useEffect(() => {\r\n isMountedRef.current = true;\r\n return () => {\r\n isMountedRef.current = false;\r\n if (rafRef.current)\r\n owningWindowRef.current.cancelAnimationFrame(rafRef.current);\r\n owningWindowRef.current?.removeEventListener(\"beforeunload\", resizeObserverCleanup);\r\n };\r\n }, []);\r\n\r\n const processResize = React.useCallback((target: HTMLElement) => {\r\n const newBounds = target.getBoundingClientRect();\r\n // istanbul ignore else\r\n if (isMountedRef.current && (bounds.width !== newBounds.width || bounds.height !== newBounds.height)) {\r\n setBounds(newBounds);\r\n onResize && onResize(newBounds.width, newBounds.height);\r\n }\r\n }, [onResize, bounds.height, bounds.width]);\r\n\r\n const handleResize = React.useCallback((entries: any[]) => {\r\n // istanbul ignore if\r\n if (!isMountedRef.current || !Array.isArray(entries) || 0 === entries.length) {\r\n return;\r\n }\r\n const target = entries[0].target as HTMLElement;\r\n // istanbul ignore next\r\n owningWindowRef.current && owningWindowRef.current.removeEventListener(\"beforeunload\", resizeObserverCleanup);\r\n\r\n owningWindowRef.current = target.ownerDocument.defaultView;\r\n // istanbul ignore else\r\n if (owningWindowRef.current) {\r\n owningWindowRef.current.addEventListener(\"beforeunload\", resizeObserverCleanup);\r\n\r\n // using requestAnimationFrame to stop the \"ResizeObserver loop completed with undelivered notifications.\" and\r\n // \"ResizeObserver loop limit exceeded\" messages reported to window.onError\r\n rafRef.current = owningWindowRef.current.requestAnimationFrame(() => processResize(target));\r\n }\r\n }, [processResize]);\r\n\r\n const observerRef = useRefEffect((instance: T | null) => {\r\n resizeObserver.current = new ResizeObserver(handleResize);\r\n if (instance) {\r\n resizeObserver.current.observe(instance);\r\n const newBounds = instance.getBoundingClientRect();\r\n onResize && onResize(newBounds.width, newBounds.height);\r\n setBounds(newBounds);\r\n }\r\n\r\n return () => {\r\n instance && ( /* istanbul ignore next */resizeObserver.current?.unobserve(instance));\r\n resizeObserver.current = null;\r\n };\r\n }, [handleResize, onResize]);\r\n\r\n const handleRef = React.useCallback((instance: Element | null) => {\r\n const newBounds = instance && instance.getBoundingClientRect();\r\n // istanbul ignore if\r\n if (newBounds && (bounds.width !== newBounds.width || bounds.height !== newBounds.height)) {\r\n setBounds(newBounds);\r\n onResize && onResize(newBounds.width, newBounds.height);\r\n }\r\n }, [bounds.height, bounds.width, onResize]);\r\n\r\n const ref = useRefs(handleRef, observerRef);\r\n return ref;\r\n}\r\n\r\n/** React hook that uses ResizeObserver API to notify about element bound changes. Note: to work similar to ReactResizeDetector\r\n * width and height are initialized as undefined and only set during after mount if bounds are non-zero. This implementation properly\r\n * handles observing element in pop-out/child windows.\r\n * @internal\r\n */\r\nexport function useLayoutResizeObserver(inElement: HTMLElement | null, onResize?: (width?: number, height?: number) => void) {\r\n const inBoundingRect = inElement?.getBoundingClientRect();\r\n const [bounds, setBounds] = React.useState<{ width?: number, height?: number }>({ width: inBoundingRect?.width, height: inBoundingRect?.height });\r\n const [watchedElement, setWatchedElement] = React.useState(inElement);\r\n const resizeObserver = React.useRef<ResizeObserver | null>(null);\r\n const rafRef = React.useRef(0); // set to non-zero when requestAnimationFrame processing is active\r\n const isMountedRef = React.useRef(false);\r\n const owningWindowRef = React.useRef<any>(null);\r\n\r\n // istanbul ignore next\r\n const resizeObserverCleanup = () => {\r\n if (rafRef.current)\r\n owningWindowRef.current.cancelAnimationFrame(rafRef.current);\r\n\r\n resizeObserver.current?.disconnect();\r\n resizeObserver.current = null;\r\n };\r\n\r\n React.useEffect(() => {\r\n isMountedRef.current = true;\r\n setWatchedElement(inElement);\r\n\r\n // istanbul ignore next\r\n if (inElement) {\r\n const newBounds = inElement.getBoundingClientRect();\r\n onResize && onResize(newBounds.width, newBounds.height);\r\n setBounds(newBounds);\r\n }\r\n\r\n return () => {\r\n isMountedRef.current = false;\r\n (rafRef.current && owningWindowRef.current) && owningWindowRef.current.cancelAnimationFrame(rafRef.current);\r\n owningWindowRef.current && owningWindowRef.current.removeEventListener(\"beforeunload\", resizeObserverCleanup);\r\n };\r\n }, [onResize, inElement]);\r\n\r\n const processResize = React.useCallback((target: HTMLElement) => {\r\n const newBounds = target.getBoundingClientRect();\r\n // istanbul ignore next\r\n if (isMountedRef.current && (bounds.width !== newBounds.width || bounds.height !== newBounds.height)) {\r\n onResize && onResize(newBounds.width, newBounds.height);\r\n setBounds(newBounds);\r\n }\r\n }, [bounds.height, bounds.width, onResize]);\r\n\r\n const handleResize = React.useCallback((entries: any[]) => {\r\n // istanbul ignore next\r\n if (!isMountedRef.current || !Array.isArray(entries) || 0 === entries.length) {\r\n return;\r\n }\r\n const target = entries[0].target as HTMLElement;\r\n // istanbul ignore next\r\n if (owningWindowRef.current)\r\n owningWindowRef.current.removeEventListener(\"beforeunload\", resizeObserverCleanup);\r\n\r\n owningWindowRef.current = target.ownerDocument.defaultView;\r\n // istanbul ignore else\r\n if (owningWindowRef.current) {\r\n owningWindowRef.current.addEventListener(\"beforeunload\", resizeObserverCleanup);\r\n\r\n // using requestAnimationFrame to stop the \"ResizeObserver loop completed with undelivered notifications.\" and\r\n // \"ResizeObserver loop limit exceeded\" messages reported to window.onError\r\n rafRef.current = owningWindowRef.current.requestAnimationFrame(() => processResize(target));\r\n }\r\n }, [processResize]);\r\n\r\n React.useLayoutEffect(() => {\r\n if (!watchedElement) {\r\n return;\r\n }\r\n resizeObserver.current = new ResizeObserver(handleResize);\r\n resizeObserver.current.observe(watchedElement);\r\n return () => {\r\n // istanbul ignore next\r\n resizeObserver.current?.disconnect();\r\n resizeObserver.current = null;\r\n };\r\n }, [handleResize, watchedElement]);\r\n\r\n return [bounds.width, bounds.height];\r\n}\r\n\r\n/** Prop the ElementResizeObserver sends to the render function.\r\n * @public\r\n */\r\nexport interface RenderPropsArgs {\r\n width?: number;\r\n height?: number;\r\n}\r\n\r\n/** ElementResizeObserver provides functionality similar to ReactResizeDetector when a render function is specified. This implementation properly handles\r\n * observing element in pop-out/child windows.\r\n * @public\r\n */\r\nexport function ElementResizeObserver({ watchedElement, render }: { watchedElement: HTMLElement | null, render: (props: RenderPropsArgs) => JSX.Element }) {\r\n const [width, height] = useLayoutResizeObserver(watchedElement);\r\n return render({ width, height });\r\n}\r\n\r\n/** ResizableContainerObserver is a component that provides the functionality similar to the ReactResizeDetector option that call a function when\r\n * the observed element is resized. This implementation properly handles observing element in pop-out/child windows. If children nodes are defined then\r\n * the div added by the component is considered the container whose size will be observed. If no children are provided then the component will report\r\n * size changes from its parent container.\r\n * @public\r\n */\r\nexport function ResizableContainerObserver({ onResize, children }: { onResize: (width: number, height: number) => void, children?: React.ReactNode }) {\r\n const containerRef = React.useRef<HTMLDivElement>(null); // set to non-zero when requestAnimationFrame processing is active\r\n const [containerElement, setContainerElement] = React.useState<HTMLElement | null>(null);\r\n const isMountedRef = React.useRef(false);\r\n const hasChildren = React.Children.count(children) !== 0;\r\n\r\n // if no children are specified then monitor size of parent element.\r\n React.useEffect(() => {\r\n // istanbul ignore next\r\n if (!isMountedRef.current && containerRef.current) {\r\n isMountedRef.current = true;\r\n const hasParent = !!containerRef.current.parentElement;\r\n setContainerElement(hasChildren && hasParent ? containerRef.current : containerRef.current.parentElement);\r\n }\r\n }, [hasChildren]);\r\n\r\n const processResize = React.useCallback((width?: number, height?: number) => {\r\n // istanbul ignore next\r\n onResize(width ?? 0, height ?? 0);\r\n }, [onResize]);\r\n\r\n useLayoutResizeObserver(containerElement, processResize);\r\n const style: React.CSSProperties = hasChildren ? { width: \"100%\", height: \"100%\" } : { display: \"none\" };\r\n\r\n return (\r\n <div ref={containerRef} className=\"uicore-resizable-container\" style={style}>\r\n {hasChildren && children}\r\n </div>\r\n );\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"useResizeObserver.js","sourceRoot":"","sources":["../../../../../src/core-react/utils/hooks/useResizeObserver.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Utilities\r\n */\r\nimport * as React from \"react\";\r\nimport { ResizeObserver } from \"./ResizeObserverPolyfill\";\r\nimport { useRefEffect } from \"./useRefEffect\";\r\nimport { useRefs } from \"./useRefs\";\r\n\r\n/** Uses ResizeObserver API to notify about element bound changes.\r\n * @internal\r\n */\r\nexport function useResizeObserver<T extends Element>(onResize?: (width: number, height: number) => void) {\r\n const [bounds, setBounds] = React.useState({ width: 0, height: 0 });\r\n const resizeObserver = React.useRef<ResizeObserver | null>(null);\r\n const rafRef = React.useRef(0); // set to non-zero when requestAnimationFrame processing is active\r\n const isMountedRef = React.useRef(false);\r\n const owningWindowRef = React.useRef<any>(null);\r\n\r\n // istanbul ignore next\r\n const resizeObserverCleanup = () => {\r\n if (rafRef.current)\r\n owningWindowRef.current.cancelAnimationFrame(rafRef.current);\r\n\r\n resizeObserver.current?.disconnect();\r\n resizeObserver.current = null;\r\n };\r\n\r\n React.useEffect(() => {\r\n isMountedRef.current = true;\r\n return () => {\r\n isMountedRef.current = false;\r\n if (rafRef.current)\r\n owningWindowRef.current.cancelAnimationFrame(rafRef.current);\r\n owningWindowRef.current?.removeEventListener(\"beforeunload\", resizeObserverCleanup);\r\n };\r\n }, []);\r\n\r\n const processResize = React.useCallback((target: HTMLElement) => {\r\n const newBounds = target.getBoundingClientRect();\r\n // istanbul ignore else\r\n if (isMountedRef.current && (bounds.width !== newBounds.width || bounds.height !== newBounds.height)) {\r\n setBounds(newBounds);\r\n onResize && onResize(newBounds.width, newBounds.height);\r\n }\r\n }, [onResize, bounds.height, bounds.width]);\r\n\r\n const handleResize = React.useCallback((entries: any[]) => {\r\n // istanbul ignore if\r\n if (!isMountedRef.current || !Array.isArray(entries) || 0 === entries.length) {\r\n return;\r\n }\r\n const target = entries[0].target as HTMLElement;\r\n // istanbul ignore next\r\n owningWindowRef.current && owningWindowRef.current.removeEventListener(\"beforeunload\", resizeObserverCleanup);\r\n\r\n owningWindowRef.current = target.ownerDocument.defaultView;\r\n // istanbul ignore else\r\n if (owningWindowRef.current) {\r\n owningWindowRef.current.addEventListener(\"unload\", resizeObserverCleanup);\r\n\r\n // using requestAnimationFrame to stop the \"ResizeObserver loop completed with undelivered notifications.\" and\r\n // \"ResizeObserver loop limit exceeded\" messages reported to window.onError\r\n rafRef.current = owningWindowRef.current.requestAnimationFrame(() => processResize(target));\r\n }\r\n }, [processResize]);\r\n\r\n const observerRef = useRefEffect((instance: T | null) => {\r\n resizeObserver.current = new ResizeObserver(handleResize);\r\n if (instance) {\r\n resizeObserver.current.observe(instance);\r\n const newBounds = instance.getBoundingClientRect();\r\n onResize && onResize(newBounds.width, newBounds.height);\r\n setBounds(newBounds);\r\n }\r\n\r\n return () => {\r\n instance && ( /* istanbul ignore next */resizeObserver.current?.unobserve(instance));\r\n resizeObserver.current = null;\r\n };\r\n }, [handleResize, onResize]);\r\n\r\n const handleRef = React.useCallback((instance: Element | null) => {\r\n const newBounds = instance && instance.getBoundingClientRect();\r\n // istanbul ignore if\r\n if (newBounds && (bounds.width !== newBounds.width || bounds.height !== newBounds.height)) {\r\n setBounds(newBounds);\r\n onResize && onResize(newBounds.width, newBounds.height);\r\n }\r\n }, [bounds.height, bounds.width, onResize]);\r\n\r\n const ref = useRefs(handleRef, observerRef);\r\n return ref;\r\n}\r\n\r\n/** React hook that uses ResizeObserver API to notify about element bound changes. Note: to work similar to ReactResizeDetector\r\n * width and height are initialized as undefined and only set during after mount if bounds are non-zero. This implementation properly\r\n * handles observing element in pop-out/child windows.\r\n * @internal\r\n */\r\nexport function useLayoutResizeObserver(inElement: HTMLElement | null, onResize?: (width?: number, height?: number) => void) {\r\n const inBoundingRect = inElement?.getBoundingClientRect();\r\n const [bounds, setBounds] = React.useState<{ width?: number, height?: number }>({ width: inBoundingRect?.width, height: inBoundingRect?.height });\r\n const [watchedElement, setWatchedElement] = React.useState(inElement);\r\n const resizeObserver = React.useRef<ResizeObserver | null>(null);\r\n const rafRef = React.useRef(0); // set to non-zero when requestAnimationFrame processing is active\r\n const isMountedRef = React.useRef(false);\r\n const owningWindowRef = React.useRef<any>(null);\r\n\r\n // istanbul ignore next\r\n const resizeObserverCleanup = () => {\r\n if (rafRef.current)\r\n owningWindowRef.current.cancelAnimationFrame(rafRef.current);\r\n\r\n resizeObserver.current?.disconnect();\r\n resizeObserver.current = null;\r\n };\r\n\r\n React.useEffect(() => {\r\n isMountedRef.current = true;\r\n setWatchedElement(inElement);\r\n\r\n // istanbul ignore next\r\n if (inElement) {\r\n const newBounds = inElement.getBoundingClientRect();\r\n onResize && onResize(newBounds.width, newBounds.height);\r\n setBounds(newBounds);\r\n }\r\n\r\n return () => {\r\n isMountedRef.current = false;\r\n (rafRef.current && owningWindowRef.current) && owningWindowRef.current.cancelAnimationFrame(rafRef.current);\r\n owningWindowRef.current && owningWindowRef.current.removeEventListener(\"beforeunload\", resizeObserverCleanup);\r\n };\r\n }, [onResize, inElement]);\r\n\r\n const processResize = React.useCallback((target: HTMLElement) => {\r\n const newBounds = target.getBoundingClientRect();\r\n // istanbul ignore next\r\n if (isMountedRef.current && (bounds.width !== newBounds.width || bounds.height !== newBounds.height)) {\r\n onResize && onResize(newBounds.width, newBounds.height);\r\n setBounds(newBounds);\r\n }\r\n }, [bounds.height, bounds.width, onResize]);\r\n\r\n const handleResize = React.useCallback((entries: any[]) => {\r\n // istanbul ignore next\r\n if (!isMountedRef.current || !Array.isArray(entries) || 0 === entries.length) {\r\n return;\r\n }\r\n const target = entries[0].target as HTMLElement;\r\n // istanbul ignore next\r\n if (owningWindowRef.current)\r\n owningWindowRef.current.removeEventListener(\"beforeunload\", resizeObserverCleanup);\r\n\r\n owningWindowRef.current = target.ownerDocument.defaultView;\r\n // istanbul ignore else\r\n if (owningWindowRef.current) {\r\n owningWindowRef.current.addEventListener(\"unload\", resizeObserverCleanup);\r\n\r\n // using requestAnimationFrame to stop the \"ResizeObserver loop completed with undelivered notifications.\" and\r\n // \"ResizeObserver loop limit exceeded\" messages reported to window.onError\r\n rafRef.current = owningWindowRef.current.requestAnimationFrame(() => processResize(target));\r\n }\r\n }, [processResize]);\r\n\r\n React.useLayoutEffect(() => {\r\n if (!watchedElement) {\r\n return;\r\n }\r\n resizeObserver.current = new ResizeObserver(handleResize);\r\n resizeObserver.current.observe(watchedElement);\r\n return () => {\r\n // istanbul ignore next\r\n resizeObserver.current?.disconnect();\r\n resizeObserver.current = null;\r\n };\r\n }, [handleResize, watchedElement]);\r\n\r\n return [bounds.width, bounds.height];\r\n}\r\n\r\n/** Prop the ElementResizeObserver sends to the render function.\r\n * @public\r\n */\r\nexport interface RenderPropsArgs {\r\n width?: number;\r\n height?: number;\r\n}\r\n\r\n/** ElementResizeObserver provides functionality similar to ReactResizeDetector when a render function is specified. This implementation properly handles\r\n * observing element in pop-out/child windows.\r\n * @public\r\n */\r\nexport function ElementResizeObserver({ watchedElement, render }: { watchedElement: HTMLElement | null, render: (props: RenderPropsArgs) => JSX.Element }) {\r\n const [width, height] = useLayoutResizeObserver(watchedElement);\r\n return render({ width, height });\r\n}\r\n\r\n/** ResizableContainerObserver is a component that provides the functionality similar to the ReactResizeDetector option that call a function when\r\n * the observed element is resized. This implementation properly handles observing element in pop-out/child windows. If children nodes are defined then\r\n * the div added by the component is considered the container whose size will be observed. If no children are provided then the component will report\r\n * size changes from its parent container.\r\n * @public\r\n */\r\nexport function ResizableContainerObserver({ onResize, children }: { onResize: (width: number, height: number) => void, children?: React.ReactNode }) {\r\n const containerRef = React.useRef<HTMLDivElement>(null); // set to non-zero when requestAnimationFrame processing is active\r\n const [containerElement, setContainerElement] = React.useState<HTMLElement | null>(null);\r\n const isMountedRef = React.useRef(false);\r\n const hasChildren = React.Children.count(children) !== 0;\r\n\r\n // if no children are specified then monitor size of parent element.\r\n React.useEffect(() => {\r\n // istanbul ignore next\r\n if (!isMountedRef.current && containerRef.current) {\r\n isMountedRef.current = true;\r\n const hasParent = !!containerRef.current.parentElement;\r\n setContainerElement(hasChildren && hasParent ? containerRef.current : containerRef.current.parentElement);\r\n }\r\n }, [hasChildren]);\r\n\r\n const processResize = React.useCallback((width?: number, height?: number) => {\r\n // istanbul ignore next\r\n onResize(width ?? 0, height ?? 0);\r\n }, [onResize]);\r\n\r\n useLayoutResizeObserver(containerElement, processResize);\r\n const style: React.CSSProperties = hasChildren ? { width: \"100%\", height: \"100%\" } : { display: \"none\" };\r\n\r\n return (\r\n <div ref={containerRef} className=\"uicore-resizable-container\" style={style}>\r\n {hasChildren && children}\r\n </div>\r\n );\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/core-react",
|
|
3
|
-
"version": "3.2.0-dev.
|
|
3
|
+
"version": "3.2.0-dev.70",
|
|
4
4
|
"description": "iTwin.js UI core components",
|
|
5
5
|
"main": "lib/cjs/core-react.js",
|
|
6
6
|
"module": "lib/esm/core-react.js",
|
|
7
7
|
"typings": "lib/cjs/core-react",
|
|
8
|
-
"imodeljsSharedLibrary": true,
|
|
9
8
|
"license": "MIT",
|
|
10
9
|
"repository": {
|
|
11
10
|
"type": "git",
|
|
@@ -23,8 +22,8 @@
|
|
|
23
22
|
"url": "http://www.bentley.com"
|
|
24
23
|
},
|
|
25
24
|
"peerDependencies": {
|
|
26
|
-
"@itwin/appui-abstract": "^3.2.0-dev.
|
|
27
|
-
"@itwin/core-bentley": "^3.2.0-dev.
|
|
25
|
+
"@itwin/appui-abstract": "^3.2.0-dev.70",
|
|
26
|
+
"@itwin/core-bentley": "^3.2.0-dev.70",
|
|
28
27
|
"react": "^17.0.0",
|
|
29
28
|
"react-dom": "^17.0.0"
|
|
30
29
|
},
|
|
@@ -33,12 +32,13 @@
|
|
|
33
32
|
"NOTE: All tools used by scripts in this package must be listed as devDependencies"
|
|
34
33
|
],
|
|
35
34
|
"devDependencies": {
|
|
36
|
-
"@itwin/appui-abstract": "3.2.0-dev.
|
|
37
|
-
"@itwin/build-tools": "3.2.0-dev.
|
|
38
|
-
"@itwin/core-bentley": "3.2.0-dev.
|
|
39
|
-
"@itwin/core-common": "3.2.0-dev.
|
|
40
|
-
"@itwin/core-i18n": "3.2.0-dev.
|
|
41
|
-
"@itwin/eslint-plugin": "3.2.0-dev.
|
|
35
|
+
"@itwin/appui-abstract": "3.2.0-dev.70",
|
|
36
|
+
"@itwin/build-tools": "3.2.0-dev.70",
|
|
37
|
+
"@itwin/core-bentley": "3.2.0-dev.70",
|
|
38
|
+
"@itwin/core-common": "3.2.0-dev.70",
|
|
39
|
+
"@itwin/core-i18n": "3.2.0-dev.70",
|
|
40
|
+
"@itwin/eslint-plugin": "3.2.0-dev.70",
|
|
41
|
+
"@testing-library/dom": "^8.11.2",
|
|
42
42
|
"@testing-library/react": "^12.0.0",
|
|
43
43
|
"@testing-library/react-hooks": "^7.0.2",
|
|
44
44
|
"@testing-library/user-event": "^13.2.1",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"enzyme-to-json": "^3.3.4",
|
|
68
68
|
"eslint": "^7.11.0",
|
|
69
69
|
"ignore-styles": "^5.0.1",
|
|
70
|
-
"jsdom": "^
|
|
70
|
+
"jsdom": "^19.0.0",
|
|
71
71
|
"jsdom-global": "3.0.2",
|
|
72
72
|
"mocha": "^8.3.2",
|
|
73
73
|
"nyc": "^15.1.0",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"rimraf": "^3.0.2",
|
|
80
80
|
"sinon": "^9.0.2",
|
|
81
81
|
"sinon-chai": "^3.2.0",
|
|
82
|
-
"ts-node": "^
|
|
82
|
+
"ts-node": "^10.4.0",
|
|
83
83
|
"typemoq": "^2.1.0",
|
|
84
84
|
"typescript": "~4.4.0",
|
|
85
85
|
"xmlhttprequest": "^1.8.0"
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
],
|
|
91
91
|
"dependencies": {
|
|
92
92
|
"@bentley/icons-generic-webfont": "^1.0.15",
|
|
93
|
-
"@itwin/itwinui-css": "0.
|
|
93
|
+
"@itwin/itwinui-css": "0.x",
|
|
94
94
|
"@itwin/itwinui-react": "^1.32.0",
|
|
95
95
|
"classnames": "^2.3.1",
|
|
96
96
|
"dompurify": "^2.0.12",
|