overkit 0.0.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 ADDED
@@ -0,0 +1,314 @@
1
+ # Overkit
2
+
3
+ Simplified overlay management system for React and Next.js. Uses Zustand for state management and allows creating modals, drawers, sheets, and more with ease.
4
+
5
+ ## Features
6
+
7
+ - **Centralized State**: State management with Zustand
8
+ - **Simple Triggers**: Open overlays with a single click
9
+ - **Portals**: Flexible rendering with tunnel-rat
10
+ - **TypeScript**: Complete and safe typing
11
+ - **Dynamic Configuration**: Props based on store state
12
+ - **Built-in Hooks**: Access state from any component
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install overkit
18
+ # or
19
+ yarn add overkit
20
+ # or
21
+ pnpm add overkit
22
+ ```
23
+
24
+ ## Dependencies
25
+
26
+ ```bash
27
+ npm install zustand @radix-ui/react-slot tunnel-rat
28
+ ```
29
+
30
+ ## Basic Usage
31
+
32
+ ### 1. Create a Registry
33
+
34
+ First, create a base component that will serve as the overlay (Modal, Drawer, Sheet, etc.):
35
+
36
+ ```tsx
37
+ // components/modal.tsx
38
+ import { registry, type RegistryComponentProps } from "overkit";
39
+
40
+ const Modal = ({
41
+ open,
42
+ onOpenChange,
43
+ title,
44
+ description,
45
+ children,
46
+ }: RegistryComponentProps) => {
47
+ if (!open) return null;
48
+
49
+ return (
50
+ <div className="modal-backdrop" onClick={() => onOpenChange?.(false)}>
51
+ <div className="modal-content">
52
+ <h2>{title}</h2>
53
+ <p>{description}</p>
54
+ {children}
55
+ </div>
56
+ </div>
57
+ );
58
+ };
59
+
60
+ export const ModalRegistry = registry({
61
+ name: "modal",
62
+ render: Modal,
63
+ });
64
+ ```
65
+
66
+ ### 2. Configure Overkit
67
+
68
+ ```tsx
69
+ // overlays.tsx
70
+ import { Overkit } from "overkit";
71
+ import { ModalRegistry } from "./modal";
72
+
73
+ const o = new Overkit(["userModal", "confirmDialog"] as const)
74
+ .with(ModalRegistry)
75
+ .build();
76
+
77
+ // Create simple overlay
78
+ const userDialog = o.create("userModal", "modal").configure({
79
+ title: "User Profile",
80
+ description: "Manage your profile information",
81
+ });
82
+
83
+ // Create overlay with extended state
84
+ const confirmDialog = o
85
+ .create("confirmDialog", "modal")
86
+ .extend<{ message: string }>(() => ({
87
+ message: "",
88
+ }))
89
+ .configure({
90
+ title: "Confirm Action",
91
+ description: "Are you sure?",
92
+ });
93
+
94
+ // Export components
95
+ export const UserModalTrigger = userDialog.trigger;
96
+ export const UserModalView = userDialog.view;
97
+
98
+ export const ConfirmTrigger = confirmDialog.trigger;
99
+ export const ConfirmView = confirmDialog.view;
100
+ export const useOverkitStore = o.useOverkitStore;
101
+ ```
102
+
103
+ ### 3. Use in Your App
104
+
105
+ ```tsx
106
+ // page.tsx
107
+ import { UserModalTrigger, UserModalView } from "./overlays";
108
+
109
+ export default function Page() {
110
+ return (
111
+ <div>
112
+ <UserModalTrigger>
113
+ <button>Open User Modal</button>
114
+ </UserModalTrigger>
115
+
116
+ <UserModalView />
117
+ </div>
118
+ );
119
+ }
120
+ ```
121
+
122
+ ## API
123
+
124
+ ### `Overkit`
125
+
126
+ The main class for creating and managing overlays.
127
+
128
+ ```tsx
129
+ const o = new Overkit(["key1", "key2"] as const).with(RegistryItem).build();
130
+ ```
131
+
132
+ ### `.create(key, registryName)`
133
+
134
+ Creates a new overlay.
135
+
136
+ ```tsx
137
+ const dialog = o.create("myDialog", "modal");
138
+ ```
139
+
140
+ ### `.extend<State>(storeCreator)`
141
+
142
+ Extends the overlay state with additional properties.
143
+
144
+ ```tsx
145
+ const dialog = o
146
+ .create("myDialog", "modal")
147
+ .extend<{ count: number }>((set) => ({
148
+ count: 0,
149
+ increment: () => set((state) => ({ count: state.count + 1 })),
150
+ }));
151
+ ```
152
+
153
+ ### `.configure(options)`
154
+
155
+ Configures the overlay properties. You can use static values or functions that receive the store:
156
+
157
+ ```tsx
158
+ const dialog = o
159
+ .create("productDialog", "modal")
160
+ .extend<{ mode: "create" | "edit" }>((set) => ({
161
+ mode: "create",
162
+ setMode: (mode) => set({ mode }),
163
+ }))
164
+ .configure({
165
+ // Static values
166
+ title: "Product",
167
+
168
+ // Functions with store access
169
+ title: (store) =>
170
+ store?.mode === "create" ? "Create Product" : "Edit Product",
171
+ description: (store) =>
172
+ store?.mode === "create"
173
+ ? "Create a new product"
174
+ : "Edit existing product",
175
+ className: (store) =>
176
+ store?.mode === "create" ? "mode-create" : "mode-edit",
177
+ });
178
+ ```
179
+
180
+ ### `trigger`
181
+
182
+ Component to open the overlay.
183
+
184
+ ```tsx
185
+ <Trigger>
186
+ <button>Open</button>
187
+ </Trigger>
188
+
189
+ // With initial store values
190
+ <Trigger count={100}>
191
+ <button>Open with 100</button>
192
+ </Trigger>
193
+
194
+ // With componentProps for the view
195
+ <Trigger componentProps={{ items: ["a", "b", "c"] }}>
196
+ <button>Open with Items</button>
197
+ </Trigger>
198
+ ```
199
+
200
+ ### `view`
201
+
202
+ Component that renders the overlay content.
203
+
204
+ ```tsx
205
+ // Basic
206
+ const View = dialog.view(() => <div>Content</div>);
207
+
208
+ // With props
209
+ const View = dialog.view<{ items: string[] }>(({ items }) => (
210
+ <ul>
211
+ {items.map((item) => (
212
+ <li key={item}>{item}</li>
213
+ ))}
214
+ </ul>
215
+ ));
216
+
217
+ // With close function
218
+ const View = dialog.view(({ close }) => (
219
+ <div>
220
+ <button onClick={close}>Close</button>
221
+ </div>
222
+ ));
223
+
224
+ // With useInnerContext (requires .extend())
225
+ const View = dialog.view(({ useInnerContext }) => {
226
+ const count = useInnerContext((state) => state.count);
227
+ const increment = useInnerContext((state) => state.increment);
228
+
229
+ return (
230
+ <div>
231
+ <p>Count: {count}</p>
232
+ <button onClick={increment}>Increment</button>
233
+ </div>
234
+ );
235
+ });
236
+ ```
237
+
238
+ ### `useOverkitStore`
239
+
240
+ Hook to access the global state of all overlays.
241
+
242
+ ```tsx
243
+ const isOpen = useOverkitStore((state) => state.states.myDialog);
244
+ const setOpen = useOverkitStore((state) => state.setMyDialog);
245
+
246
+ // Open/close programmatically
247
+ setOpen(true);
248
+ setOpen(false);
249
+ ```
250
+
251
+ ## Advanced Examples
252
+
253
+ ### Product Sheet (Create/Edit)
254
+
255
+ ```tsx
256
+ const productSheet = o
257
+ .create("productSheet", "Sheet")
258
+ .extend<ProductState>((set) => ({
259
+ mode: "create",
260
+ setMode: (mode) => set({ mode }),
261
+ }))
262
+ .configure({
263
+ title: (store) => {
264
+ return store?.mode === "create" ? "Create a Product" : "Edit Product";
265
+ },
266
+ description: (store) => {
267
+ return store?.mode === "create"
268
+ ? "Fill in the details of the product you want to create"
269
+ : "Fill in the details of the product you want to edit";
270
+ },
271
+ className: "!max-w-none w-3/8",
272
+ });
273
+ ```
274
+
275
+ ### Counter with Extended State
276
+
277
+ ```tsx
278
+ const counterDialog = o
279
+ .create("counter", "modal")
280
+ .extend<{ count: number }>((set) => ({
281
+ count: 0,
282
+ }))
283
+ .configure({
284
+ title: "Counter Dialog",
285
+ });
286
+
287
+ // Open with initial value
288
+ <counterDialog.trigger count={100}>
289
+ <button>Open with 100</button>
290
+ </counterDialog.trigger>;
291
+
292
+ // Use in the view
293
+ const CounterView = counterDialog.view(({ useInnerContext }) => {
294
+ const count = useInnerContext((state) => state.count);
295
+ return <div>Count: {count}</div>;
296
+ });
297
+ ```
298
+
299
+ ## TypeScript
300
+
301
+ Overkit is fully typed. When creating overlays, types are automatically inferred:
302
+
303
+ ```tsx
304
+ // Keys are validated at compile time
305
+ const o = new Overkit(["dialog1", "dialog2"] as const);
306
+
307
+ // TypeScript knows only "dialog1" and "dialog2" are valid
308
+ o.create("dialog1", "modal"); // ✅
309
+ o.create("dialog3", "modal"); // ❌ Type error
310
+ ```
311
+
312
+ ## License
313
+
314
+ MIT
@@ -0,0 +1,110 @@
1
+ import React from "react";
2
+ import tunnel from "tunnel-rat";
3
+ import * as zustand from "zustand";
4
+ import { StoreApi, UseBoundStore } from "zustand";
5
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
6
+
7
+ //#region src/types.d.ts
8
+ type Capitalize<S extends string> = S extends `${infer F}${infer R}` ? `${Uppercase<F>}${R}` : S;
9
+ type StoreStates<TKeys extends readonly string[]> = { [K in TKeys[number]]: boolean };
10
+ type StoreSetters<TKeys extends readonly string[]> = { [K in TKeys[number] as `set${Capitalize<K>}`]: (value: boolean) => void };
11
+ type FactoryStore<TKeys extends readonly string[]> = {
12
+ states: StoreStates<TKeys>;
13
+ } & StoreSetters<TKeys>;
14
+ type ValueOrFunction<T, Store> = T | ((value: Store) => T);
15
+ type _SharedProps<ExtendedProps extends object = object> = ExtendedProps & {
16
+ title: string;
17
+ description: string;
18
+ className: string;
19
+ beforeOpen?: () => void;
20
+ beforeClose?: () => void;
21
+ };
22
+ type RegistryHooks<Store = unknown> = {
23
+ beforeOpen?: (store?: Store, api?: StoreApi<Store>) => void;
24
+ beforeClose?: (store?: Store, api?: StoreApi<Store>) => void;
25
+ };
26
+ type InitViewProps<ExtendedProps extends object = object, Store = unknown> = ExtendedProps & { [K in keyof Omit<_SharedProps, keyof RegistryHooks>]?: ValueOrFunction<_SharedProps[K], Store> } & RegistryHooks<Store>;
27
+ type RegistryComponentProps<ExtendedProps extends object = object> = {
28
+ children?: React.ReactNode;
29
+ open?: boolean;
30
+ onOpenChange?: (open: boolean) => void;
31
+ t: ReturnType<typeof tunnel>;
32
+ } & _SharedProps<ExtendedProps>;
33
+ //#endregion
34
+ //#region src/core/registry.d.ts
35
+ interface RegistryItem<Key extends string = string, OtherProps extends object = object> {
36
+ name: Key;
37
+ render: (opt: RegistryComponentProps & InitViewProps<OtherProps>) => React.ReactElement | null;
38
+ }
39
+ declare const registry: <Key extends string = string, ItemProps extends object = object>(config: RegistryItem<Key, ItemProps>) => RegistryItem<Key, ItemProps>;
40
+ type RegistryItemMap = Record<string, RegistryItem<any, any>>;
41
+ //#endregion
42
+ //#region src/core/builder.d.ts
43
+ type ViewProps<TProps extends object> = TProps & {
44
+ close: () => void;
45
+ FooterButtons: ReturnType<typeof tunnel>["In"];
46
+ };
47
+ type ExtendedState<T> = T & {
48
+ _internal?: any;
49
+ _injectedProps?: Record<string, any>;
50
+ };
51
+ type UseInnerContextHook<TState> = <TSelected = TState>(selector?: (state: TState) => TSelected) => TSelected;
52
+ type ValueProperties<T> = { [K in keyof T as T[K] extends ((...args: any[]) => any) ? never : K]: T[K] };
53
+ declare class PortalBuilder<TKeys extends readonly string[], TKey extends TKeys[number], TExtendedProps extends object = object, TExtendedState extends object = object, Extended extends boolean = false> {
54
+ private key;
55
+ private t;
56
+ private options;
57
+ private RegistryComponent;
58
+ private innerStore?;
59
+ private useFactoryStore;
60
+ private extended;
61
+ constructor(key: TKey, useFactoryStore: UseBoundStore<StoreApi<FactoryStore<TKeys>>>, HubItemComponent: React.ComponentType<RegistryComponentProps>, options?: InitViewProps<TExtendedProps>, extended?: Extended);
62
+ configure(options: InitViewProps<TExtendedProps, Extended extends true ? TExtendedState : never>): PortalBuilder<TKeys, TKey, TExtendedProps, TExtendedState, Extended>;
63
+ extend<TNewState extends object>(storeCreator: (set: StoreApi<ExtendedState<TNewState>>["setState"], get: StoreApi<ExtendedState<TNewState>>["getState"]) => TNewState): PortalBuilder<TKeys, TKey, TExtendedProps, TNewState, true>;
64
+ private getInnerStore;
65
+ get useInnerContext(): Extended extends true ? UseInnerContextHook<TExtendedState> : never;
66
+ private parseOptions;
67
+ view: <TProps extends object = object>(Component: React.ComponentType<ViewProps<TProps & (Extended extends true ? {
68
+ useInnerContext: UseInnerContextHook<TExtendedState>;
69
+ } : object)>>) => React.FC<TProps>;
70
+ trigger: <THubComponentProps extends object = object, TProps extends object = object>({
71
+ before,
72
+ componentProps,
73
+ ...props
74
+ }: TProps & {
75
+ before?: (innerStore?: TExtendedState) => void;
76
+ componentProps?: Partial<THubComponentProps>;
77
+ children?: React.ReactNode;
78
+ } & ValueProperties<TExtendedState>) => react_jsx_runtime0.JSX.Element;
79
+ }
80
+ //#endregion
81
+ //#region src/core/store.d.ts
82
+ declare class Store<TKeys extends readonly string[]> {
83
+ private factoryStore;
84
+ private FactoryContext;
85
+ private keys;
86
+ private withProvider?;
87
+ constructor(keys: TKeys, withProvider?: boolean);
88
+ private createFactoryStore;
89
+ createProvider: () => React.FC<{
90
+ children: React.ReactNode;
91
+ }>;
92
+ getStore: () => UseBoundStore<StoreApi<FactoryStore<TKeys>>>;
93
+ private getStoreHook;
94
+ }
95
+ //#endregion
96
+ //#region src/core/overkit.d.ts
97
+ declare class Overkit<TKeys extends readonly string[], Items extends RegistryItemMap = Record<string, never>> extends Store<TKeys> {
98
+ private registry;
99
+ constructor(keys: TKeys);
100
+ private create;
101
+ private get useOverkitStore();
102
+ with<THubItemName extends string, ItemProps extends object = object>(item: RegistryItem<THubItemName, ItemProps>): Overkit<TKeys, Items & Record<THubItemName, RegistryItem<THubItemName, ItemProps>>>;
103
+ build(): {
104
+ create: <TKey extends TKeys[number], THubItemName extends keyof Items, ItemProps extends React.ComponentProps<Items[THubItemName]["render"]>>(key: TKey, hubItemName: THubItemName) => PortalBuilder<TKeys, TKey, Omit<ItemProps, "title" | "beforeOpen" | "beforeClose" | "description" | "className" | "children" | "open" | "onOpenChange" | "t">, object, false>;
105
+ useOverkitStore: zustand.UseBoundStore<zustand.StoreApi<FactoryStore<TKeys>>>;
106
+ };
107
+ }
108
+ //#endregion
109
+ export { Overkit, type RegistryComponentProps, registry };
110
+ //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs ADDED
@@ -0,0 +1,305 @@
1
+ import { Slot } from "@radix-ui/react-slot";
2
+ import { createContext, useCallback, useContext, useMemo, useRef } from "react";
3
+ import tunnel from "tunnel-rat";
4
+ import { create, useStore } from "zustand";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+
7
+ //#region \0@oxc-project+runtime@0.112.0/helpers/typeof.js
8
+ function _typeof(o) {
9
+ "@babel/helpers - typeof";
10
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
11
+ return typeof o;
12
+ } : function(o) {
13
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
14
+ }, _typeof(o);
15
+ }
16
+
17
+ //#endregion
18
+ //#region \0@oxc-project+runtime@0.112.0/helpers/toPrimitive.js
19
+ function toPrimitive(t, r) {
20
+ if ("object" != _typeof(t) || !t) return t;
21
+ var e = t[Symbol.toPrimitive];
22
+ if (void 0 !== e) {
23
+ var i = e.call(t, r || "default");
24
+ if ("object" != _typeof(i)) return i;
25
+ throw new TypeError("@@toPrimitive must return a primitive value.");
26
+ }
27
+ return ("string" === r ? String : Number)(t);
28
+ }
29
+
30
+ //#endregion
31
+ //#region \0@oxc-project+runtime@0.112.0/helpers/toPropertyKey.js
32
+ function toPropertyKey(t) {
33
+ var i = toPrimitive(t, "string");
34
+ return "symbol" == _typeof(i) ? i : i + "";
35
+ }
36
+
37
+ //#endregion
38
+ //#region \0@oxc-project+runtime@0.112.0/helpers/defineProperty.js
39
+ function _defineProperty(e, r, t) {
40
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
41
+ value: t,
42
+ enumerable: !0,
43
+ configurable: !0,
44
+ writable: !0
45
+ }) : e[r] = t, e;
46
+ }
47
+
48
+ //#endregion
49
+ //#region src/core/registry.ts
50
+ const registry = (config) => {
51
+ return {
52
+ name: config.name,
53
+ render: config.render
54
+ };
55
+ };
56
+ var Registry = class {
57
+ constructor() {
58
+ _defineProperty(this, "items", []);
59
+ }
60
+ add(config) {
61
+ this.items.push(config);
62
+ return this;
63
+ }
64
+ get(key) {
65
+ const item = this.items.find((item) => item.name === key);
66
+ if (!item) throw new Error(`Item ${String(key)} not found`);
67
+ return item;
68
+ }
69
+ };
70
+
71
+ //#endregion
72
+ //#region src/core/builder.tsx
73
+ const HOOKS = ["beforeOpen", "beforeClose"];
74
+ var PortalBuilder = class PortalBuilder {
75
+ constructor(key, useFactoryStore, HubItemComponent, options = {}, extended = false) {
76
+ _defineProperty(this, "key", void 0);
77
+ _defineProperty(this, "t", void 0);
78
+ _defineProperty(this, "options", void 0);
79
+ _defineProperty(this, "RegistryComponent", void 0);
80
+ _defineProperty(this, "innerStore", void 0);
81
+ _defineProperty(this, "useFactoryStore", void 0);
82
+ _defineProperty(this, "extended", void 0);
83
+ _defineProperty(this, "getInnerStore", () => {
84
+ const innerStore = this.innerStore;
85
+ return () => innerStore;
86
+ });
87
+ _defineProperty(this, "view", (Component) => {
88
+ const key = this.key;
89
+ const t = this.t;
90
+ const RegistryComponent = this.RegistryComponent;
91
+ const useInnerContextHook = this.getInnerStore()();
92
+ const useFactoryStore = this.useFactoryStore;
93
+ return (props) => {
94
+ const isOpen = useFactoryStore((store) => store.states[key]);
95
+ const capitalize = key.charAt(0).toUpperCase() + key.slice(1);
96
+ const openChange = useFactoryStore((store) => store[`set${capitalize}`]);
97
+ const injectedProps = this.extended ? useInnerContextHook((state) => state._injectedProps) : void 0;
98
+ const options = this.parseOptions(this.options);
99
+ const innerStore = this.innerStore;
100
+ const close = useCallback(() => {
101
+ options?.beforeClose?.();
102
+ if (innerStore) innerStore.setState({ _injectedProps: void 0 });
103
+ openChange(false);
104
+ }, [
105
+ openChange,
106
+ options,
107
+ innerStore
108
+ ]);
109
+ const componentProps = {
110
+ ...injectedProps,
111
+ ...props,
112
+ close,
113
+ FooterButtons: t.In
114
+ };
115
+ if (this.extended) componentProps.useInnerContext = useInnerContextHook;
116
+ return /* @__PURE__ */ jsx(RegistryComponent, {
117
+ open: isOpen,
118
+ onOpenChange: openChange,
119
+ t,
120
+ ...options,
121
+ children: /* @__PURE__ */ jsx(Component, { ...componentProps })
122
+ });
123
+ };
124
+ });
125
+ _defineProperty(this, "trigger", ({ before, componentProps, ...props }) => {
126
+ const key = this.key;
127
+ const capitalize = key.charAt(0).toUpperCase() + key.slice(1);
128
+ const openChange = this.useFactoryStore((store) => store[`set${capitalize}`]);
129
+ const { safeProps, innerStoreValues } = useMemo(() => {
130
+ if (!this.innerStore) return {
131
+ safeProps: props,
132
+ innerStoreValues: void 0
133
+ };
134
+ const innerStoreDefaultValues = this.innerStore.getInitialState();
135
+ const storeKeys = Object.keys(innerStoreDefaultValues);
136
+ const safeProps = {};
137
+ const innerStoreValues = { ...innerStoreDefaultValues };
138
+ for (const key in props) if (Object.prototype.hasOwnProperty.call(props, key)) if (!storeKeys.includes(key)) safeProps[key] = props[key];
139
+ else innerStoreValues[key] = props[key];
140
+ return {
141
+ safeProps,
142
+ innerStoreValues
143
+ };
144
+ }, [props]);
145
+ const handleClick = () => {
146
+ const portalStore = this.innerStore;
147
+ const options = this.parseOptions(this.options);
148
+ const innerStore = portalStore?.getState();
149
+ options?.beforeOpen?.();
150
+ if (portalStore) {
151
+ const stateUpdate = {
152
+ ...innerStoreValues,
153
+ _injectedProps: componentProps ?? void 0
154
+ };
155
+ portalStore.setState(stateUpdate);
156
+ }
157
+ before?.(innerStore);
158
+ openChange(true);
159
+ };
160
+ return /* @__PURE__ */ jsx(Slot, {
161
+ onClick: handleClick,
162
+ ...safeProps
163
+ });
164
+ });
165
+ this.key = key;
166
+ this.t = tunnel();
167
+ this.options = options;
168
+ this.RegistryComponent = HubItemComponent;
169
+ this.useFactoryStore = useFactoryStore;
170
+ this.extended = extended;
171
+ }
172
+ configure(options) {
173
+ const newBuilder = new PortalBuilder(this.key, this.useFactoryStore, this.RegistryComponent, {
174
+ ...this.options,
175
+ ...options
176
+ }, this.extended);
177
+ newBuilder.t = this.t;
178
+ newBuilder.innerStore = this.innerStore;
179
+ return newBuilder;
180
+ }
181
+ extend(storeCreator) {
182
+ const newBuilder = new PortalBuilder(this.key, this.useFactoryStore, this.RegistryComponent, this.options, true);
183
+ newBuilder.t = this.t;
184
+ newBuilder.innerStore = create()((set, get) => ({ ...storeCreator(set, get) }));
185
+ return newBuilder;
186
+ }
187
+ get useInnerContext() {
188
+ return this.getInnerStore();
189
+ }
190
+ parseOptions(options) {
191
+ const innerStore = this.innerStore;
192
+ return Object.fromEntries(Object.entries(options).map(([key, value]) => {
193
+ const state = innerStore?.getState() || {};
194
+ if (typeof value === "function") {
195
+ if (HOOKS.includes(key)) {
196
+ const fn = (store, storeApi) => {
197
+ return () => value(store, storeApi);
198
+ };
199
+ return [key, fn(state, innerStore)];
200
+ }
201
+ return [key, value(state)];
202
+ }
203
+ return [key, value];
204
+ }));
205
+ }
206
+ };
207
+
208
+ //#endregion
209
+ //#region src/core/store.tsx
210
+ var Store = class {
211
+ constructor(keys, withProvider = false) {
212
+ _defineProperty(this, "factoryStore", void 0);
213
+ _defineProperty(this, "FactoryContext", void 0);
214
+ _defineProperty(this, "keys", void 0);
215
+ _defineProperty(this, "withProvider", void 0);
216
+ _defineProperty(this, "createProvider", () => {
217
+ if (!this.FactoryContext) throw new Error("FactoryContext is not defined");
218
+ const createStore = this.createFactoryStore;
219
+ const Context = this.FactoryContext;
220
+ const Provider = ({ children }) => {
221
+ const storeRef = useRef(null);
222
+ if (!storeRef.current) storeRef.current = createStore();
223
+ const store = storeRef.current;
224
+ return /* @__PURE__ */ jsxs(Context.Provider, {
225
+ value: store,
226
+ children: [
227
+ " ",
228
+ children,
229
+ " "
230
+ ]
231
+ });
232
+ };
233
+ return Provider;
234
+ });
235
+ _defineProperty(this, "getStore", () => {
236
+ if (this.withProvider) return this.getStoreHook();
237
+ return this.factoryStore;
238
+ });
239
+ _defineProperty(this, "getStoreHook", () => {
240
+ if (!this.FactoryContext) throw new Error("FactoryContext is not defined");
241
+ const FactoryContext = this.FactoryContext;
242
+ return function useStore_(selector) {
243
+ const store = useContext(FactoryContext);
244
+ if (!store) throw new Error("useStore must be used within a Provider");
245
+ return useStore(store, selector);
246
+ };
247
+ });
248
+ this.keys = keys;
249
+ this.withProvider = withProvider;
250
+ if (withProvider) this.FactoryContext = createContext(null);
251
+ else this.factoryStore = this.createFactoryStore();
252
+ }
253
+ createFactoryStore() {
254
+ return create()((set) => {
255
+ const states = {};
256
+ for (const key of this.keys) states[key] = false;
257
+ const setters = {};
258
+ for (const key of this.keys) {
259
+ const setterKey = `set${key.charAt(0).toUpperCase() + key.slice(1)}`;
260
+ setters[setterKey] = ((value) => set((state) => ({
261
+ ...state,
262
+ states: {
263
+ ...state.states,
264
+ [key]: value
265
+ }
266
+ })));
267
+ }
268
+ return {
269
+ states,
270
+ ...setters
271
+ };
272
+ });
273
+ }
274
+ };
275
+
276
+ //#endregion
277
+ //#region src/core/overkit.tsx
278
+ var Overkit = class extends Store {
279
+ constructor(keys) {
280
+ super(keys);
281
+ _defineProperty(this, "registry", void 0);
282
+ this.registry = new Registry();
283
+ }
284
+ create(key, hubItemName) {
285
+ const RegistryComponent = this.registry.get(hubItemName).render;
286
+ return new PortalBuilder(key, this.useOverkitStore, RegistryComponent);
287
+ }
288
+ get useOverkitStore() {
289
+ return this.getStore();
290
+ }
291
+ with(item) {
292
+ this.registry.add(item);
293
+ return this;
294
+ }
295
+ build() {
296
+ return {
297
+ create: this.create.bind(this),
298
+ useOverkitStore: this.useOverkitStore
299
+ };
300
+ }
301
+ };
302
+
303
+ //#endregion
304
+ export { Overkit, registry };
305
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/core/registry.ts","../src/core/builder.tsx","../src/core/store.tsx","../src/core/overkit.tsx"],"sourcesContent":["import type React from 'react';\r\nimport type { RegistryComponentProps, InitViewProps } from '../types';\r\nexport type { RegistryComponentProps }\r\n\r\n\r\nexport interface RegistryItem<\r\n Key extends string = string,\r\n OtherProps extends object = object\r\n> {\r\n name: Key;\r\n render: (\r\n opt: RegistryComponentProps & InitViewProps<OtherProps>\r\n ) => React.ReactElement | null\r\n}\r\n\r\nexport const registry = <\r\n Key extends string = string,\r\n ItemProps extends object = object\r\n>(\r\n config: RegistryItem<Key, ItemProps>\r\n): RegistryItem<Key, ItemProps> => {\r\n return {\r\n name: config.name,\r\n render: config.render,\r\n };\r\n};\r\n\r\n\r\nexport type RegistryItemMap = Record<string, RegistryItem<any, any>>;\r\n\r\nexport class Registry<\r\n Items extends RegistryItemMap = Record<string, never>\r\n> {\r\n private items: RegistryItem<string, object>[] = [];\r\n\r\n add<Key extends string, ItemProps extends object = object>(\r\n config: RegistryItem<Key, ItemProps>\r\n ): Registry<Items & Record<Key, RegistryItem<Key, ItemProps>>> {\r\n this.items.push(config as unknown as RegistryItem<string, object>);\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n return this as any as Registry<\r\n Items & Record<Key, RegistryItem<Key, ItemProps>>\r\n >;\r\n }\r\n\r\n get<Key extends keyof Items>(key: Key): Items[Key] {\r\n const item = this.items.find((item) => item.name === key);\r\n if (!item) throw new Error(`Item ${String(key)} not found`);\r\n return item as Items[Key];\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { Slot } from \"@radix-ui/react-slot\";\r\nimport type React from \"react\";\r\nimport { useCallback, useMemo } from \"react\";\r\nimport tunnel from \"tunnel-rat\";\r\nimport { create, type StoreApi, type UseBoundStore } from \"zustand\";\r\n\r\nimport type {\r\n _SharedProps,\r\n Capitalize,\r\n FactoryStore,\r\n RegistryComponentProps,\r\n InitViewProps,\r\n} from \"../types\";\r\n\r\ntype ViewProps<TProps extends object> = TProps & {\r\n close: () => void;\r\n FooterButtons: ReturnType<typeof tunnel>[\"In\"];\r\n};\r\n\r\ntype ExtendedState<T> = T & {\r\n _internal?: any;\r\n\r\n _injectedProps?: Record<string, any>;\r\n};\r\n\r\ntype UseInnerContextHook<TState> = <TSelected = TState>(\r\n selector?: (state: TState) => TSelected,\r\n) => TSelected;\r\n\r\ntype ValueProperties<T> = {\r\n [K in keyof T as T[K] extends (...args: any[]) => any ? never : K]: T[K];\r\n};\r\n\r\nconst HOOKS = [\"beforeOpen\", \"beforeClose\"];\r\n\r\nexport class PortalBuilder<\r\n TKeys extends readonly string[],\r\n TKey extends TKeys[number],\r\n TExtendedProps extends object = object,\r\n TExtendedState extends object = object,\r\n Extended extends boolean = false,\r\n> {\r\n private key: TKey;\r\n private t: ReturnType<typeof tunnel>;\r\n private options: InitViewProps<TExtendedProps>;\r\n private RegistryComponent: React.ComponentType<RegistryComponentProps>;\r\n private innerStore?: UseBoundStore<StoreApi<ExtendedState<TExtendedState>>>;\r\n private useFactoryStore: UseBoundStore<StoreApi<FactoryStore<TKeys>>>;\r\n private extended: boolean;\r\n\r\n constructor(\r\n key: TKey,\r\n useFactoryStore: UseBoundStore<StoreApi<FactoryStore<TKeys>>>,\r\n HubItemComponent: React.ComponentType<RegistryComponentProps>,\r\n options: InitViewProps<TExtendedProps> = {} as InitViewProps<TExtendedProps>,\r\n extended: Extended = false as Extended,\r\n ) {\r\n this.key = key;\r\n this.t = tunnel();\r\n this.options = options;\r\n this.RegistryComponent = HubItemComponent;\r\n this.useFactoryStore = useFactoryStore;\r\n this.extended = extended;\r\n }\r\n\r\n configure(\r\n options: InitViewProps<TExtendedProps, Extended extends true ? TExtendedState : never>,\r\n ): PortalBuilder<TKeys, TKey, TExtendedProps, TExtendedState, Extended> {\r\n const newBuilder = new PortalBuilder<TKeys, TKey, TExtendedProps, TExtendedState, Extended>(\r\n this.key,\r\n this.useFactoryStore,\r\n this.RegistryComponent,\r\n { ...this.options, ...options },\r\n this.extended as Extended,\r\n );\r\n newBuilder.t = this.t;\r\n newBuilder.innerStore = this.innerStore;\r\n\r\n return newBuilder;\r\n }\r\n\r\n extend<TNewState extends object>(\r\n storeCreator: (\r\n set: StoreApi<ExtendedState<TNewState>>[\"setState\"],\r\n get: StoreApi<ExtendedState<TNewState>>[\"getState\"],\r\n ) => TNewState,\r\n ): PortalBuilder<TKeys, TKey, TExtendedProps, TNewState, true> {\r\n const newBuilder = new PortalBuilder<TKeys, TKey, TExtendedProps, TNewState, true>(\r\n this.key,\r\n this.useFactoryStore,\r\n this.RegistryComponent,\r\n this.options,\r\n true,\r\n );\r\n newBuilder.t = this.t;\r\n\r\n newBuilder.innerStore = create<ExtendedState<TNewState>>()((set, get) => ({\r\n ...storeCreator(set, get),\r\n }));\r\n\r\n // TODO: omit extended state from newBuilder\r\n return newBuilder;\r\n }\r\n\r\n private getInnerStore = () => {\r\n const innerStore = this.innerStore;\r\n\r\n return () => innerStore!;\r\n };\r\n\r\n get useInnerContext(): Extended extends true ? UseInnerContextHook<TExtendedState> : never {\r\n return this.getInnerStore() as Extended extends true\r\n ? UseInnerContextHook<TExtendedState>\r\n : never;\r\n }\r\n\r\n private parseOptions(options: InitViewProps<TExtendedProps>): _SharedProps<TExtendedProps> {\r\n const innerStore = this.innerStore;\r\n\r\n const parsedOptions = Object.fromEntries(\r\n Object.entries(options).map(([key, value]) => {\r\n const state = innerStore?.getState() || ({} as TExtendedState);\r\n if (typeof value === \"function\") {\r\n const isHook = HOOKS.includes(key);\r\n if (isHook) {\r\n const fn = (store?: TExtendedState, storeApi?: StoreApi<TExtendedState>) => {\r\n return () =>\r\n (value as (store?: TExtendedState, storeApi?: StoreApi<TExtendedState>) => void)(\r\n store,\r\n storeApi,\r\n );\r\n };\r\n return [key, fn(state, innerStore)];\r\n }\r\n const resolvedValue = value(state);\r\n return [key, resolvedValue];\r\n }\r\n return [key, value];\r\n }),\r\n ) as _SharedProps<TExtendedProps>;\r\n\r\n return parsedOptions;\r\n }\r\n\r\n view = <TProps extends object = object>(\r\n Component: React.ComponentType<\r\n ViewProps<\r\n TProps &\r\n (Extended extends true\r\n ? {\r\n useInnerContext: UseInnerContextHook<TExtendedState>;\r\n }\r\n : object)\r\n >\r\n >,\r\n ): React.FC<TProps> => {\r\n const key = this.key;\r\n const t = this.t;\r\n\r\n const RegistryComponent = this.RegistryComponent;\r\n const useInnerContextHook = this.getInnerStore()();\r\n const useFactoryStore = this.useFactoryStore;\r\n\r\n return (props: TProps) => {\r\n const isOpen = useFactoryStore((store) => store.states[key]);\r\n const capitalize = (key.charAt(0).toUpperCase() + key.slice(1)) as Capitalize<TKey>;\r\n const openChange = useFactoryStore(\r\n (store) => store[`set${capitalize}` as keyof typeof store] as (value: boolean) => void,\r\n );\r\n\r\n const injectedProps = this.extended\r\n ? useInnerContextHook((state) => state._injectedProps)\r\n : undefined;\r\n\r\n const options = this.parseOptions(this.options);\r\n\r\n const innerStore = this.innerStore;\r\n\r\n const close = useCallback(() => {\r\n options?.beforeClose?.();\r\n // Clear injected props when closing\r\n if (innerStore) {\r\n innerStore.setState({ _injectedProps: undefined } as Partial<\r\n ExtendedState<TExtendedState>\r\n >);\r\n }\r\n openChange(false);\r\n }, [openChange, options, innerStore]);\r\n\r\n const componentProps: any = {\r\n ...injectedProps,\r\n ...props,\r\n close,\r\n FooterButtons: t.In,\r\n };\r\n\r\n if (this.extended) {\r\n componentProps.useInnerContext = useInnerContextHook;\r\n }\r\n\r\n return (\r\n <RegistryComponent open={isOpen} onOpenChange={openChange} t={t} {...options}>\r\n <Component {...componentProps} />\r\n </RegistryComponent>\r\n );\r\n };\r\n };\r\n\r\n trigger = <THubComponentProps extends object = object, TProps extends object = object>({\r\n before,\r\n componentProps,\r\n ...props\r\n }: TProps & {\r\n before?: (innerStore?: TExtendedState) => void;\r\n componentProps?: Partial<THubComponentProps>;\r\n children?: React.ReactNode;\r\n } & ValueProperties<TExtendedState>) => {\r\n const key = this.key;\r\n const capitalize = (key.charAt(0).toUpperCase() + key.slice(1)) as Capitalize<TKey>;\r\n\r\n const openChange = this.useFactoryStore(\r\n (store) => store[`set${capitalize}` as keyof typeof store] as (value: boolean) => void,\r\n );\r\n\r\n // eslint-disable-next-line react-hooks/rules-of-hooks\r\n const { safeProps, innerStoreValues } = useMemo(() => {\r\n // return safeProps values that is included in this.innerStore.getInitialState()\r\n const portalStore = this.innerStore;\r\n\r\n if (!portalStore) return { safeProps: props, innerStoreValues: undefined };\r\n const innerStoreDefaultValues = this.innerStore!.getInitialState();\r\n const storeKeys = Object.keys(innerStoreDefaultValues);\r\n\r\n const safeProps: Record<string, unknown> = {};\r\n const innerStoreValues: Partial<TExtendedState> = {\r\n ...innerStoreDefaultValues,\r\n };\r\n\r\n for (const key in props) {\r\n if (Object.prototype.hasOwnProperty.call(props, key)) {\r\n if (!storeKeys.includes(key)) {\r\n safeProps[key] = (props as Record<string, unknown>)[key];\r\n } else {\r\n innerStoreValues[key as keyof TExtendedState] = (props as TExtendedState)[\r\n key as keyof TExtendedState\r\n ];\r\n }\r\n }\r\n }\r\n\r\n return { safeProps, innerStoreValues };\r\n }, [props]);\r\n\r\n const handleClick = () => {\r\n const portalStore = this.innerStore;\r\n const options = this.parseOptions(this.options);\r\n const innerStore = portalStore?.getState();\r\n\r\n options?.beforeOpen?.();\r\n\r\n if (portalStore) {\r\n const stateUpdate = {\r\n ...innerStoreValues,\r\n _injectedProps: (componentProps as any) ?? undefined,\r\n } as Partial<ExtendedState<TExtendedState>>;\r\n\r\n portalStore.setState(stateUpdate);\r\n }\r\n\r\n before?.(innerStore);\r\n openChange(true);\r\n };\r\n\r\n return <Slot onClick={handleClick} {...safeProps} />;\r\n };\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport type React from \"react\";\r\nimport { createContext, useContext, useRef } from \"react\";\r\n\r\nimport { create, type StoreApi, type UseBoundStore, useStore } from \"zustand\";\r\nimport type { FactoryStore, StoreSetters, StoreStates } from \"../types\";\r\n\r\nexport class Store<TKeys extends readonly string[]> {\r\n private factoryStore: UseBoundStore<StoreApi<FactoryStore<TKeys>>> | undefined;\r\n private FactoryContext: React.Context<UseBoundStore<StoreApi<FactoryStore<TKeys>>>> | undefined;\r\n private keys: TKeys;\r\n private withProvider?: boolean;\r\n constructor(keys: TKeys, withProvider = false) {\r\n this.keys = keys;\r\n this.withProvider = withProvider;\r\n\r\n if (withProvider) {\r\n this.FactoryContext = createContext<UseBoundStore<StoreApi<FactoryStore<TKeys>>>>(\r\n null as unknown as UseBoundStore<StoreApi<FactoryStore<TKeys>>>,\r\n );\r\n } else {\r\n this.factoryStore = this.createFactoryStore();\r\n }\r\n }\r\n\r\n private createFactoryStore() {\r\n return create<FactoryStore<TKeys>>()((set) => {\r\n const states = {} as StoreStates<TKeys>;\r\n for (const key of this.keys) {\r\n states[key as TKeys[number]] = false;\r\n }\r\n\r\n const setters = {} as StoreSetters<TKeys>;\r\n for (const key of this.keys) {\r\n const capitalizedKey = (key.charAt(0).toUpperCase() + key.slice(1)) as Capitalize<\r\n TKeys[number]\r\n >;\r\n const setterKey = `set${capitalizedKey}` as keyof StoreSetters<TKeys>;\r\n\r\n setters[setterKey] = ((value: boolean) =>\r\n set((state) => ({\r\n ...state,\r\n states: { ...state.states, [key]: value },\r\n }))) as any;\r\n }\r\n\r\n return {\r\n states,\r\n ...setters,\r\n };\r\n });\r\n }\r\n\r\n public createProvider = () => {\r\n if (!this.FactoryContext) {\r\n throw new Error(\"FactoryContext is not defined\");\r\n }\r\n\r\n const createStore = this.createFactoryStore;\r\n const Context = this.FactoryContext!;\r\n\r\n const Provider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\r\n const storeRef = useRef<UseBoundStore<StoreApi<FactoryStore<TKeys>>> | null>(null);\r\n\r\n if (!storeRef.current) {\r\n storeRef.current = createStore();\r\n }\r\n\r\n const store = storeRef.current;\r\n\r\n return <Context.Provider value={store}> {children} </Context.Provider>;\r\n };\r\n\r\n return Provider;\r\n };\r\n\r\n public getStore = () => {\r\n if (this.withProvider) {\r\n return this.getStoreHook();\r\n }\r\n return this.factoryStore!;\r\n };\r\n\r\n private getStoreHook = () => {\r\n if (!this.FactoryContext) {\r\n throw new Error(\"FactoryContext is not defined\");\r\n }\r\n const FactoryContext = this.FactoryContext;\r\n\r\n return function useStore_<T>(selector: (state: FactoryStore<TKeys>) => T) {\r\n const store = useContext(FactoryContext);\r\n\r\n if (!store) {\r\n throw new Error(\"useStore must be used within a Provider\");\r\n }\r\n\r\n return useStore(store, selector);\r\n } as UseBoundStore<StoreApi<FactoryStore<TKeys>>>;\r\n };\r\n}\r\n","import type React from \"react\";\r\nimport { PortalBuilder } from \"./builder\";\r\nimport { Registry, type RegistryItem, type RegistryItemMap } from \"./registry\";\r\nimport { Store } from \"./store\";\r\nimport type { RegistryComponentProps } from \"../types\";\r\n\r\nexport class Overkit<\r\n TKeys extends readonly string[],\r\n Items extends RegistryItemMap = Record<string, never>,\r\n> extends Store<TKeys> {\r\n private registry: Registry<Items>;\r\n\r\n constructor(keys: TKeys) {\r\n super(keys);\r\n this.registry = new Registry<Items>();\r\n }\r\n\r\n private create<\r\n TKey extends TKeys[number],\r\n THubItemName extends keyof Items,\r\n ItemProps extends React.ComponentProps<Items[THubItemName][\"render\"]>,\r\n >(key: TKey, hubItemName: THubItemName) {\r\n const registryElement = this.registry.get(hubItemName);\r\n const RegistryComponent = registryElement.render;\r\n return new PortalBuilder<TKeys, TKey, Omit<ItemProps, keyof RegistryComponentProps>>(\r\n key,\r\n this.useOverkitStore,\r\n RegistryComponent,\r\n );\r\n }\r\n\r\n private get useOverkitStore() {\r\n return this.getStore();\r\n }\r\n\r\n with<THubItemName extends string, ItemProps extends object = object>(\r\n item: RegistryItem<THubItemName, ItemProps>,\r\n ): Overkit<TKeys, Items & Record<THubItemName, RegistryItem<THubItemName, ItemProps>>> {\r\n this.registry.add<THubItemName, ItemProps>(item);\r\n return this as Overkit<\r\n TKeys,\r\n Items & Record<THubItemName, RegistryItem<THubItemName, ItemProps>>\r\n >;\r\n }\r\n\r\n build() {\r\n return {\r\n create: this.create.bind(this),\r\n useOverkitStore: this.useOverkitStore,\r\n };\r\n }\r\n}\r\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "overkit",
3
+ "version": "0.0.2",
4
+ "description": "Simplified overlay management system for React",
5
+ "type": "module",
6
+ "main": "./dist/index.mjs",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.mts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.mts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.mjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsdown",
22
+ "test": "vitest",
23
+ "test:ui": "vitest --ui",
24
+ "test:run": "vitest run"
25
+ },
26
+ "keywords": [
27
+ "react",
28
+ "reactjs",
29
+ "overlay",
30
+ "modal",
31
+ "dialog",
32
+ "drawer",
33
+ "sheet",
34
+ "portal",
35
+ "zustand",
36
+ "state-management",
37
+ "typescript"
38
+ ],
39
+ "author": {
40
+ "name": "Jean Caiza",
41
+ "email": "jeanmcm@hotmail.com",
42
+ "url": "https://github.com/jfortez"
43
+ },
44
+ "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/jfortez/overkit.git",
48
+ "directory": "lib/overkit"
49
+ },
50
+ "bugs": {
51
+ "url": "https://github.com/jfortez/overkit/issues"
52
+ },
53
+ "homepage": "https://github.com/jfortez/overkit#readme",
54
+ "devDependencies": {
55
+ "@testing-library/jest-dom": "^6.9.1",
56
+ "@testing-library/react": "^16.0.0",
57
+ "@types/bun": "latest",
58
+ "@types/react": "^19.0.0",
59
+ "@types/react-dom": "^19.0.0",
60
+ "@vitejs/plugin-react": "^4.3.0",
61
+ "jsdom": "^25.0.0",
62
+ "tsdown": "^0.20.3",
63
+ "typescript": "^5.0.0",
64
+ "vitest": "^2.1.0"
65
+ },
66
+ "peerDependencies": {
67
+ "react": ">=18.0.0",
68
+ "react-dom": ">=18.0.0"
69
+ },
70
+ "dependencies": {
71
+ "zustand": "^5.0.0",
72
+ "@radix-ui/react-slot": "^1.1.0",
73
+ "tunnel-rat": "^0.1.0"
74
+ }
75
+ }