mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-09 08:09:32 +08:00
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
61 lines
1.6 KiB
TypeScript
61 lines
1.6 KiB
TypeScript
import type { CapacitorException } from '@capacitor/core';
|
|
import type { KeyboardPlugin, KeyboardResizeOptions } from '@capacitor/keyboard';
|
|
|
|
import { getCapacitor } from './capacitor';
|
|
import { ExceptionCode } from './native-interface';
|
|
|
|
export enum KeyboardResize {
|
|
/**
|
|
* Only the `body` HTML element will be resized.
|
|
* Relative units are not affected, because the viewport does not change.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
Body = 'body',
|
|
/**
|
|
* Only the `ion-app` HTML element will be resized.
|
|
* Use it only for Ionic Framework apps.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
Ionic = 'ionic',
|
|
/**
|
|
* The whole native Web View will be resized when the keyboard shows/hides.
|
|
* This affects the `vh` relative unit.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
Native = 'native',
|
|
/**
|
|
* Neither the app nor the Web View are resized.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
None = 'none',
|
|
}
|
|
|
|
export const Keyboard = {
|
|
getEngine(): KeyboardPlugin | undefined {
|
|
const capacitor = getCapacitor();
|
|
|
|
if (capacitor?.isPluginAvailable('Keyboard')) {
|
|
return capacitor.Plugins.Keyboard as KeyboardPlugin;
|
|
}
|
|
return undefined;
|
|
},
|
|
getResizeMode(): Promise<KeyboardResizeOptions | undefined> {
|
|
const engine = this.getEngine();
|
|
if (!engine?.getResizeMode) {
|
|
return Promise.resolve(undefined);
|
|
}
|
|
return engine.getResizeMode().catch((e: CapacitorException) => {
|
|
if (e.code === ExceptionCode.Unimplemented) {
|
|
// If the native implementation is not available
|
|
// we treat it the same as if the plugin is not available.
|
|
return undefined;
|
|
}
|
|
throw e;
|
|
});
|
|
},
|
|
};
|