@totalpave/cordova-plugin-insets 0.4.0 → 0.4.2
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/README.md +4 -0
- package/docs.md +42 -0
- package/package.json +5 -5
- package/plugin.xml +6 -1
- package/plugin.xml.ejs +5 -0
- package/src/ios/TPIInset.m +20 -26
- package/src/ios/TPIInsetObserverController.h +37 -0
- package/src/ios/TPIInsetObserverController.m +57 -0
package/README.md
CHANGED
|
@@ -8,6 +8,10 @@ On iOS, in rare circumstances the CSS safe area inset variables may resolve to i
|
|
|
8
8
|
|
|
9
9
|
This plugin provides a work around to obtain these values in javascript. You will have to implement your own javascript code to actually start using these values in your CSS.
|
|
10
10
|
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
`cordova plugin add @totalpave/cordova-plugin-insets`
|
|
14
|
+
|
|
11
15
|
## Supported Platforms
|
|
12
16
|
|
|
13
17
|
- Android
|
package/docs.md
CHANGED
|
@@ -18,6 +18,7 @@ This document describes the public API available to library consumers.
|
|
|
18
18
|
- [3.3 - addListener](#33---addlistener)
|
|
19
19
|
- [3.4 - removeListener](#34---removelistener)
|
|
20
20
|
- [3.5 - getInset](#35---getinset)
|
|
21
|
+
- [4.0 - Sample Code](#40---sample-code)
|
|
21
22
|
|
|
22
23
|
## 1.0 - General Notes
|
|
23
24
|
The namespace of this plugin is `window.totalpave.Inset`. It will become available after the `deviceready` event. Throughout this document, I'll refer to the `totalpave.Inset` object as `Inset`.
|
|
@@ -168,3 +169,44 @@ Returns the last known [IInset](#21---iinset) object.
|
|
|
168
169
|
```typescript
|
|
169
170
|
getInset(): IInset;
|
|
170
171
|
```
|
|
172
|
+
|
|
173
|
+
## 4.0 - Sample Code
|
|
174
|
+
|
|
175
|
+
The plugin concerns itself with reporting safe area values. How the app consumes them is entirely up to the app. A very basic example that goes straight to the point would look something like this:
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
let insetProvider = await window.totalpave.Inset.create();
|
|
179
|
+
insetProvider.addListener((insets) => {
|
|
180
|
+
let bottomOffset = insets.bottom;
|
|
181
|
+
|
|
182
|
+
let myDiv = document.getElementById('myDiv').style.marginBottom = bottomOffset + 'px';
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
However, styling a lot of UI directly in the JS isn't very ideal, so a better method is to read the inset reports and set CSS variables which is then accessible from your CSS:
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
let insetProvider = await window.totalpave.Inset.create();
|
|
190
|
+
insetProvider.addListener((insets) => {
|
|
191
|
+
let r = document.querySelector(':root');
|
|
192
|
+
|
|
193
|
+
r.style.setProperty('--my-inset-top', `${insets.top}px`);
|
|
194
|
+
r.style.setProperty('--my-inset-bottom', `${insets.bottom}px`);
|
|
195
|
+
r.style.setProperty('--my-inset-left', `${insets.left}px`);
|
|
196
|
+
r.style.setProperty('--my-inset-right', `${insets.right}px`);
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
This sets variables that can be referenced from CSS:
|
|
201
|
+
|
|
202
|
+
```css
|
|
203
|
+
#myDiv {
|
|
204
|
+
margin-bottom: var(--my-inset-bottom, env(safe-area-inset-bottom));
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Of course you can use `var(--my-inset-bottom)` anywhere you see fit in CSS, inside padding directives, or top/left/right/botton directives, etc...
|
|
209
|
+
|
|
210
|
+
If `--my-inset-bottom` is not set, it falls back to the webview environment variable `env(safe-area-inset-bottom)`, useful if you're sharing web code between cordova and other web environments like a standard website.
|
|
211
|
+
|
|
212
|
+
If you use a CSS preprocessor like Less, Stylus or Sass. It may be smart to create a macro to abstract the usages of the custom variable. There may be a time where this plugin becomes completely unnecessary.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@totalpave/cordova-plugin-insets",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Cordova Android Plugin to receive native information regarding the unsafe area insets.",
|
|
5
5
|
"main": "www/insets.js",
|
|
6
6
|
"types": "www/api.d.ts",
|
|
@@ -26,16 +26,16 @@
|
|
|
26
26
|
},
|
|
27
27
|
"homepage": "https://github.com/totalpaveinc/cordova-plugin-insets#readme",
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@rollup/plugin-commonjs": "
|
|
29
|
+
"@rollup/plugin-commonjs": "29.0.0",
|
|
30
30
|
"@rollup/plugin-node-resolve": "16.0.1",
|
|
31
31
|
"@types/cordova": "11.0.3",
|
|
32
32
|
"@types/node": "24.3.1",
|
|
33
|
-
"ejs": "
|
|
34
|
-
"rollup": "4.
|
|
33
|
+
"ejs": "4.0.1",
|
|
34
|
+
"rollup": "4.57.1",
|
|
35
35
|
"rollup-plugin-progress": "1.1.2",
|
|
36
36
|
"rollup-plugin-typescript2": "0.36.0",
|
|
37
37
|
"ts-node": "10.9.2",
|
|
38
|
-
"typescript": "5.9.
|
|
38
|
+
"typescript": "5.9.3"
|
|
39
39
|
},
|
|
40
40
|
"engines": {
|
|
41
41
|
"cordovaDependencies": {
|
package/plugin.xml
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<plugin
|
|
3
3
|
xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
|
4
4
|
id="@totalpave/cordova-plugin-insets"
|
|
5
|
-
version="0.4.
|
|
5
|
+
version="0.4.2"
|
|
6
6
|
>
|
|
7
7
|
<name>cordova-plugin-insets</name>
|
|
8
8
|
<description>Cordova Android Plugin to receive native information regarding the unsafe area insets</description>
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
<config-file target="res/xml/config.xml" parent="/*">
|
|
20
20
|
<feature name="Inset">
|
|
21
21
|
<param name="android-package" value="com.totalpave.cordova.inset.Inset" />
|
|
22
|
+
<param name="onload" value="true" />
|
|
22
23
|
</feature>
|
|
23
24
|
</config-file>
|
|
24
25
|
<source-file src="src/android/com/totalpave/cordova/inset/Inset.java" target-dir="src/com/totalpave/cordova/inset" />
|
|
@@ -28,6 +29,7 @@
|
|
|
28
29
|
<config-file target="config.xml" parent="/*">
|
|
29
30
|
<feature name="Inset">
|
|
30
31
|
<param name="ios-package" value="TPIInset" />
|
|
32
|
+
<param name="onload" value="true" />
|
|
31
33
|
</feature>
|
|
32
34
|
</config-file>
|
|
33
35
|
|
|
@@ -36,5 +38,8 @@
|
|
|
36
38
|
|
|
37
39
|
<header-file src="src/ios/TPIInsetObserver.h" target-dir="totalpave/insets" />
|
|
38
40
|
<source-file src="src/ios/TPIInsetObserver.m" target-dir="totalpave/insets" />
|
|
41
|
+
|
|
42
|
+
<header-file src="src/ios/TPIInsetObserverController.h" target-dir="totalpave/insets" />
|
|
43
|
+
<source-file src="src/ios/TPIInsetObserverController.m" target-dir="totalpave/insets" />
|
|
39
44
|
</platform>
|
|
40
45
|
</plugin>
|
package/plugin.xml.ejs
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
<config-file target="res/xml/config.xml" parent="/*">
|
|
20
20
|
<feature name="Inset">
|
|
21
21
|
<param name="android-package" value="com.totalpave.cordova.inset.Inset" />
|
|
22
|
+
<param name="onload" value="true" />
|
|
22
23
|
</feature>
|
|
23
24
|
</config-file>
|
|
24
25
|
<source-file src="src/android/com/totalpave/cordova/inset/Inset.java" target-dir="src/com/totalpave/cordova/inset" />
|
|
@@ -28,6 +29,7 @@
|
|
|
28
29
|
<config-file target="config.xml" parent="/*">
|
|
29
30
|
<feature name="Inset">
|
|
30
31
|
<param name="ios-package" value="TPIInset" />
|
|
32
|
+
<param name="onload" value="true" />
|
|
31
33
|
</feature>
|
|
32
34
|
</config-file>
|
|
33
35
|
|
|
@@ -36,5 +38,8 @@
|
|
|
36
38
|
|
|
37
39
|
<header-file src="src/ios/TPIInsetObserver.h" target-dir="totalpave/insets" />
|
|
38
40
|
<source-file src="src/ios/TPIInsetObserver.m" target-dir="totalpave/insets" />
|
|
41
|
+
|
|
42
|
+
<header-file src="src/ios/TPIInsetObserverController.h" target-dir="totalpave/insets" />
|
|
43
|
+
<source-file src="src/ios/TPIInsetObserverController.m" target-dir="totalpave/insets" />
|
|
39
44
|
</platform>
|
|
40
45
|
</plugin>
|
package/src/ios/TPIInset.m
CHANGED
|
@@ -16,24 +16,19 @@
|
|
|
16
16
|
|
|
17
17
|
#import <Foundation/Foundation.h>
|
|
18
18
|
#import "TPIInset.h"
|
|
19
|
-
#import "
|
|
19
|
+
#import "TPIInsetObserverController.h"
|
|
20
20
|
#import <UIKit/UIKit.h>
|
|
21
21
|
|
|
22
22
|
@implementation TPIInset {
|
|
23
23
|
NSMutableDictionary* $listeners;
|
|
24
|
-
|
|
24
|
+
TPIInsetObserverController* $observer;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
- (void) pluginInitialize {
|
|
28
|
-
self->$listeners = [[NSMutableDictionary alloc] init];
|
|
29
|
-
self->$observer = [[TPIInsetObserver alloc] init];
|
|
30
|
-
self->$observer.frame = self.viewController.view.frame;
|
|
31
|
-
self->$observer.userInteractionEnabled = false;
|
|
32
|
-
self->$observer.translatesAutoresizingMaskIntoConstraints = false;
|
|
33
|
-
|
|
34
28
|
__weak TPIInset* weakSelf = self;
|
|
35
29
|
|
|
36
|
-
self->$
|
|
30
|
+
self->$listeners = [[NSMutableDictionary alloc] init];
|
|
31
|
+
self->$observer = [[TPIInsetObserverController alloc] initWithSAICallback:^(UIEdgeInsets insets) {
|
|
37
32
|
TPIInset* strongSelf = weakSelf;
|
|
38
33
|
|
|
39
34
|
if (strongSelf == nil) {
|
|
@@ -46,24 +41,28 @@
|
|
|
46
41
|
[strongSelf emitInsetChange: value inset: insets];
|
|
47
42
|
}
|
|
48
43
|
}
|
|
49
|
-
};
|
|
44
|
+
}];
|
|
50
45
|
|
|
51
|
-
[self.viewController
|
|
46
|
+
[self.viewController addChildViewController: self->$observer];
|
|
47
|
+
|
|
48
|
+
[self.viewController.view addSubview: self->$observer.view];
|
|
52
49
|
|
|
53
50
|
[NSLayoutConstraint activateConstraints:@[
|
|
54
|
-
[self->$observer.topAnchor constraintEqualToAnchor:self.viewController.view.topAnchor],
|
|
55
|
-
[self->$observer.bottomAnchor constraintEqualToAnchor:self.viewController.view.bottomAnchor],
|
|
56
|
-
[self->$observer.leadingAnchor constraintEqualToAnchor:self.viewController.view.leadingAnchor],
|
|
57
|
-
[self->$observer.trailingAnchor constraintEqualToAnchor:self.viewController.view.trailingAnchor],
|
|
51
|
+
[self->$observer.view.topAnchor constraintEqualToAnchor:self.viewController.view.topAnchor],
|
|
52
|
+
[self->$observer.view.bottomAnchor constraintEqualToAnchor:self.viewController.view.bottomAnchor],
|
|
53
|
+
[self->$observer.view.leadingAnchor constraintEqualToAnchor:self.viewController.view.leadingAnchor],
|
|
54
|
+
[self->$observer.view.trailingAnchor constraintEqualToAnchor:self.viewController.view.trailingAnchor],
|
|
58
55
|
]];
|
|
56
|
+
|
|
57
|
+
[self->$observer didMoveToParentViewController: self.viewController];
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
- (void) emitInsetChange:(NSDictionary*) listener inset:(UIEdgeInsets) inset {
|
|
62
61
|
NSString* callbackID = [listener objectForKey: @"callbackID"];
|
|
63
|
-
|
|
64
62
|
if (callbackID == nil) return;
|
|
65
63
|
|
|
66
64
|
NSString* ident = [listener objectForKey:@"id"];
|
|
65
|
+
|
|
67
66
|
if (ident == nil) return;
|
|
68
67
|
|
|
69
68
|
NSDictionary* payload = @{
|
|
@@ -82,14 +81,6 @@
|
|
|
82
81
|
[self.commandDelegate sendPluginResult: result callbackId: callbackID];
|
|
83
82
|
}
|
|
84
83
|
|
|
85
|
-
- (UIEdgeInsets) $getViewInsets {
|
|
86
|
-
if (self.viewController.viewIfLoaded == nil) {
|
|
87
|
-
return UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return self.viewController.view.safeAreaInsets;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
84
|
- (void) create:(CDVInvokedUrlCommand*) command {
|
|
94
85
|
NSString* ident = [[NSUUID UUID] UUIDString];
|
|
95
86
|
|
|
@@ -110,7 +101,7 @@
|
|
|
110
101
|
|
|
111
102
|
[self.commandDelegate sendPluginResult: result callbackId: command.callbackId];
|
|
112
103
|
|
|
113
|
-
[self emitInsetChange: listener inset: self->$observer.safeAreaInsets];
|
|
104
|
+
[self emitInsetChange: listener inset: self->$observer.view.safeAreaInsets];
|
|
114
105
|
}
|
|
115
106
|
|
|
116
107
|
- (void) delete:(CDVInvokedUrlCommand*) command {
|
|
@@ -125,8 +116,11 @@
|
|
|
125
116
|
}
|
|
126
117
|
|
|
127
118
|
- (void) dealloc {
|
|
128
|
-
[self->$observer
|
|
119
|
+
[self->$observer willMoveToParentViewController: nil];
|
|
120
|
+
[self->$observer.view removeFromSuperview];
|
|
121
|
+
[self->$observer removeFromParentViewController];
|
|
129
122
|
self->$observer.safeAreaChanged = nil;
|
|
123
|
+
self->$observer = nil;
|
|
130
124
|
}
|
|
131
125
|
|
|
132
126
|
@end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2026 Total Pave Inc.
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#ifndef TPIInsetObserverController_h
|
|
18
|
+
#define TPIInsetObserverController_h
|
|
19
|
+
|
|
20
|
+
#import <Foundation/Foundation.h>
|
|
21
|
+
#import <UIKit/UIKit.h>
|
|
22
|
+
|
|
23
|
+
typedef void (^TPIInsetSAICallback)(UIEdgeInsets insets);
|
|
24
|
+
|
|
25
|
+
@interface TPIInsetObserverController: UIViewController
|
|
26
|
+
|
|
27
|
+
@property (nonatomic, copy) TPIInsetSAICallback safeAreaChanged;
|
|
28
|
+
|
|
29
|
+
- (instancetype) init NS_UNAVAILABLE;
|
|
30
|
+
- (instancetype) initWithNibName:(NSString*) nib bundle:(NSBundle*) bundle NS_UNAVAILABLE;
|
|
31
|
+
- (instancetype) initWithCoder:(NSCoder*) code NS_UNAVAILABLE;
|
|
32
|
+
|
|
33
|
+
- (instancetype) initWithSAICallback:(TPIInsetSAICallback) callback NS_DESIGNATED_INITIALIZER;
|
|
34
|
+
|
|
35
|
+
@end
|
|
36
|
+
|
|
37
|
+
#endif
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2026 Total Pave Inc.
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#import <Foundation/Foundation.h>
|
|
18
|
+
#import "TPIInsetObserverController.h"
|
|
19
|
+
#import "TPIInsetObserver.h"
|
|
20
|
+
|
|
21
|
+
@implementation TPIInsetObserverController : UIViewController
|
|
22
|
+
|
|
23
|
+
- (instancetype) initWithSAICallback:(TPIInsetSAICallback) callback {
|
|
24
|
+
self = [super initWithNibName: nil bundle: nil];
|
|
25
|
+
|
|
26
|
+
self.safeAreaChanged = callback;
|
|
27
|
+
|
|
28
|
+
return self;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
- (void) loadView {
|
|
32
|
+
TPIInsetObserver* view = [[TPIInsetObserver alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
|
33
|
+
view.safeAreaChanged = self.safeAreaChanged;
|
|
34
|
+
view.userInteractionEnabled = false;
|
|
35
|
+
view.translatesAutoresizingMaskIntoConstraints = false;
|
|
36
|
+
self.view = view;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
- (void) viewDidLoad {
|
|
40
|
+
[super viewDidLoad];
|
|
41
|
+
UIView* parent = self.view.superview;
|
|
42
|
+
if (!parent) return;
|
|
43
|
+
|
|
44
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
45
|
+
[self.view.topAnchor constraintEqualToAnchor:parent.topAnchor],
|
|
46
|
+
[self.view.bottomAnchor constraintEqualToAnchor:parent.bottomAnchor],
|
|
47
|
+
[self.view.leadingAnchor constraintEqualToAnchor:parent.leadingAnchor],
|
|
48
|
+
[self.view.trailingAnchor constraintEqualToAnchor:parent.trailingAnchor],
|
|
49
|
+
]];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
- (void) dealloc {
|
|
53
|
+
self.safeAreaChanged = nil;
|
|
54
|
+
self.view = nil;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@end
|