From 48bc75d0977aec29d6d4491c8a7afd61d86d36cc Mon Sep 17 00:00:00 2001 From: "Travis.Cobbs" <77415528+tcobbs-bentley@users.noreply.github.com> Date: Tue, 16 Jul 2024 10:30:13 -0700 Subject: [PATCH 1/3] Move deprecated AppUI functionality into mobile-ui-react. --- src/mobile-ui-react/ActionSheetButton.tsx | 3 +- src/mobile-ui-react/BottomPanel.tsx | 10 +- src/mobile-ui-react/CenterDiv.tsx | 2 +- src/mobile-ui-react/CountNotification.tsx | 4 +- src/mobile-ui-react/HorizontalPicker.tsx | 2 +- src/mobile-ui-react/MobileUi.tsx | 57 +++++++++- src/mobile-ui-react/ModalEntryFormDialog.tsx | 3 +- src/mobile-ui-react/NavigationPanel.tsx | 4 +- src/mobile-ui-react/PanelHeader.tsx | 2 +- src/mobile-ui-react/ResizablePanel.tsx | 3 +- src/mobile-ui-react/ScrollableWithFades.tsx | 3 +- src/mobile-ui-react/Suggestion.tsx | 4 +- src/mobile-ui-react/TabBar.tsx | 3 +- src/mobile-ui-react/TileGrid.tsx | 3 +- src/mobile-ui-react/Timer.ts | 79 ++++++++++++++ src/mobile-ui-react/useOnOutsideClick.tsx | 106 +++++++++++++++++++ 16 files changed, 265 insertions(+), 23 deletions(-) create mode 100644 src/mobile-ui-react/Timer.ts create mode 100644 src/mobile-ui-react/useOnOutsideClick.tsx diff --git a/src/mobile-ui-react/ActionSheetButton.tsx b/src/mobile-ui-react/ActionSheetButton.tsx index 0be4bdc..53bbb13 100644 --- a/src/mobile-ui-react/ActionSheetButton.tsx +++ b/src/mobile-ui-react/ActionSheetButton.tsx @@ -3,9 +3,10 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ import * as React from "react"; -import { CommonProps, IconSpec } from "@itwin/core-react"; +import { IconSpec } from "@itwin/core-react"; import { ActionSheetProps, presentActionSheet } from "@itwin/mobile-sdk-core"; import { NavigationButton } from "./NavigationPanel"; +import { CommonProps } from "./MobileUi"; /** * Properties for {@link ActionSheetButton} diff --git a/src/mobile-ui-react/BottomPanel.tsx b/src/mobile-ui-react/BottomPanel.tsx index 71004a6..ccde32a 100644 --- a/src/mobile-ui-react/BottomPanel.tsx +++ b/src/mobile-ui-react/BottomPanel.tsx @@ -5,9 +5,15 @@ import * as React from "react"; import classnames from "classnames"; import { BeUiEvent } from "@itwin/core-bentley"; -import { CommonProps, getCssVariableAsNumber } from "@itwin/core-react"; import { Optional } from "@itwin/mobile-sdk-core"; -import { makeRefHandler, MutableHtmlDivRefOrFunction, useBeUiEvent, useWindowEvent } from "./MobileUi"; +import { + CommonProps, + getCssVariableAsNumber, + makeRefHandler, + MutableHtmlDivRefOrFunction, + useBeUiEvent, + useWindowEvent, +} from "./MobileUi"; import { PanelHeader, PanelHeaderProps } from "./PanelHeader"; import { ResizablePanel, ResizablePanelProps } from "./ResizablePanel"; import "./BottomPanel.scss"; diff --git a/src/mobile-ui-react/CenterDiv.tsx b/src/mobile-ui-react/CenterDiv.tsx index bcf6c72..31ca6f3 100644 --- a/src/mobile-ui-react/CenterDiv.tsx +++ b/src/mobile-ui-react/CenterDiv.tsx @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as React from "react"; import classnames from "classnames"; -import { CommonProps } from "@itwin/core-react"; import "./CenterDiv.scss"; +import { CommonProps } from "./MobileUi"; /** * Properties for {@link CenterDiv} component diff --git a/src/mobile-ui-react/CountNotification.tsx b/src/mobile-ui-react/CountNotification.tsx index 41e79dc..b40257b 100644 --- a/src/mobile-ui-react/CountNotification.tsx +++ b/src/mobile-ui-react/CountNotification.tsx @@ -4,11 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as React from "react"; import classnames from "classnames"; -import { CommonProps, IconSpec } from "@itwin/core-react"; +import { IconSpec } from "@itwin/core-react"; import { AlertAction } from "@itwin/mobile-sdk-core"; import { ActionSheetButton } from "./ActionSheetButton"; import { IconImage } from "./IconImage"; -import { MobileUi } from "./MobileUi"; +import { CommonProps, MobileUi } from "./MobileUi"; import "./CountNotification.scss"; diff --git a/src/mobile-ui-react/HorizontalPicker.tsx b/src/mobile-ui-react/HorizontalPicker.tsx index 435a1e6..1597a15 100644 --- a/src/mobile-ui-react/HorizontalPicker.tsx +++ b/src/mobile-ui-react/HorizontalPicker.tsx @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as React from "react"; import classnames from "classnames"; -import { CommonProps } from "@itwin/core-react"; +import { CommonProps } from "./MobileUi"; import "./HorizontalPicker.scss"; diff --git a/src/mobile-ui-react/MobileUi.tsx b/src/mobile-ui-react/MobileUi.tsx index 15c186d..27e4744 100644 --- a/src/mobile-ui-react/MobileUi.tsx +++ b/src/mobile-ui-react/MobileUi.tsx @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as React from "react"; import { BackendError, Localization } from "@itwin/core-common"; -import { getCssVariable, getCssVariableAsNumber } from "@itwin/core-react"; import { ColorTheme, SessionStateActionId, SyncUiEventDispatcher, SyncUiEventId, SYSTEM_PREFERRED_COLOR_THEME, UiFramework, UiSyncEventArgs } from "@itwin/appui-react"; import { EmphasizeElements, IModelApp, IModelConnection, ScreenViewport, SelectionSet, Tool, Viewport } from "@itwin/core-frontend"; import { BeEvent, BeUiEvent, BriefcaseStatus, Id64Set, Listener } from "@itwin/core-bentley"; @@ -12,6 +11,30 @@ import { getAllViewports, getEmphasizeElements, Messenger, MobileCore, UIError } import "./MobileUi.scss"; +/** Props used by components that expect class name to be passed in. + * + * __Note__: Copied from @itwin/core-react, where it is being deprecated. It will **not ever** be + * deprecated from @itwin/mobile-ui-react. + * @public + */ +export interface ClassNameProps { + /** Custom CSS class name */ + className?: string; +} + +/** Common props used by components. + * + * __Note__: Copied from @itwin/core-react, where it is being deprecated. It will **not ever** be + * deprecated from @itwin/mobile-ui-react. + * @public + */ +export interface CommonProps extends ClassNameProps { + /** Custom CSS style properties */ + style?: React.CSSProperties; + /** Optional unique identifier for item. If defined it will be added to DOM Element attribute as data-item-id */ + itemId?: string; +} + /** Type used for MobileUi.onClose BeEvent. */ export declare type CloseListener = () => void; @@ -669,3 +692,35 @@ export function useActiveColorSchemeIsDark() { }, [isMountedRef]), MobileUi.onColorSchemeChanged); return isDark; } + +/** Get CSS variable + * @public + * + * __Note__: Copied from @itwin/core-react, where it is being deprecated. It will **not ever** be + * deprecated from @itwin/mobile-ui-react. + */ +export function getCssVariable( + variableName: string, + htmlElement?: HTMLElement, +): string { + const element = htmlElement ?? document.documentElement; + const cssStyles = getComputedStyle(element, null); + const cssVal = String(cssStyles.getPropertyValue(variableName)).trim(); + return cssVal; +} + +/** Get CSS variable as number + * @public + * + * __Note__: Copied from @itwin/core-react, where it is being deprecated. It will **not ever** be + * deprecated from @itwin/mobile-ui-react. + */ +export function getCssVariableAsNumber( + variableName: string, + htmlElement?: HTMLElement, +): number { + let cssValNum: number = NaN; + const cssValStr = getCssVariable(variableName, htmlElement); + if (cssValStr) cssValNum = parseFloat(cssValStr); + return cssValNum; +} diff --git a/src/mobile-ui-react/ModalEntryFormDialog.tsx b/src/mobile-ui-react/ModalEntryFormDialog.tsx index c91d27e..01a55b8 100644 --- a/src/mobile-ui-react/ModalEntryFormDialog.tsx +++ b/src/mobile-ui-react/ModalEntryFormDialog.tsx @@ -4,11 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as React from "react"; import classnames from "classnames"; -import { CommonProps } from "@itwin/core-react"; import { UiFramework } from "@itwin/appui-react"; import { getCssVariableAsNumberOrDefault, MobileCore, Optional } from "@itwin/mobile-sdk-core"; import { CloseButton } from "./NavigationPanel"; -import { MobileUi } from "./MobileUi"; +import { CommonProps, MobileUi } from "./MobileUi"; import "./ModalEntryFormDialog.scss"; diff --git a/src/mobile-ui-react/NavigationPanel.tsx b/src/mobile-ui-react/NavigationPanel.tsx index a832260..f22d5f2 100644 --- a/src/mobile-ui-react/NavigationPanel.tsx +++ b/src/mobile-ui-react/NavigationPanel.tsx @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as React from "react"; import classnames from "classnames"; -import { ClassNameProps, CommonProps, IconSpec } from "@itwin/core-react"; +import { IconSpec } from "@itwin/core-react"; import { ConditionalBooleanValue, ConditionalStringValue } from "@itwin/appui-abstract"; import { IconImage } from "./IconImage"; -import { useSyncUiEvent } from "./MobileUi"; +import { ClassNameProps, CommonProps, useSyncUiEvent } from "./MobileUi"; import "./NavigationPanel.scss"; import { diff --git a/src/mobile-ui-react/PanelHeader.tsx b/src/mobile-ui-react/PanelHeader.tsx index 4d851a3..1cb91d3 100644 --- a/src/mobile-ui-react/PanelHeader.tsx +++ b/src/mobile-ui-react/PanelHeader.tsx @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as React from "react"; import classnames from "classnames"; -import { CommonProps } from "@itwin/core-react"; import { withoutClassName } from "@itwin/mobile-sdk-core"; import { DraggableComponent, DraggableComponentCallbackProps } from "./ResizablePanel"; +import { CommonProps } from "./MobileUi"; import "./PanelHeader.scss"; diff --git a/src/mobile-ui-react/ResizablePanel.tsx b/src/mobile-ui-react/ResizablePanel.tsx index 55b76f1..1b25e49 100644 --- a/src/mobile-ui-react/ResizablePanel.tsx +++ b/src/mobile-ui-react/ResizablePanel.tsx @@ -5,9 +5,8 @@ import * as React from "react"; import classnames from "classnames"; import { Point2d, XAndY } from "@itwin/core-geometry"; -import { CommonProps, getCssVariableAsNumber } from "@itwin/core-react"; import { ReloadedEvent } from "@itwin/mobile-sdk-core"; -import { ReactUseState, useIsMountedRef, useWindowEvent } from "./MobileUi"; +import { CommonProps, getCssVariableAsNumber, ReactUseState, useIsMountedRef, useWindowEvent } from "./MobileUi"; import "./ResizablePanel.scss"; /** diff --git a/src/mobile-ui-react/ScrollableWithFades.tsx b/src/mobile-ui-react/ScrollableWithFades.tsx index 2c0b3e6..10ff8fd 100644 --- a/src/mobile-ui-react/ScrollableWithFades.tsx +++ b/src/mobile-ui-react/ScrollableWithFades.tsx @@ -5,8 +5,7 @@ import * as React from "react"; import classnames from "classnames"; import { ColorDef } from "@itwin/core-common"; -import { ClassNameProps, getCssVariable } from "@itwin/core-react"; -import { useScroll, useWindowEvent } from "./MobileUi"; +import { ClassNameProps, getCssVariable, useScroll, useWindowEvent } from "./MobileUi"; import "./ScrollableWithFades.scss"; diff --git a/src/mobile-ui-react/Suggestion.tsx b/src/mobile-ui-react/Suggestion.tsx index 69c12c0..a2b808e 100644 --- a/src/mobile-ui-react/Suggestion.tsx +++ b/src/mobile-ui-react/Suggestion.tsx @@ -5,10 +5,10 @@ import * as React from "react"; import classnames from "classnames"; import { BeUiEvent } from "@itwin/core-bentley"; -import { getCssVariableAsNumber, useOnOutsideClick } from "@itwin/core-react"; import { ToolAssistanceInstructions } from "@itwin/core-frontend"; import { IconImage } from "./IconImage"; -import { useBeUiEvent } from "./MobileUi"; +import { getCssVariableAsNumber, useBeUiEvent } from "./MobileUi"; +import { useOnOutsideClick } from "./useOnOutsideClick"; import "./Suggestion.scss"; /** diff --git a/src/mobile-ui-react/TabBar.tsx b/src/mobile-ui-react/TabBar.tsx index 1213076..eadfdbd 100644 --- a/src/mobile-ui-react/TabBar.tsx +++ b/src/mobile-ui-react/TabBar.tsx @@ -4,11 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as React from "react"; import classnames from "classnames"; -import { getCssVariable, getCssVariableAsNumber } from "@itwin/core-react"; import { ColorDef } from "@itwin/core-common"; import { BottomPanelProps } from "./BottomPanel"; import { HorizontalScrollableWithFades } from "./ScrollableWithFades"; -import { useHorizontalScrollChildVisibleOnResize } from "./MobileUi"; +import { getCssVariable, getCssVariableAsNumber, useHorizontalScrollChildVisibleOnResize } from "./MobileUi"; import "./TabBar.scss"; diff --git a/src/mobile-ui-react/TileGrid.tsx b/src/mobile-ui-react/TileGrid.tsx index 977420d..1cdd504 100644 --- a/src/mobile-ui-react/TileGrid.tsx +++ b/src/mobile-ui-react/TileGrid.tsx @@ -4,8 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as React from "react"; import classnames from "classnames"; -import { CommonProps } from "@itwin/core-react"; -import { useMediaQuery, useScrolling } from "./MobileUi"; +import { CommonProps, useMediaQuery, useScrolling } from "./MobileUi"; import "./TileGrid.scss"; /** diff --git a/src/mobile-ui-react/Timer.ts b/src/mobile-ui-react/Timer.ts new file mode 100644 index 0000000..8b45b43 --- /dev/null +++ b/src/mobile-ui-react/Timer.ts @@ -0,0 +1,79 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Bentley Systems, Incorporated. All rights reserved. + * See LICENSE.md in the project root for license terms and full copyright notice. + *--------------------------------------------------------------------------------------------*/ + +/* + * NOTE: This entire file was copied from @itwin/core-react, where it is being deprecated. It was + * then modified to make things internal instead of public and deprecated. + */ + +/** Signature for [[Timer]] execute callback. + * @internal + */ +export type ExecuteHandler = (this: void) => void; + +/** Notifies handler after a set interval. + * @internal + */ +export class Timer { + private _delay: number; + private _isRunning = false; + private _timerId = 0; + private _onExecute: ExecuteHandler | undefined; + + /** + * Creates a new Timer. + * @param msDelay Time interval in milliseconds after which handler will be notified. + */ + public constructor(msDelay: number) { + this._delay = msDelay; + } + + /** Indicates whether the timer is running */ + public get isRunning(): boolean { + return this._isRunning; + } + + /** Time interval in milliseconds after which handler will be notified. */ + public get delay() { + return this._delay; + } + public set delay(ms: number) { + this._delay = ms; + } + + /** Set handler that is called after a set interval. */ + public setOnExecute(onExecute: ExecuteHandler | undefined) { + this._onExecute = onExecute; + } + + /** Starts this Timer. */ + public start() { + if (this._isRunning) this.clearTimeout(); + + this._isRunning = true; + this.setTimeout(); + } + + /** Stops this Timer. */ + public stop() { + if (!this._isRunning) return; + + this._isRunning = false; + this.clearTimeout(); + } + + private execute() { + this._onExecute && this._onExecute(); + this._isRunning = false; + } + + private setTimeout() { + this._timerId = window.setTimeout(() => this.execute(), this._delay); + } + + private clearTimeout() { + window.clearTimeout(this._timerId); + } +} diff --git a/src/mobile-ui-react/useOnOutsideClick.tsx b/src/mobile-ui-react/useOnOutsideClick.tsx new file mode 100644 index 0000000..c19cd85 --- /dev/null +++ b/src/mobile-ui-react/useOnOutsideClick.tsx @@ -0,0 +1,106 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Bentley Systems, Incorporated. All rights reserved. + * See LICENSE.md in the project root for license terms and full copyright notice. + *--------------------------------------------------------------------------------------------*/ + +/* + * NOTE: This entire file was copied from @itwin/core-react, where it is being deprecated. It was + * then modified to make things internal instead of public and deprecated. + */ + +import * as React from "react"; +import { Timer } from "./Timer"; + +function hasPointerEventsSupport() { + return !!window.PointerEvent; +} + +/** + * @internal + */ +export type OutsideClickEvent = PointerEvent | MouseEvent | TouchEvent; + +/** Invokes onOutsideClick handler when user clicks outside of referenced element. + * @internal + */ +export function useOnOutsideClick( + onOutsideClick?: () => void, + /** Invoked for intermediate events. Return `false` to prevent outside click. */ + outsideEventPredicate?: (e: OutsideClickEvent) => boolean, +) { + const handleMouseEvents = React.useRef(true); + const handleMouseEventsTimer = React.useRef(new Timer(1000)); + const ref = React.useRef(null); + const isDownOutside = React.useRef(false); + React.useEffect(() => { + const listener = (e: OutsideClickEvent) => { + if (e.type === "touchstart") { + // Skip mouse event handlers after touch event. + handleMouseEvents.current = false; + handleMouseEventsTimer.current.start(); + } else if (e.type === "mousedown" && !handleMouseEvents.current) { + return; + } + const isOutsideEvent = !outsideEventPredicate || outsideEventPredicate(e); + isDownOutside.current = + !!ref.current && + e.target instanceof Node && + !ref.current.contains(e.target) && + isOutsideEvent; + }; + if (hasPointerEventsSupport()) { + document.addEventListener("pointerdown", listener); + } else { + document.addEventListener("mousedown", listener); + document.addEventListener("touchstart", listener); + } + return () => { + if (hasPointerEventsSupport()) { + document.removeEventListener("pointerdown", listener); + } else { + document.removeEventListener("mousedown", listener); + document.removeEventListener("touchstart", listener); + } + }; + }, [outsideEventPredicate]); + React.useEffect(() => { + const listener = (e: OutsideClickEvent) => { + if (e.type === "mouseup" && !handleMouseEvents.current) { + return; + } + onOutsideClick && + isDownOutside.current && + (!outsideEventPredicate || outsideEventPredicate(e)) && + ref.current && + e.target instanceof Node && + !ref.current.contains(e.target) && + onOutsideClick(); + isDownOutside.current = false; + }; + if (hasPointerEventsSupport()) { + document.addEventListener("pointerup", listener); + } else { + document.addEventListener("mouseup", listener); + document.addEventListener("touchend", listener); + } + return () => { + if (hasPointerEventsSupport()) { + document.removeEventListener("pointerup", listener); + } else { + document.removeEventListener("mouseup", listener); + document.removeEventListener("touchend", listener); + } + }; + }, [onOutsideClick, outsideEventPredicate]); + React.useEffect(() => { + const listener = () => { + handleMouseEvents.current = true; + }; + const timer = handleMouseEventsTimer.current; + timer.setOnExecute(listener); + return () => { + timer.setOnExecute(undefined); + }; + }, []); + return ref; +} From 7e30acef6a3594dea5f9e7cd2e84d2ccc36d2151 Mon Sep 17 00:00:00 2001 From: "Travis.Cobbs" <77415528+tcobbs-bentley@users.noreply.github.com> Date: Tue, 16 Jul 2024 13:34:01 -0700 Subject: [PATCH 2/3] Further AppUI deprecation fixes --- src/mobile-ui-react/BottomPanel.tsx | 3 +- src/mobile-ui-react/MobileUi.tsx | 46 ++++++--------------- src/mobile-ui-react/PanViewport.ts | 2 + src/mobile-ui-react/ResizablePanel.tsx | 4 +- src/mobile-ui-react/ScrollableWithFades.tsx | 3 +- src/mobile-ui-react/Suggestion.tsx | 4 +- src/mobile-ui-react/TabBar.tsx | 3 +- 7 files changed, 25 insertions(+), 40 deletions(-) diff --git a/src/mobile-ui-react/BottomPanel.tsx b/src/mobile-ui-react/BottomPanel.tsx index ccde32a..4c7a220 100644 --- a/src/mobile-ui-react/BottomPanel.tsx +++ b/src/mobile-ui-react/BottomPanel.tsx @@ -5,10 +5,9 @@ import * as React from "react"; import classnames from "classnames"; import { BeUiEvent } from "@itwin/core-bentley"; -import { Optional } from "@itwin/mobile-sdk-core"; +import { getCssVariableAsNumber, Optional } from "@itwin/mobile-sdk-core"; import { CommonProps, - getCssVariableAsNumber, makeRefHandler, MutableHtmlDivRefOrFunction, useBeUiEvent, diff --git a/src/mobile-ui-react/MobileUi.tsx b/src/mobile-ui-react/MobileUi.tsx index 27e4744..800ed3e 100644 --- a/src/mobile-ui-react/MobileUi.tsx +++ b/src/mobile-ui-react/MobileUi.tsx @@ -7,7 +7,15 @@ import { BackendError, Localization } from "@itwin/core-common"; import { ColorTheme, SessionStateActionId, SyncUiEventDispatcher, SyncUiEventId, SYSTEM_PREFERRED_COLOR_THEME, UiFramework, UiSyncEventArgs } from "@itwin/appui-react"; import { EmphasizeElements, IModelApp, IModelConnection, ScreenViewport, SelectionSet, Tool, Viewport } from "@itwin/core-frontend"; import { BeEvent, BeUiEvent, BriefcaseStatus, Id64Set, Listener } from "@itwin/core-bentley"; -import { getAllViewports, getEmphasizeElements, Messenger, MobileCore, UIError } from "@itwin/mobile-sdk-core"; +import { + getAllViewports, + getCssVariable, + getCssVariableAsNumber, + getEmphasizeElements, + Messenger, + MobileCore, + UIError, +} from "@itwin/mobile-sdk-core"; import "./MobileUi.scss"; @@ -105,6 +113,8 @@ export class MobileUi { const isDark = MobileUi.activeColorSchemeIsDark; if (UiFramework.initialized) { const newTheme = isDark ? ColorTheme.Dark : ColorTheme.Light; + // @todo AppUI deprecation + // eslint-disable-next-line deprecation/deprecation UiFramework.setColorTheme(newTheme); // The imodeljs UI framework relies on the "data-theme" attribute. Since the only two ColorTheme // values are Light and Dark, the below handles those and Automatic. @@ -570,6 +580,8 @@ export function useIsolatedCount(): number { export function useIModel(handler: (iModel: IModelConnection | undefined) => void) { useSyncUiEvent(React.useCallback(() => { handler(UiFramework.getIModelConnection()); + // @todo AppUI deprecation + // eslint-disable-next-line deprecation/deprecation }, [handler]), SessionStateActionId.SetIModelConnection); } @@ -692,35 +704,3 @@ export function useActiveColorSchemeIsDark() { }, [isMountedRef]), MobileUi.onColorSchemeChanged); return isDark; } - -/** Get CSS variable - * @public - * - * __Note__: Copied from @itwin/core-react, where it is being deprecated. It will **not ever** be - * deprecated from @itwin/mobile-ui-react. - */ -export function getCssVariable( - variableName: string, - htmlElement?: HTMLElement, -): string { - const element = htmlElement ?? document.documentElement; - const cssStyles = getComputedStyle(element, null); - const cssVal = String(cssStyles.getPropertyValue(variableName)).trim(); - return cssVal; -} - -/** Get CSS variable as number - * @public - * - * __Note__: Copied from @itwin/core-react, where it is being deprecated. It will **not ever** be - * deprecated from @itwin/mobile-ui-react. - */ -export function getCssVariableAsNumber( - variableName: string, - htmlElement?: HTMLElement, -): number { - let cssValNum: number = NaN; - const cssValStr = getCssVariable(variableName, htmlElement); - if (cssValStr) cssValNum = parseFloat(cssValStr); - return cssValNum; -} diff --git a/src/mobile-ui-react/PanViewport.ts b/src/mobile-ui-react/PanViewport.ts index 4bb5434..04ff28d 100644 --- a/src/mobile-ui-react/PanViewport.ts +++ b/src/mobile-ui-react/PanViewport.ts @@ -73,6 +73,8 @@ export class PanTracker { // @todo FIX Remove deprecated usage once appui-react provides a reasonable solution. // eslint-disable-next-line deprecation/deprecation private _onSyncUi = (args: UiSyncEventArgs) => { + // @todo AppUI deprecation + // eslint-disable-next-line deprecation/deprecation if (args.eventIds.has(SessionStateActionId.SetIModelConnection) && this._vpParentDivId) { let panTracker = PanTracker.getWithKey(this._vpParentDivId); const nextX = panTracker.nextX; diff --git a/src/mobile-ui-react/ResizablePanel.tsx b/src/mobile-ui-react/ResizablePanel.tsx index 1b25e49..5d787e7 100644 --- a/src/mobile-ui-react/ResizablePanel.tsx +++ b/src/mobile-ui-react/ResizablePanel.tsx @@ -5,8 +5,8 @@ import * as React from "react"; import classnames from "classnames"; import { Point2d, XAndY } from "@itwin/core-geometry"; -import { ReloadedEvent } from "@itwin/mobile-sdk-core"; -import { CommonProps, getCssVariableAsNumber, ReactUseState, useIsMountedRef, useWindowEvent } from "./MobileUi"; +import { getCssVariableAsNumber, ReloadedEvent } from "@itwin/mobile-sdk-core"; +import { CommonProps, ReactUseState, useIsMountedRef, useWindowEvent } from "./MobileUi"; import "./ResizablePanel.scss"; /** diff --git a/src/mobile-ui-react/ScrollableWithFades.tsx b/src/mobile-ui-react/ScrollableWithFades.tsx index 10ff8fd..80572cb 100644 --- a/src/mobile-ui-react/ScrollableWithFades.tsx +++ b/src/mobile-ui-react/ScrollableWithFades.tsx @@ -5,7 +5,8 @@ import * as React from "react"; import classnames from "classnames"; import { ColorDef } from "@itwin/core-common"; -import { ClassNameProps, getCssVariable, useScroll, useWindowEvent } from "./MobileUi"; +import { ClassNameProps, useScroll, useWindowEvent } from "./MobileUi"; +import { getCssVariable } from "@itwin/mobile-sdk-core"; import "./ScrollableWithFades.scss"; diff --git a/src/mobile-ui-react/Suggestion.tsx b/src/mobile-ui-react/Suggestion.tsx index a2b808e..dc93a7e 100644 --- a/src/mobile-ui-react/Suggestion.tsx +++ b/src/mobile-ui-react/Suggestion.tsx @@ -7,8 +7,10 @@ import classnames from "classnames"; import { BeUiEvent } from "@itwin/core-bentley"; import { ToolAssistanceInstructions } from "@itwin/core-frontend"; import { IconImage } from "./IconImage"; -import { getCssVariableAsNumber, useBeUiEvent } from "./MobileUi"; +import { useBeUiEvent } from "./MobileUi"; import { useOnOutsideClick } from "./useOnOutsideClick"; +import { getCssVariableAsNumber } from "@itwin/mobile-sdk-core"; + import "./Suggestion.scss"; /** diff --git a/src/mobile-ui-react/TabBar.tsx b/src/mobile-ui-react/TabBar.tsx index eadfdbd..d34cc2b 100644 --- a/src/mobile-ui-react/TabBar.tsx +++ b/src/mobile-ui-react/TabBar.tsx @@ -7,7 +7,8 @@ import classnames from "classnames"; import { ColorDef } from "@itwin/core-common"; import { BottomPanelProps } from "./BottomPanel"; import { HorizontalScrollableWithFades } from "./ScrollableWithFades"; -import { getCssVariable, getCssVariableAsNumber, useHorizontalScrollChildVisibleOnResize } from "./MobileUi"; +import { useHorizontalScrollChildVisibleOnResize } from "./MobileUi"; +import { getCssVariable, getCssVariableAsNumber } from "@itwin/mobile-sdk-core"; import "./TabBar.scss"; From 852d7dc42088836b10b53d8e7d4098fe71c04dd4 Mon Sep 17 00:00:00 2001 From: "Travis.Cobbs" <77415528+tcobbs-bentley@users.noreply.github.com> Date: Fri, 19 Jul 2024 11:41:08 -0700 Subject: [PATCH 3/3] Stop using SessionStateActionId.SetIModelConnection --- src/mobile-ui-react/MobileUi.tsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/mobile-ui-react/MobileUi.tsx b/src/mobile-ui-react/MobileUi.tsx index 1c07df3..c89a569 100644 --- a/src/mobile-ui-react/MobileUi.tsx +++ b/src/mobile-ui-react/MobileUi.tsx @@ -6,12 +6,12 @@ import * as React from "react"; import { BackendError, Localization } from "@itwin/core-common"; import { ColorTheme, - SessionStateActionId, SyncUiEventDispatcher, SyncUiEventId, SYSTEM_PREFERRED_COLOR_THEME, UiFramework, UiSyncEventArgs, + useActiveIModelConnection, } from "@itwin/appui-react"; import { EmphasizeElements, IModelApp, IModelConnection, ScreenViewport, SelectionSet, Tool, Viewport } from "@itwin/core-frontend"; import { BeEvent, BeUiEvent, BriefcaseStatus, Id64Set, Listener } from "@itwin/core-bentley"; @@ -582,11 +582,10 @@ export function useIsolatedCount(): number { * @param handler - The callback function. */ export function useIModel(handler: (iModel: IModelConnection | undefined) => void) { - useSyncUiEvent(React.useCallback(() => { - handler(UiFramework.getIModelConnection()); - // @todo AppUI deprecation - // eslint-disable-next-line deprecation/deprecation - }, [handler]), SessionStateActionId.SetIModelConnection); + const iModelConnection = useActiveIModelConnection(); + React.useMemo(() => { + handler(iModelConnection); + }, [iModelConnection, handler]); } /**