@excom/provider-orientation 0.1.0
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/.rush/temp/chunked-rush-logs/provider-orientation.apply-exports.chunks.jsonl +1 -0
- package/.rush/temp/chunked-rush-logs/provider-orientation.build_docs.chunks.jsonl +1 -0
- package/.rush/temp/chunked-rush-logs/provider-orientation.build_package-metas.chunks.jsonl +1 -0
- package/.rush/temp/operation/apply-exports/all.log +1 -0
- package/.rush/temp/operation/apply-exports/log-chunks.jsonl +1 -0
- package/.rush/temp/operation/apply-exports/state.json +3 -0
- package/.rush/temp/operation/build_docs/all.log +1 -0
- package/.rush/temp/operation/build_docs/log-chunks.jsonl +1 -0
- package/.rush/temp/operation/build_docs/state.json +3 -0
- package/.rush/temp/operation/build_package-metas/all.log +1 -0
- package/.rush/temp/operation/build_package-metas/log-chunks.jsonl +1 -0
- package/.rush/temp/operation/build_package-metas/state.json +3 -0
- package/.rush/temp/shrinkwrap-deps.json +3 -0
- package/config/rig.json +5 -0
- package/index.ts +18 -0
- package/package.json +42 -0
- package/provider-orientation.ts +225 -0
- package/rush-logs/provider-orientation.apply-exports.cache.log +1 -0
- package/rush-logs/provider-orientation.apply-exports.log +1 -0
- package/rush-logs/provider-orientation.build_docs.cache.log +1 -0
- package/rush-logs/provider-orientation.build_docs.log +1 -0
- package/rush-logs/provider-orientation.build_package-metas.cache.log +1 -0
- package/rush-logs/provider-orientation.build_package-metas.log +1 -0
- package/support/custom-elements.json +208 -0
- package/support/demos/request.html +14 -0
- package/support/dist-docs/provider-orientation.md +126 -0
- package/support/docs/README.md +52 -0
- package/support/package-meta.json +127 -0
- package/support/tests/provider-orientation.test.ts +624 -0
- package/support/tests/request.view.test.ts +39 -0
- package/tsconfig.json +5 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"kind":"O","text":"Invoking: cd \"$RUSH_PROJECT_FOLDER\" && node ../heft-rig/scripts/apply-exports.mjs \n"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs \n"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs \n"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Invoking: cd "$RUSH_PROJECT_FOLDER" && node ../heft-rig/scripts/apply-exports.mjs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"kind":"O","text":"Invoking: cd \"$RUSH_PROJECT_FOLDER\" && node ../heft-rig/scripts/apply-exports.mjs \n"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs \n"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs \n"}
|
package/config/rig.json
ADDED
package/index.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ProviderOrientation } from "./provider-orientation";
|
|
2
|
+
|
|
3
|
+
ProviderOrientation.define();
|
|
4
|
+
|
|
5
|
+
export { ProviderOrientation };
|
|
6
|
+
|
|
7
|
+
type T_HTMLProviderOrientationElement =
|
|
8
|
+
typeof ProviderOrientation.CustomElement;
|
|
9
|
+
declare global {
|
|
10
|
+
interface HTMLProviderOrientationElement extends T_HTMLProviderOrientationElement {}
|
|
11
|
+
interface Window {
|
|
12
|
+
HTMLProviderOrientationElement: HTMLProviderOrientationElement;
|
|
13
|
+
}
|
|
14
|
+
interface HTMLElementTagNameMap {
|
|
15
|
+
"provider-orientation": HTMLProviderOrientationElement;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export type { HTMLProviderOrientationElement };
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@excom/provider-orientation",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "<provider-orientation> custom element",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=24.13.0"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@excom/neutron": "^0.1.0"
|
|
12
|
+
},
|
|
13
|
+
"peerDependencies": {},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@excom/heft-rig": "^0.1.0"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"url": "excom-dev/nucleus",
|
|
19
|
+
"directory": "packages/provider-orientation"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://github.com/excom-dev/nucleus/tree/main/packages/provider-orientation/support/docs/README.md",
|
|
22
|
+
"bugs": "https://github.com/excom-dev/nucleus/issues",
|
|
23
|
+
"keywords": [
|
|
24
|
+
"provider-orientation",
|
|
25
|
+
"neutron",
|
|
26
|
+
"custom-elements"
|
|
27
|
+
],
|
|
28
|
+
"excom": {
|
|
29
|
+
"packageType": "kit-element"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "node node_modules/@excom/heft-rig/scripts/vite-build.mjs",
|
|
33
|
+
"build:watch": "node node_modules/@excom/heft-rig/scripts/vite-build-watch.mjs",
|
|
34
|
+
"format": "node node_modules/@excom/heft-rig/scripts/format.mjs",
|
|
35
|
+
"test": "node node_modules/@excom/heft-rig/scripts/vitest.mjs",
|
|
36
|
+
"coverage": "node node_modules/@excom/heft-rig/scripts/coverage.mjs",
|
|
37
|
+
"dev": "node node_modules/@excom/heft-rig/scripts/vite-dev.mjs",
|
|
38
|
+
"preview": "node node_modules/@excom/heft-rig/scripts/vite-preview.mjs",
|
|
39
|
+
"build:package-metas": "node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs",
|
|
40
|
+
"build:docs": "node node_modules/@excom/heft-rig/scripts/build-docs.mjs"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { ConstructorType, Neutron, TEvent } from "@excom/neutron";
|
|
2
|
+
|
|
3
|
+
export type ProviderOrientationSuccess = {
|
|
4
|
+
bearing: number;
|
|
5
|
+
alpha: number | null;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type ProviderOrientationError = string | Error;
|
|
9
|
+
|
|
10
|
+
export type ProviderOrientationSuccessEvent = TEvent & {
|
|
11
|
+
type: "provider-orientation-success";
|
|
12
|
+
detail: ProviderOrientationSuccess;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type ProviderOrientationErrorEvent = TEvent & {
|
|
16
|
+
type: "provider-orientation-error";
|
|
17
|
+
detail: ProviderOrientationError;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Wraps the device orientation / compass APIs — request a heading and
|
|
22
|
+
* read updates from attributes/state, no app JS required. Requests on
|
|
23
|
+
* connect unless `is-paused`, same as the other `provider-*` elements —
|
|
24
|
+
* but on iOS that request must happen synchronously inside a user
|
|
25
|
+
* gesture (`DeviceOrientationEvent.requestPermission()`), so a
|
|
26
|
+
* connect-time request will silently fail there. **Set `is-paused` and
|
|
27
|
+
* invoke the `--request` command from a button instead** unless you know
|
|
28
|
+
* your app only targets Android/desktop (the handler runs in a microtask
|
|
29
|
+
* of the click, inside its user activation).
|
|
30
|
+
*
|
|
31
|
+
* Bearing (`provision.bearing`) is normalized to degrees clockwise from
|
|
32
|
+
* magnetic north (`0`–`360`) across both the iOS
|
|
33
|
+
* (`webkitCompassHeading`) and Android/absolute (`alpha`) code paths, so
|
|
34
|
+
* consumers don't need to branch on platform.
|
|
35
|
+
*
|
|
36
|
+
* Lifecycle: the `window` listener is tracked by Neutron — removed when
|
|
37
|
+
* the element leaves the document, restored (and the request repeated
|
|
38
|
+
* unless `is-paused`) when it is reconnected, and kept across a DOM move.
|
|
39
|
+
* Removing the element while an iOS permission prompt is still open
|
|
40
|
+
* abandons that request: nothing is attached when it settles, and a
|
|
41
|
+
* later reconnect requests again.
|
|
42
|
+
*
|
|
43
|
+
* @fires provider-orientation-success - Dispatched on every compass
|
|
44
|
+
* update (throttled by `compass-throttle-ms`). `bearing` is
|
|
45
|
+
* normalized 0-360°; `alpha` is the raw
|
|
46
|
+
* `DeviceOrientationEvent.alpha` where available.
|
|
47
|
+
* @type ProviderOrientationSuccessEvent
|
|
48
|
+
* @fires provider-orientation-error - Dispatched when the permission
|
|
49
|
+
* request is denied, or fails for any other reason.
|
|
50
|
+
* @type ProviderOrientationErrorEvent
|
|
51
|
+
* @command --request - Requests permission (iOS) and starts listening for
|
|
52
|
+
* orientation updates. Invoke it from a button (`<button
|
|
53
|
+
* command="--request" commandfor="…">`) so the user activation is there.
|
|
54
|
+
* @default-action provider-orientation-success - Stores `{ bearing,
|
|
55
|
+
* alpha }` in `provision` and sets `is-success` (clearing `is-requesting` /
|
|
56
|
+
* `is-error`).
|
|
57
|
+
* @default-action provider-orientation-error - Stores the error in
|
|
58
|
+
* `provision` and sets `is-error` (clearing `is-requesting` /
|
|
59
|
+
* `is-success`).
|
|
60
|
+
*/
|
|
61
|
+
export const ProviderOrientation = Neutron({
|
|
62
|
+
tag: "provider-orientation",
|
|
63
|
+
props: {
|
|
64
|
+
// options
|
|
65
|
+
/**
|
|
66
|
+
* @option
|
|
67
|
+
* Skip requesting on connect. On iOS this is effectively required
|
|
68
|
+
* (a connect-time request happens outside a user gesture and will
|
|
69
|
+
* be denied) — pair with `provider-orientation-request` from a
|
|
70
|
+
* click handler instead (see class docs).
|
|
71
|
+
*/
|
|
72
|
+
isPaused: Boolean,
|
|
73
|
+
/**
|
|
74
|
+
* @option
|
|
75
|
+
* Minimum ms between `provider-orientation-success` updates.
|
|
76
|
+
* Android can fire `deviceorientationabsolute` at 60-200 Hz;
|
|
77
|
+
* without throttling that floods listeners and CSS/Quark bindings.
|
|
78
|
+
* @default 100
|
|
79
|
+
*/
|
|
80
|
+
compassThrottleMs: {
|
|
81
|
+
type: Number,
|
|
82
|
+
defaultValue: () => 100,
|
|
83
|
+
},
|
|
84
|
+
// state
|
|
85
|
+
/**
|
|
86
|
+
* @state
|
|
87
|
+
* iOS only: the permission request is pending (between
|
|
88
|
+
* `provider-orientation-request` and the user's response).
|
|
89
|
+
*/
|
|
90
|
+
isRequesting: Boolean,
|
|
91
|
+
/**
|
|
92
|
+
* @state
|
|
93
|
+
* Listening for orientation updates (permission granted where
|
|
94
|
+
* required). Stays set across updates.
|
|
95
|
+
*/
|
|
96
|
+
isSuccess: Boolean,
|
|
97
|
+
/**
|
|
98
|
+
* @state
|
|
99
|
+
* The permission request was denied, or listening failed to start.
|
|
100
|
+
*/
|
|
101
|
+
isError: Boolean,
|
|
102
|
+
/**
|
|
103
|
+
* @provision
|
|
104
|
+
* Latest reading: `{ bearing, alpha }` on success, or the error on
|
|
105
|
+
* failure. Not reflected as an attribute.
|
|
106
|
+
* @type ProviderOrientationSuccess
|
|
107
|
+
*/
|
|
108
|
+
provision: Object as unknown as ConstructorType<any>,
|
|
109
|
+
// private
|
|
110
|
+
permissionPromise: Promise as unknown as ConstructorType<
|
|
111
|
+
Promise<PermissionStatus>
|
|
112
|
+
>,
|
|
113
|
+
lastCompassUpdate: {
|
|
114
|
+
type: Number,
|
|
115
|
+
defaultValue: () => 0,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
})
|
|
119
|
+
.defineMethods({
|
|
120
|
+
handleSuccess: (_, { bearing, alpha }) => ({
|
|
121
|
+
// Emit success event for continuous updates
|
|
122
|
+
emit: ["provider-orientation-success", { detail: { bearing, alpha } }],
|
|
123
|
+
}),
|
|
124
|
+
handleError: (_, error) => ({
|
|
125
|
+
emit: ["provider-orientation-error", { detail: error }],
|
|
126
|
+
}),
|
|
127
|
+
makeRequest: () => {
|
|
128
|
+
const DOE =
|
|
129
|
+
typeof DeviceOrientationEvent !== "undefined"
|
|
130
|
+
? (DeviceOrientationEvent as any)
|
|
131
|
+
: null;
|
|
132
|
+
if (DOE && typeof DOE.requestPermission === "function") {
|
|
133
|
+
// iOS: request permission (async) from a user-gesture context
|
|
134
|
+
return {
|
|
135
|
+
permissionPromise: DOE.requestPermission(),
|
|
136
|
+
isRequesting: true,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/* Android / desktop: no permission here. Attach synchronously so it
|
|
140
|
+
stays in the user-gesture context; some Android browser / PWA
|
|
141
|
+
combos silently block `deviceorientation` outside a gesture. */
|
|
142
|
+
return {
|
|
143
|
+
_attachCompassListener: [],
|
|
144
|
+
isRequesting: false,
|
|
145
|
+
isSuccess: true,
|
|
146
|
+
isError: false,
|
|
147
|
+
};
|
|
148
|
+
},
|
|
149
|
+
/**
|
|
150
|
+
* Register the `window` orientation listener once, via Neutron's
|
|
151
|
+
* tracked registry (`target: window`). Dropped on disconnect,
|
|
152
|
+
* restored on reconnect, never added twice.
|
|
153
|
+
*/
|
|
154
|
+
// @ts-ignore TODO fix defineMethods sibling references
|
|
155
|
+
_attachCompassListener: ({ compassHandler }) => ({
|
|
156
|
+
addListener: [
|
|
157
|
+
"ondeviceorientationabsolute" in window
|
|
158
|
+
? "deviceorientationabsolute"
|
|
159
|
+
: "deviceorientation",
|
|
160
|
+
compassHandler,
|
|
161
|
+
{ capture: true, target: window },
|
|
162
|
+
],
|
|
163
|
+
}),
|
|
164
|
+
compassHandler: ({ compassThrottleMs, lastCompassUpdate }, e: any) => {
|
|
165
|
+
// Throttle: Android fires `deviceorientationabsolute` at 60-200 Hz
|
|
166
|
+
const now = Date.now();
|
|
167
|
+
if (now - lastCompassUpdate < compassThrottleMs) return;
|
|
168
|
+
|
|
169
|
+
let bearing: number | null = null;
|
|
170
|
+
|
|
171
|
+
// iOS: `webkitCompassHeading` (degrees from magnetic north, 0-360)
|
|
172
|
+
if (typeof e.webkitCompassHeading === "number") {
|
|
173
|
+
bearing = e.webkitCompassHeading;
|
|
174
|
+
} else if (typeof e.alpha === "number" && e.absolute) {
|
|
175
|
+
// Android / absolute: `alpha` is degrees from north
|
|
176
|
+
bearing = (360 - e.alpha) % 360;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (bearing !== null) {
|
|
180
|
+
return {
|
|
181
|
+
lastCompassUpdate: now,
|
|
182
|
+
handleSuccess: [{ bearing, alpha: e.alpha ?? undefined }],
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
})
|
|
187
|
+
.onConnected(
|
|
188
|
+
// A DOM move keeps the listener (Neutron restores it). Only a fresh
|
|
189
|
+
// connect or a real reconnect requests again.
|
|
190
|
+
({ isPaused, isMoving }) =>
|
|
191
|
+
!isPaused &&
|
|
192
|
+
!isMoving && {
|
|
193
|
+
makeRequest: [],
|
|
194
|
+
}
|
|
195
|
+
)
|
|
196
|
+
.onPropUnset("isPaused", () => ({
|
|
197
|
+
makeRequest: [],
|
|
198
|
+
}))
|
|
199
|
+
.onPromiseResolved("permissionPromise", (element, result) => {
|
|
200
|
+
/* Removed while the permission prompt was open: no disconnect will
|
|
201
|
+
clean up, so attach nothing. A later reconnect requests again via
|
|
202
|
+
`onConnected`. */
|
|
203
|
+
if (!element.isConnected) return;
|
|
204
|
+
// @ts-ignore TODO fix onPromiseResolved types
|
|
205
|
+
if (result?.permissionPromise === "granted") {
|
|
206
|
+
return { _attachCompassListener: [] };
|
|
207
|
+
}
|
|
208
|
+
return { handleError: ["Device orientation permission denied"] };
|
|
209
|
+
})
|
|
210
|
+
.onPromiseRejected("permissionPromise", (_, err) => ({
|
|
211
|
+
handleError: [err],
|
|
212
|
+
}))
|
|
213
|
+
.onCommand("--request", () => ({ makeRequest: [] }))
|
|
214
|
+
.onEventDefault("provider-orientation-success", (_, { detail }) => ({
|
|
215
|
+
provision: detail,
|
|
216
|
+
isRequesting: false,
|
|
217
|
+
isSuccess: true,
|
|
218
|
+
isError: false,
|
|
219
|
+
}))
|
|
220
|
+
.onEventDefault("provider-orientation-error", (_, { detail }) => ({
|
|
221
|
+
provision: detail,
|
|
222
|
+
isRequesting: false,
|
|
223
|
+
isSuccess: false,
|
|
224
|
+
isError: true,
|
|
225
|
+
}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Caching has been disabled for this project's "apply-exports" command.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Invoking: cd "$RUSH_PROJECT_FOLDER" && node ../heft-rig/scripts/apply-exports.mjs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
This project does not define the caching behavior of the "build:docs" command, so caching has been disabled.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
This project does not define the caching behavior of the "build:package-metas" command, so caching has been disabled.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "1.0.0",
|
|
3
|
+
"modules": [
|
|
4
|
+
{
|
|
5
|
+
"kind": "javascript-module",
|
|
6
|
+
"path": "provider-orientation.ts",
|
|
7
|
+
"declarations": [
|
|
8
|
+
{
|
|
9
|
+
"kind": "class",
|
|
10
|
+
"name": "ProviderOrientation",
|
|
11
|
+
"customElement": true,
|
|
12
|
+
"tagName": "provider-orientation",
|
|
13
|
+
"description": "Wraps the device orientation / compass APIs — request a heading and read updates from attributes/state, no app JS required. Requests on connect unless `is-paused`, same as the other `provider-*` elements — but on iOS that request must happen synchronously inside a user gesture (`DeviceOrientationEvent.requestPermission()`), so a connect-time request will silently fail there. **Set `is-paused` and invoke the `--request` command from a button instead** unless you know your app only targets Android/desktop (the handler runs in a microtask of the click, inside its user activation). Bearing (`provision.bearing`) is normalized to degrees clockwise from magnetic north (`0`–`360`) across both the iOS (`webkitCompassHeading`) and Android/absolute (`alpha`) code paths, so consumers don't need to branch on platform. Lifecycle: the `window` listener is tracked by Neutron — removed when the element leaves the document, restored (and the request repeated unless `is-paused`) when it is reconnected, and kept across a DOM move. Removing the element while an iOS permission prompt is still open abandons that request: nothing is attached when it settles, and a later reconnect requests again.",
|
|
14
|
+
"attributes": [
|
|
15
|
+
{
|
|
16
|
+
"name": "is-paused",
|
|
17
|
+
"type": {
|
|
18
|
+
"text": "boolean"
|
|
19
|
+
},
|
|
20
|
+
"description": "Skip requesting on connect. On iOS this is effectively required (a connect-time request happens outside a user gesture and will be denied) — pair with `provider-orientation-request` from a click handler instead (see class docs).",
|
|
21
|
+
"fieldName": "isPaused"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "compass-throttle-ms",
|
|
25
|
+
"type": {
|
|
26
|
+
"text": "number"
|
|
27
|
+
},
|
|
28
|
+
"description": "Minimum ms between `provider-orientation-success` updates. Android can fire `deviceorientationabsolute` at 60-200 Hz; without throttling that floods listeners and CSS/Quark bindings.",
|
|
29
|
+
"fieldName": "compassThrottleMs",
|
|
30
|
+
"default": 100
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "is-requesting",
|
|
34
|
+
"type": {
|
|
35
|
+
"text": "boolean"
|
|
36
|
+
},
|
|
37
|
+
"description": "iOS only: the permission request is pending (between `provider-orientation-request` and the user's response).",
|
|
38
|
+
"fieldName": "isRequesting"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "is-success",
|
|
42
|
+
"type": {
|
|
43
|
+
"text": "boolean"
|
|
44
|
+
},
|
|
45
|
+
"description": "Listening for orientation updates (permission granted where required). Stays set across updates.",
|
|
46
|
+
"fieldName": "isSuccess"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "is-error",
|
|
50
|
+
"type": {
|
|
51
|
+
"text": "boolean"
|
|
52
|
+
},
|
|
53
|
+
"description": "The permission request was denied, or listening failed to start.",
|
|
54
|
+
"fieldName": "isError"
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"members": [
|
|
58
|
+
{
|
|
59
|
+
"kind": "field",
|
|
60
|
+
"name": "isPaused",
|
|
61
|
+
"type": {
|
|
62
|
+
"text": "boolean"
|
|
63
|
+
},
|
|
64
|
+
"privacy": "public",
|
|
65
|
+
"readonly": false,
|
|
66
|
+
"description": "Skip requesting on connect. On iOS this is effectively required (a connect-time request happens outside a user gesture and will be denied) — pair with `provider-orientation-request` from a click handler instead (see class docs).",
|
|
67
|
+
"_neutron": {
|
|
68
|
+
"surface": "option"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"kind": "field",
|
|
73
|
+
"name": "compassThrottleMs",
|
|
74
|
+
"type": {
|
|
75
|
+
"text": "number"
|
|
76
|
+
},
|
|
77
|
+
"privacy": "public",
|
|
78
|
+
"readonly": false,
|
|
79
|
+
"description": "Minimum ms between `provider-orientation-success` updates. Android can fire `deviceorientationabsolute` at 60-200 Hz; without throttling that floods listeners and CSS/Quark bindings.",
|
|
80
|
+
"default": 100,
|
|
81
|
+
"_neutron": {
|
|
82
|
+
"surface": "option"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"kind": "field",
|
|
87
|
+
"name": "isRequesting",
|
|
88
|
+
"type": {
|
|
89
|
+
"text": "boolean"
|
|
90
|
+
},
|
|
91
|
+
"privacy": "public",
|
|
92
|
+
"readonly": true,
|
|
93
|
+
"description": "iOS only: the permission request is pending (between `provider-orientation-request` and the user's response).",
|
|
94
|
+
"_neutron": {
|
|
95
|
+
"surface": "state"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"kind": "field",
|
|
100
|
+
"name": "isSuccess",
|
|
101
|
+
"type": {
|
|
102
|
+
"text": "boolean"
|
|
103
|
+
},
|
|
104
|
+
"privacy": "public",
|
|
105
|
+
"readonly": true,
|
|
106
|
+
"description": "Listening for orientation updates (permission granted where required). Stays set across updates.",
|
|
107
|
+
"_neutron": {
|
|
108
|
+
"surface": "state"
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"kind": "field",
|
|
113
|
+
"name": "isError",
|
|
114
|
+
"type": {
|
|
115
|
+
"text": "boolean"
|
|
116
|
+
},
|
|
117
|
+
"privacy": "public",
|
|
118
|
+
"readonly": true,
|
|
119
|
+
"description": "The permission request was denied, or listening failed to start.",
|
|
120
|
+
"_neutron": {
|
|
121
|
+
"surface": "state"
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"kind": "field",
|
|
126
|
+
"name": "provision",
|
|
127
|
+
"type": {
|
|
128
|
+
"text": "ProviderOrientationSuccess",
|
|
129
|
+
"expanded": "{ bearing: number; alpha: number | null; }"
|
|
130
|
+
},
|
|
131
|
+
"privacy": "public",
|
|
132
|
+
"readonly": false,
|
|
133
|
+
"description": "Latest reading: `{ bearing, alpha }` on success, or the error on failure. Not reflected as an attribute.",
|
|
134
|
+
"_neutron": {
|
|
135
|
+
"surface": "option"
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
"events": [
|
|
140
|
+
{
|
|
141
|
+
"name": "provider-orientation-success",
|
|
142
|
+
"description": "Dispatched on every compass update (throttled by `compass-throttle-ms`). `bearing` is normalized 0-360°; `alpha` is the raw `DeviceOrientationEvent.alpha` where available.",
|
|
143
|
+
"type": {
|
|
144
|
+
"text": "ProviderOrientationSuccessEvent",
|
|
145
|
+
"expanded": "CustomEvent & { type: \"provider-orientation-success\"; detail: { bearing: number; alpha: number | null; }; bubbles: true; cancelable: true; composed: true }"
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"name": "provider-orientation-error",
|
|
150
|
+
"description": "Dispatched when the permission request is denied, or fails for any other reason.",
|
|
151
|
+
"type": {
|
|
152
|
+
"text": "ProviderOrientationErrorEvent",
|
|
153
|
+
"expanded": "CustomEvent & { type: \"provider-orientation-error\"; detail: string | Error; bubbles: true; cancelable: true; composed: true }"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
],
|
|
157
|
+
"_neutron": {
|
|
158
|
+
"provisions": [
|
|
159
|
+
{
|
|
160
|
+
"name": "provision",
|
|
161
|
+
"type": {
|
|
162
|
+
"text": "ProviderOrientationSuccess",
|
|
163
|
+
"expanded": "{ bearing: number; alpha: number | null; }"
|
|
164
|
+
},
|
|
165
|
+
"description": "Latest reading: `{ bearing, alpha }` on success, or the error on failure. Not reflected as an attribute.",
|
|
166
|
+
"fieldName": "provision"
|
|
167
|
+
}
|
|
168
|
+
],
|
|
169
|
+
"commands": [
|
|
170
|
+
{
|
|
171
|
+
"name": "--request",
|
|
172
|
+
"description": "Requests permission (iOS) and starts listening for orientation updates. Invoke it from a button (`<button command=\"--request\" commandfor=\"…\">`) so the user activation is there."
|
|
173
|
+
}
|
|
174
|
+
],
|
|
175
|
+
"defaultActions": [
|
|
176
|
+
{
|
|
177
|
+
"name": "provider-orientation-success",
|
|
178
|
+
"description": "Stores `{ bearing, alpha }` in `provision` and sets `is-success` (clearing `is-requesting` / `is-error`)."
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"name": "provider-orientation-error",
|
|
182
|
+
"description": "Stores the error in `provision` and sets `is-error` (clearing `is-requesting` / `is-success`)."
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
],
|
|
188
|
+
"exports": [
|
|
189
|
+
{
|
|
190
|
+
"kind": "js",
|
|
191
|
+
"name": "ProviderOrientation",
|
|
192
|
+
"declaration": {
|
|
193
|
+
"name": "ProviderOrientation",
|
|
194
|
+
"module": "provider-orientation.ts"
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"kind": "custom-element-definition",
|
|
199
|
+
"name": "provider-orientation",
|
|
200
|
+
"declaration": {
|
|
201
|
+
"name": "ProviderOrientation",
|
|
202
|
+
"module": "provider-orientation.ts"
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
]
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<div id="orient-demo">
|
|
2
|
+
<button type="button" command="--request" commandfor="orient">
|
|
3
|
+
Enable compass
|
|
4
|
+
</button>
|
|
5
|
+
<provider-orientation id="orient" is-paused></provider-orientation>
|
|
6
|
+
<p class="status">No reading yet — click above. Requires a device
|
|
7
|
+
sensor (desktop browsers usually have none).</p>
|
|
8
|
+
<output>Waiting…</output>
|
|
9
|
+
<quark-sheet>
|
|
10
|
+
@use "/demo-utils" as *;
|
|
11
|
+
|
|
12
|
+
#orient-demo { @on neutron-provision (handle: setOutputFromElementData); }
|
|
13
|
+
</quark-sheet>
|
|
14
|
+
</div>
|