@tooee/overlays 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/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # @tooee/overlays
2
+
3
+ Overlay stack management for Tooee.
4
+
5
+ Part of the [Tooee](https://github.com/gingerhendrix/tooee) monorepo. See the main repo for documentation.
@@ -0,0 +1,3 @@
1
+ export { OverlayContext, OverlayControllerContext, OverlayStateContext, useOverlay, useOverlayState, useCurrentOverlay, useHasOverlay, } from "./overlay-context.jsx";
2
+ export type { OverlayContextValue, OverlayId, OverlayCloseReason, OverlayOpenOptions, OverlayRenderArgs, OverlayRenderer, OverlayHandle, OverlayController, OverlayState, } from "./overlay-context.jsx";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,aAAa,GACd,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EACV,mBAAmB,EACnB,SAAS,EACT,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,YAAY,GACb,MAAM,uBAAuB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { OverlayContext, OverlayControllerContext, OverlayStateContext, useOverlay, useOverlayState, useCurrentOverlay, useHasOverlay, } from "./overlay-context.jsx";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,aAAa,GACd,MAAM,uBAAuB,CAAA"}
@@ -0,0 +1,54 @@
1
+ import type { ReactNode } from "react";
2
+ export type OverlayId = string;
3
+ export type OverlayCloseReason = "close" | "escape" | "replaced" | "unmounted";
4
+ export interface OverlayOpenOptions {
5
+ /** Mode to set while overlay is active (default: "insert"). null = don't change mode. */
6
+ mode?: string | null;
7
+ /** Restore previous mode on close (default: true) */
8
+ restoreMode?: boolean;
9
+ /** Allow Escape to close this overlay (default: true) */
10
+ dismissOnEscape?: boolean;
11
+ /** Lifecycle callback */
12
+ onClose?: (reason: OverlayCloseReason) => void;
13
+ }
14
+ export interface OverlayRenderArgs<TPayload> {
15
+ id: OverlayId;
16
+ payload: TPayload;
17
+ isTop: boolean;
18
+ close: (reason?: OverlayCloseReason) => void;
19
+ update: (next: TPayload | ((prev: TPayload) => TPayload)) => void;
20
+ }
21
+ export type OverlayRenderer<TPayload> = (args: OverlayRenderArgs<TPayload>) => ReactNode;
22
+ export interface OverlayHandle<TPayload> {
23
+ id: OverlayId;
24
+ close: (reason?: OverlayCloseReason) => void;
25
+ update: (next: TPayload | ((prev: TPayload) => TPayload)) => void;
26
+ }
27
+ export interface OverlayController {
28
+ open<TPayload>(id: OverlayId, render: OverlayRenderer<TPayload>, payload: TPayload, options?: OverlayOpenOptions): OverlayHandle<TPayload>;
29
+ update<TPayload>(id: OverlayId, next: TPayload | ((prev: TPayload) => TPayload)): void;
30
+ show(id: OverlayId, content: ReactNode, options?: OverlayOpenOptions): void;
31
+ hide(id: OverlayId): void;
32
+ closeTop(reason?: OverlayCloseReason): void;
33
+ isOpen(id: OverlayId): boolean;
34
+ topId: OverlayId | null;
35
+ }
36
+ export interface OverlayState {
37
+ current: ReactNode | null;
38
+ hasOverlay: boolean;
39
+ stack: OverlayId[];
40
+ }
41
+ export interface OverlayContextValue {
42
+ show: (id: string, content: ReactNode, options?: OverlayOpenOptions) => void;
43
+ hide: (id: string) => void;
44
+ current: ReactNode | null;
45
+ hasOverlay: boolean;
46
+ }
47
+ export declare const OverlayControllerContext: import("react").Context<OverlayController>;
48
+ export declare const OverlayStateContext: import("react").Context<OverlayState>;
49
+ export declare const OverlayContext: import("react").Context<OverlayContextValue>;
50
+ export declare function useOverlay(): OverlayController;
51
+ export declare function useOverlayState(): OverlayState;
52
+ export declare function useHasOverlay(): boolean;
53
+ export declare function useCurrentOverlay(): ReactNode | null;
54
+ //# sourceMappingURL=overlay-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay-context.d.ts","sourceRoot":"","sources":["../src/overlay-context.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { createContext, useContext } from "react";
2
+ // Contexts
3
+ const defaultController = {
4
+ open: (id) => ({ id, close: () => { }, update: () => { } }),
5
+ update: () => { },
6
+ show: () => { },
7
+ hide: () => { },
8
+ closeTop: () => { },
9
+ isOpen: () => false,
10
+ topId: null,
11
+ };
12
+ const defaultState = {
13
+ current: null,
14
+ hasOverlay: false,
15
+ stack: [],
16
+ };
17
+ export const OverlayControllerContext = createContext(defaultController);
18
+ export const OverlayStateContext = createContext(defaultState);
19
+ // Back-compat: OverlayContext that combines both (for existing provider consumers)
20
+ export const OverlayContext = createContext({
21
+ show: () => { },
22
+ hide: () => { },
23
+ current: null,
24
+ hasOverlay: false,
25
+ });
26
+ // Hooks
27
+ export function useOverlay() {
28
+ return useContext(OverlayControllerContext);
29
+ }
30
+ export function useOverlayState() {
31
+ return useContext(OverlayStateContext);
32
+ }
33
+ export function useHasOverlay() {
34
+ return useContext(OverlayStateContext).hasOverlay;
35
+ }
36
+ export function useCurrentOverlay() {
37
+ return useContext(OverlayStateContext).current;
38
+ }
39
+ //# sourceMappingURL=overlay-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay-context.js","sourceRoot":"","sources":["../src/overlay-context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAiEjD,WAAW;AAEX,MAAM,iBAAiB,GAAsB;IAC3C,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;IACzD,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC;IAChB,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC;IAClB,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK;IACnB,KAAK,EAAE,IAAI;CACZ,CAAA;AAED,MAAM,YAAY,GAAiB;IACjC,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,KAAK;IACjB,KAAK,EAAE,EAAE;CACV,CAAA;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG,aAAa,CAAoB,iBAAiB,CAAC,CAAA;AAC3F,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAe,YAAY,CAAC,CAAA;AAE5E,mFAAmF;AACnF,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAsB;IAC/D,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,KAAK;CAClB,CAAC,CAAA;AAEF,QAAQ;AAER,MAAM,UAAU,UAAU;IACxB,OAAO,UAAU,CAAC,wBAAwB,CAAC,CAAA;AAC7C,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,UAAU,CAAC,mBAAmB,CAAC,CAAA;AACxC,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,UAAU,CAAC,mBAAmB,CAAC,CAAC,UAAU,CAAA;AACnD,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,UAAU,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAA;AAChD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@tooee/overlays",
3
+ "version": "0.1.0",
4
+ "description": "Overlay stack management for Tooee",
5
+ "license": "MIT",
6
+ "author": "Gareth Andrew",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/gingerhendrix/tooee.git",
10
+ "directory": "packages/overlays"
11
+ },
12
+ "homepage": "https://github.com/gingerhendrix/tooee",
13
+ "bugs": "https://github.com/gingerhendrix/tooee/issues",
14
+ "keywords": ["tui", "terminal", "cli", "opentui"],
15
+ "type": "module",
16
+ "exports": {
17
+ ".": {
18
+ "import": {
19
+ "@tooee/source": "./src/index.ts",
20
+ "default": "./dist/index.js"
21
+ }
22
+ }
23
+ },
24
+ "files": ["dist", "src"],
25
+ "scripts": {
26
+ "typecheck": "tsc --noEmit"
27
+ },
28
+ "devDependencies": {
29
+ "@types/bun": "^1.3.5",
30
+ "@types/react": "^19.1.10",
31
+ "typescript": "^5.8.3"
32
+ },
33
+ "peerDependencies": {
34
+ "react": "^18.0.0 || ^19.0.0"
35
+ }
36
+ }
package/src/index.ts ADDED
@@ -0,0 +1,20 @@
1
+ export {
2
+ OverlayContext,
3
+ OverlayControllerContext,
4
+ OverlayStateContext,
5
+ useOverlay,
6
+ useOverlayState,
7
+ useCurrentOverlay,
8
+ useHasOverlay,
9
+ } from "./overlay-context.jsx"
10
+ export type {
11
+ OverlayContextValue,
12
+ OverlayId,
13
+ OverlayCloseReason,
14
+ OverlayOpenOptions,
15
+ OverlayRenderArgs,
16
+ OverlayRenderer,
17
+ OverlayHandle,
18
+ OverlayController,
19
+ OverlayState,
20
+ } from "./overlay-context.jsx"
@@ -0,0 +1,111 @@
1
+ import { createContext, useContext } from "react"
2
+ import type { ReactNode } from "react"
3
+
4
+ // Types
5
+
6
+ export type OverlayId = string
7
+
8
+ export type OverlayCloseReason = "close" | "escape" | "replaced" | "unmounted"
9
+
10
+ export interface OverlayOpenOptions {
11
+ /** Mode to set while overlay is active (default: "insert"). null = don't change mode. */
12
+ mode?: string | null
13
+ /** Restore previous mode on close (default: true) */
14
+ restoreMode?: boolean
15
+ /** Allow Escape to close this overlay (default: true) */
16
+ dismissOnEscape?: boolean
17
+ /** Lifecycle callback */
18
+ onClose?: (reason: OverlayCloseReason) => void
19
+ }
20
+
21
+ export interface OverlayRenderArgs<TPayload> {
22
+ id: OverlayId
23
+ payload: TPayload
24
+ isTop: boolean
25
+ close: (reason?: OverlayCloseReason) => void
26
+ update: (next: TPayload | ((prev: TPayload) => TPayload)) => void
27
+ }
28
+
29
+ export type OverlayRenderer<TPayload> = (args: OverlayRenderArgs<TPayload>) => ReactNode
30
+
31
+ export interface OverlayHandle<TPayload> {
32
+ id: OverlayId
33
+ close: (reason?: OverlayCloseReason) => void
34
+ update: (next: TPayload | ((prev: TPayload) => TPayload)) => void
35
+ }
36
+
37
+ export interface OverlayController {
38
+ open<TPayload>(
39
+ id: OverlayId,
40
+ render: OverlayRenderer<TPayload>,
41
+ payload: TPayload,
42
+ options?: OverlayOpenOptions,
43
+ ): OverlayHandle<TPayload>
44
+ update<TPayload>(id: OverlayId, next: TPayload | ((prev: TPayload) => TPayload)): void
45
+ show(id: OverlayId, content: ReactNode, options?: OverlayOpenOptions): void
46
+ hide(id: OverlayId): void
47
+ closeTop(reason?: OverlayCloseReason): void
48
+ isOpen(id: OverlayId): boolean
49
+ topId: OverlayId | null
50
+ }
51
+
52
+ export interface OverlayState {
53
+ current: ReactNode | null
54
+ hasOverlay: boolean
55
+ stack: OverlayId[]
56
+ }
57
+
58
+ // Back-compat type (still exported for existing consumers)
59
+ export interface OverlayContextValue {
60
+ show: (id: string, content: ReactNode, options?: OverlayOpenOptions) => void
61
+ hide: (id: string) => void
62
+ current: ReactNode | null
63
+ hasOverlay: boolean
64
+ }
65
+
66
+ // Contexts
67
+
68
+ const defaultController: OverlayController = {
69
+ open: (id) => ({ id, close: () => {}, update: () => {} }),
70
+ update: () => {},
71
+ show: () => {},
72
+ hide: () => {},
73
+ closeTop: () => {},
74
+ isOpen: () => false,
75
+ topId: null,
76
+ }
77
+
78
+ const defaultState: OverlayState = {
79
+ current: null,
80
+ hasOverlay: false,
81
+ stack: [],
82
+ }
83
+
84
+ export const OverlayControllerContext = createContext<OverlayController>(defaultController)
85
+ export const OverlayStateContext = createContext<OverlayState>(defaultState)
86
+
87
+ // Back-compat: OverlayContext that combines both (for existing provider consumers)
88
+ export const OverlayContext = createContext<OverlayContextValue>({
89
+ show: () => {},
90
+ hide: () => {},
91
+ current: null,
92
+ hasOverlay: false,
93
+ })
94
+
95
+ // Hooks
96
+
97
+ export function useOverlay(): OverlayController {
98
+ return useContext(OverlayControllerContext)
99
+ }
100
+
101
+ export function useOverlayState(): OverlayState {
102
+ return useContext(OverlayStateContext)
103
+ }
104
+
105
+ export function useHasOverlay(): boolean {
106
+ return useContext(OverlayStateContext).hasOverlay
107
+ }
108
+
109
+ export function useCurrentOverlay(): ReactNode | null {
110
+ return useContext(OverlayStateContext).current
111
+ }