@magelight/react 0.28.6
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/LICENSE +21 -0
- package/README.md +22 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +50 -0
- package/package.json +30 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Severause
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# @magelight/react
|
|
2
|
+
|
|
3
|
+
Hooks over `@magelight/sdk` for pages hosted by Magelight UI.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { useChannel, useUIMode, useSend, HostGate } from '@magelight/react';
|
|
7
|
+
|
|
8
|
+
function Config() {
|
|
9
|
+
const state = useChannel<{ volume: number }>('state', { volume: 50 });
|
|
10
|
+
const focused = useUIMode();
|
|
11
|
+
const send = useSend();
|
|
12
|
+
return (
|
|
13
|
+
<HostGate fallback={<p>Open this page inside Skyrim.</p>} minVersion={[0, 15]}>
|
|
14
|
+
<input type="range" value={state.volume} onChange={(e) => send('save', { volume: +e.target.value })} />
|
|
15
|
+
{focused ? 'keyboard is yours' : 'HUD mode'}
|
|
16
|
+
</HostGate>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`useChannel(name, initial)` · `useHostData` (alias) · `useChannelEvent(name, fn)` · `useUIMode()` ·
|
|
22
|
+
`useCapability(name)` · `useHost()` · `useSend()` · `<HostGate fallback outdated minVersion>`.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* The latest payload on a channel (parsed), `initial` until one arrives.
|
|
4
|
+
* A payload that landed before mount is replayed on subscribe, so the
|
|
5
|
+
* first render after mount already has it.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useChannel<T>(channel: string, initial: T): T;
|
|
8
|
+
/** `useHostData` is `useChannel` under the name SeverActions' frontend used. */
|
|
9
|
+
export declare const useHostData: typeof useChannel;
|
|
10
|
+
/** Subscribe with a callback instead of state (for events, not state). */
|
|
11
|
+
export declare function useChannelEvent<T>(channel: string, fn: (value: T) => void): void;
|
|
12
|
+
/** true while this view holds UI mode (cursor up, keyboard to the page). */
|
|
13
|
+
export declare function useUIMode(): boolean;
|
|
14
|
+
/** `useCapability('textureImage')` — false with no host. */
|
|
15
|
+
export declare function useCapability(name: string): boolean;
|
|
16
|
+
/** Static host facts for render-time branching (`host.present`, version, ids). */
|
|
17
|
+
export declare function useHost(): {
|
|
18
|
+
readonly present: boolean;
|
|
19
|
+
readonly info: import("@magelight/sdk").HostInfo;
|
|
20
|
+
readonly version: string;
|
|
21
|
+
readonly versionNumber: number;
|
|
22
|
+
readonly modId: string;
|
|
23
|
+
readonly viewName: string;
|
|
24
|
+
readonly viewId: number;
|
|
25
|
+
readonly dev: boolean;
|
|
26
|
+
can(capability: string): boolean;
|
|
27
|
+
atLeast(major: number, minor: number, patch?: number): boolean;
|
|
28
|
+
imageUrl(name: string): string;
|
|
29
|
+
};
|
|
30
|
+
/** Page → host, stable identity. */
|
|
31
|
+
export declare function useSend(): (channel: string, payload?: unknown) => void;
|
|
32
|
+
/**
|
|
33
|
+
* Renders children only on Magelight (or the mock in a browser); `fallback`
|
|
34
|
+
* elsewhere. `minVersion` = [major, minor, patch] gates on the host version
|
|
35
|
+
* and renders `outdated` (or `fallback`) when too old.
|
|
36
|
+
*/
|
|
37
|
+
export declare function HostGate(props: {
|
|
38
|
+
children: ReactNode;
|
|
39
|
+
fallback?: ReactNode;
|
|
40
|
+
outdated?: ReactNode;
|
|
41
|
+
minVersion?: [number, number, number?];
|
|
42
|
+
}): ReactNode;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { bridge, host } from '@magelight/sdk';
|
|
3
|
+
/**
|
|
4
|
+
* The latest payload on a channel (parsed), `initial` until one arrives.
|
|
5
|
+
* A payload that landed before mount is replayed on subscribe, so the
|
|
6
|
+
* first render after mount already has it.
|
|
7
|
+
*/
|
|
8
|
+
export function useChannel(channel, initial) {
|
|
9
|
+
const [value, setValue] = useState(initial);
|
|
10
|
+
useEffect(() => bridge.on(channel, setValue), [channel]);
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
/** `useHostData` is `useChannel` under the name SeverActions' frontend used. */
|
|
14
|
+
export const useHostData = useChannel;
|
|
15
|
+
/** Subscribe with a callback instead of state (for events, not state). */
|
|
16
|
+
export function useChannelEvent(channel, fn) {
|
|
17
|
+
useEffect(() => bridge.on(channel, fn), [channel, fn]);
|
|
18
|
+
}
|
|
19
|
+
/** true while this view holds UI mode (cursor up, keyboard to the page). */
|
|
20
|
+
export function useUIMode() {
|
|
21
|
+
const [on, setOn] = useState(false);
|
|
22
|
+
useEffect(() => bridge.onUIMode(setOn), []);
|
|
23
|
+
return on;
|
|
24
|
+
}
|
|
25
|
+
/** `useCapability('textureImage')` — false with no host. */
|
|
26
|
+
export function useCapability(name) {
|
|
27
|
+
return host.can(name);
|
|
28
|
+
}
|
|
29
|
+
/** Static host facts for render-time branching (`host.present`, version, ids). */
|
|
30
|
+
export function useHost() {
|
|
31
|
+
return host;
|
|
32
|
+
}
|
|
33
|
+
/** Page → host, stable identity. */
|
|
34
|
+
export function useSend() {
|
|
35
|
+
return bridge.send;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Renders children only on Magelight (or the mock in a browser); `fallback`
|
|
39
|
+
* elsewhere. `minVersion` = [major, minor, patch] gates on the host version
|
|
40
|
+
* and renders `outdated` (or `fallback`) when too old.
|
|
41
|
+
*/
|
|
42
|
+
export function HostGate(props) {
|
|
43
|
+
var _a, _b, _c, _d;
|
|
44
|
+
if (!host.present)
|
|
45
|
+
return (_a = props.fallback) !== null && _a !== void 0 ? _a : null;
|
|
46
|
+
if (props.minVersion && !host.atLeast(props.minVersion[0], props.minVersion[1], (_b = props.minVersion[2]) !== null && _b !== void 0 ? _b : 0)) {
|
|
47
|
+
return (_d = (_c = props.outdated) !== null && _c !== void 0 ? _c : props.fallback) !== null && _d !== void 0 ? _d : null;
|
|
48
|
+
}
|
|
49
|
+
return props.children;
|
|
50
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@magelight/react",
|
|
3
|
+
"version": "0.28.6",
|
|
4
|
+
"description": "React hooks for Magelight UI pages: useChannel, useUIMode, useCapability, HostGate.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": { "type": "git", "url": "git+https://github.com/Severause/MagelightUI.git", "directory": "packages/react" },
|
|
7
|
+
"publishConfig": { "access": "public" },
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" }
|
|
13
|
+
},
|
|
14
|
+
"files": ["dist", "README.md"],
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc -p tsconfig.json",
|
|
18
|
+
"prepack": "npm run build"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@magelight/sdk": ">=0.28.6",
|
|
22
|
+
"react": ">=18"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@magelight/sdk": "^0.28.6",
|
|
26
|
+
"@types/react": "^19.2.7",
|
|
27
|
+
"react": "^19.2.0",
|
|
28
|
+
"typescript": "~5.9.3"
|
|
29
|
+
}
|
|
30
|
+
}
|