Files
Sean Perkins 16c77ccdc8 refactor: use capacitor types for native plugins (#27755)
Issue number: Internal

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

Ionic currently detects and uses Capacitor APIs for different plugins
(haptics, status bar and keyboard). This implementation does not have
type safety and can result in unexpected behaviors.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- Adds `@capacitor/core`, `@capacitor/keyboard`, `@capacitor/haptics`
and `@capacitor/status-bar` as dev dependencies. These should _only_ be
used with `import type { }`.
- Refactors the plugin usages to be typed against the plugin packages,
while using a duplicate enum when needing a value. This allows us to not
bundle the capacitor plugins with Ionic Framework.
- Introduces a `getCapacitor()` function for interacting with the
`window.Capacitor` object through a typed object.

**How does it work?**

The idea is we want the type safety from the Capacitor packages, without
directly bundling that source code within Ionic Framework. This means we
use the Capacitor deps where a type is needed, but clone any enums where
a value is referenced. If a Capacitor dep changes the supported values,
Typescript will fail to compile and that will signal to use to update
our enum values to match any changes.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

Dev-build: `7.1.2-dev.11688696027.1c4d4ad1`

Tested against a demo app for some of the core behavior:
https://github.com/sean-perkins/capacitor-ionic-plugins-demo
2023-07-14 15:27:28 +00:00

93 lines
2.6 KiB
TypeScript

import { win } from '@utils/browser';
import { StatusBar, Style } from '@utils/native/status-bar';
/**
* Use y = mx + b to
* figure out the backdrop value
* at a particular x coordinate. This
* is useful when the backdrop does
* not begin to fade in until after
* the 0 breakpoint.
*/
export const getBackdropValueForSheet = (x: number, backdropBreakpoint: number) => {
/**
* We will use these points:
* (backdropBreakpoint, 0)
* (maxBreakpoint, 1)
* We know that at the beginning breakpoint,
* the backdrop will be hidden. We also
* know that at the maxBreakpoint, the backdrop
* must be fully visible. maxBreakpoint should
* always be 1 even if the maximum value
* of the breakpoints array is not 1 since
* the animation runs from a progress of 0
* to a progress of 1.
* m = (y2 - y1) / (x2 - x1)
*
* This is simplified from:
* m = (1 - 0) / (maxBreakpoint - backdropBreakpoint)
*
* If the backdropBreakpoint is 1, we return 0 as the
* backdrop is completely hidden.
*
*/
if (backdropBreakpoint === 1) {
return 0;
}
const slope = 1 / (1 - backdropBreakpoint);
/**
* From here, compute b which is
* the backdrop opacity if the offset
* is 0. If the backdrop does not
* begin to fade in until after the
* 0 breakpoint, this b value will be
* negative. This is fine as we never pass
* b directly into the animation keyframes.
* b = y - mx
* Use a known point: (backdropBreakpoint, 0)
* This is simplified from:
* b = 0 - (backdropBreakpoint * slope)
*/
const b = -(backdropBreakpoint * slope);
/**
* Finally, we can now determine the
* backdrop offset given an arbitrary
* gesture offset.
*/
return x * slope + b;
};
/**
* The tablet/desktop card modal activates
* when the window width is >= 768.
* At that point, the presenting element
* is not transformed, so we do not need to
* adjust the status bar color.
*
* Note: We check supportsDefaultStatusBarStyle so that
* Capacitor <= 2 users do not get their status bar
* stuck in an inconsistent state due to a lack of
* support for Style.Default.
*/
export const setCardStatusBarDark = () => {
// TODO FW-4696 Remove supportDefaultStatusBarStyle in Ionic v8
if (!win || win.innerWidth >= 768 || !StatusBar.supportsDefaultStatusBarStyle()) {
return;
}
StatusBar.setStyle({ style: Style.Dark });
};
export const setCardStatusBarDefault = (defaultStyle = Style.Default) => {
// TODO FW-4696 Remove supportDefaultStatusBarStyle in Ionic v8
if (!win || win.innerWidth >= 768 || !StatusBar.supportsDefaultStatusBarStyle()) {
return;
}
StatusBar.setStyle({ style: defaultStyle });
};