Compare commits
	
		
			2 commits
		
	
	
		
			a5f16cd3fc
			...
			60dfd776c6
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 60dfd776c6 | |||
| e7266d0ab6 | 
					 8 changed files with 923 additions and 756 deletions
				
			
		| 
						 | 
				
			
			@ -39,6 +39,7 @@ import {Await, useAsync} from "../src/Async";
 | 
			
		|||
import {NotifyErrorsBoundary} from "../src/Components/Errors/NotifyErrorsBoundary";
 | 
			
		||||
import {DemoFailingComponent, DemoResetComponent} from "./DemoFailingComponent";
 | 
			
		||||
import {Tip} from "../src/Components/Tips/Tip";
 | 
			
		||||
import {useKernelApplicationData} from "../src/KernelContext";
 | 
			
		||||
 | 
			
		||||
export function DemoApp()
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +74,8 @@ export function DemoApp()
 | 
			
		|||
 | 
			
		||||
	const [failingComponentsCount, setFailingComponentsCount] = useState(0);
 | 
			
		||||
 | 
			
		||||
	const [kernelApplicationData, setKernelApplicationData] = useKernelApplicationData("customData", "");
 | 
			
		||||
 | 
			
		||||
	return (
 | 
			
		||||
		<Application>
 | 
			
		||||
			<MainMenu>
 | 
			
		||||
| 
						 | 
				
			
			@ -609,6 +612,23 @@ export function DemoApp()
 | 
			
		|||
				</NotifyErrorsBoundary>
 | 
			
		||||
			</Card>
 | 
			
		||||
 | 
			
		||||
			<h2>
 | 
			
		||||
				Global states
 | 
			
		||||
			</h2>
 | 
			
		||||
 | 
			
		||||
			<Card>
 | 
			
		||||
				<label>
 | 
			
		||||
					Kernel application custom data
 | 
			
		||||
					<input type={"text"} name={"kernel-application-data"}
 | 
			
		||||
					       value={kernelApplicationData}
 | 
			
		||||
					       onChange={(event) => setKernelApplicationData(event.currentTarget.value)} />
 | 
			
		||||
				</label>
 | 
			
		||||
 | 
			
		||||
				<Buttons placement={"center"}>
 | 
			
		||||
					<button type={"button"} onClick={easySubapp}>Open demo subapp to see if it works</button>
 | 
			
		||||
				</Buttons>
 | 
			
		||||
			</Card>
 | 
			
		||||
 | 
			
		||||
		</Application>
 | 
			
		||||
	);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
import React from "react";
 | 
			
		||||
import {Subapp, useSubapp} from "../src/Components/Subapps/Subapps";
 | 
			
		||||
import {Card} from "../src/Components/Card";
 | 
			
		||||
import {useKernelApplicationData} from "../src/KernelContext";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A demo Subapp component.
 | 
			
		||||
| 
						 | 
				
			
			@ -10,6 +11,9 @@ export function DemoSubapp()
 | 
			
		|||
	// Get subapp close function.
 | 
			
		||||
	const {uuid, close} = useSubapp();
 | 
			
		||||
 | 
			
		||||
	// Get kernel application custom data.
 | 
			
		||||
	const [kernelApplicationData] = useKernelApplicationData("customData", "");
 | 
			
		||||
 | 
			
		||||
	return (
 | 
			
		||||
		<Subapp title={"My complex subapp"}>
 | 
			
		||||
			<Card>
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +21,8 @@ export function DemoSubapp()
 | 
			
		|||
 | 
			
		||||
				<p>UUID : <code>{uuid}</code></p>
 | 
			
		||||
 | 
			
		||||
				{kernelApplicationData && <p><strong>Kernel application data</strong>: <code>{kernelApplicationData}</code></p>}
 | 
			
		||||
 | 
			
		||||
				<button onClick={close}>Close the subapp</button>
 | 
			
		||||
			</Card>
 | 
			
		||||
		</Subapp>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								index.ts
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								index.ts
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -49,4 +49,5 @@ export * from "./src/Components/Tips/Tip";
 | 
			
		|||
 | 
			
		||||
export * from "./src/Async";
 | 
			
		||||
export * from "./src/GlobalState";
 | 
			
		||||
export * from "./src/KernelContext";
 | 
			
		||||
export * from "./src/Utils";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										14
									
								
								package.json
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								package.json
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
{
 | 
			
		||||
	"version": "1.7.1",
 | 
			
		||||
	"version": "1.8.0",
 | 
			
		||||
	"name": "@kernelui/core",
 | 
			
		||||
	"description": "Kernel UI Core.",
 | 
			
		||||
	"scripts": {
 | 
			
		||||
| 
						 | 
				
			
			@ -27,18 +27,18 @@
 | 
			
		|||
	},
 | 
			
		||||
	"devDependencies": {
 | 
			
		||||
		"@phosphor-icons/react": "^2.1.7",
 | 
			
		||||
		"@types/node": "^20.14.10",
 | 
			
		||||
		"@types/react": "^18.3.3",
 | 
			
		||||
		"@types/node": "^22.7.4",
 | 
			
		||||
		"@types/react": "^18.3.10",
 | 
			
		||||
		"@types/react-dom": "^18.3.0",
 | 
			
		||||
		"@types/uuid": "^10",
 | 
			
		||||
		"@vitejs/plugin-react": "^4.3.0",
 | 
			
		||||
		"less": "^4.2.0",
 | 
			
		||||
		"react": "^18.3.1",
 | 
			
		||||
		"react-dom": "^18.3.1",
 | 
			
		||||
		"react-router-dom": "^6.24.1",
 | 
			
		||||
		"typescript": "^5.4.5",
 | 
			
		||||
		"vite": "^5.2.11",
 | 
			
		||||
		"vite-plugin-dts": "^3.9.1"
 | 
			
		||||
		"react-router-dom": "^6.26.2",
 | 
			
		||||
		"typescript": "^5.6.2",
 | 
			
		||||
		"vite": "^5.4.8",
 | 
			
		||||
		"vite-plugin-dts": "^4.2.2"
 | 
			
		||||
	},
 | 
			
		||||
	"peerDependencies": {
 | 
			
		||||
		"@phosphor-icons/react": "^2.1.7",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ import React from "react";
 | 
			
		|||
import {createBrowserRouter, RouterProvider} from "react-router-dom";
 | 
			
		||||
import {CurtainsProvider} from "../Components/Curtains/Curtains";
 | 
			
		||||
import {NotificationsProvider} from "../Components/Notifications/Notifications";
 | 
			
		||||
import {KernelContextProvider} from "../KernelContext";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Main Kernel UI app component which initializes everything.
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +15,7 @@ export function Kernel({header, footer, router}: {
 | 
			
		|||
})
 | 
			
		||||
{
 | 
			
		||||
	return (
 | 
			
		||||
		<KernelContextProvider>
 | 
			
		||||
			<IconContext.Provider value={{
 | 
			
		||||
				size: "1em",
 | 
			
		||||
				weight: "bold",
 | 
			
		||||
| 
						 | 
				
			
			@ -26,5 +28,6 @@ export function Kernel({header, footer, router}: {
 | 
			
		|||
					</CurtainsProvider>
 | 
			
		||||
				</NotificationsProvider>
 | 
			
		||||
			</IconContext.Provider>
 | 
			
		||||
		</KernelContextProvider>
 | 
			
		||||
	);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										111
									
								
								src/KernelContext.tsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/KernelContext.tsx
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,111 @@
 | 
			
		|||
import React, {useCallback, useContext, useMemo, useState} from "react";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Application data setter function type.
 | 
			
		||||
 */
 | 
			
		||||
export type ApplicationDataSetter<IdentifierType extends string|symbol|number = string, ValueType = any> = (identifier: IdentifierType, value: ValueType) => void;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Application data dispatcher function type.
 | 
			
		||||
 */
 | 
			
		||||
export type KernelApplicationDataDispatcher<ValueType = any> = (value: ValueType) => void;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Kernel application data type.
 | 
			
		||||
 */
 | 
			
		||||
export type KernelApplicationData = Record<string, any>;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Kernel context data.
 | 
			
		||||
 */
 | 
			
		||||
export interface KernelContextData
 | 
			
		||||
{
 | 
			
		||||
	application: {
 | 
			
		||||
		data: KernelApplicationData;
 | 
			
		||||
		setData: ApplicationDataSetter;
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * React Kernel context.
 | 
			
		||||
 */
 | 
			
		||||
export const KernelContext = React.createContext<KernelContextData>({
 | 
			
		||||
	application: {
 | 
			
		||||
		data: {},
 | 
			
		||||
		setData: () => {},
 | 
			
		||||
	},
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Kernel context provider.
 | 
			
		||||
 */
 | 
			
		||||
export function KernelContextProvider({children}: React.PropsWithChildren<{}>)
 | 
			
		||||
{
 | 
			
		||||
	// Kernel application data initialization.
 | 
			
		||||
	const [kernelApplicationData, setKernelApplicationData] = useState<KernelApplicationData>({});
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Change application data function.
 | 
			
		||||
	 */
 | 
			
		||||
	const changeApplicationData = useCallback((applicationUpdate: Partial<KernelApplicationData>) => {
 | 
			
		||||
		setKernelApplicationData({
 | 
			
		||||
			...kernelApplicationData,
 | 
			
		||||
			...applicationUpdate,
 | 
			
		||||
		});
 | 
			
		||||
	}, [kernelApplicationData, setKernelApplicationData]);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Application data setter function.
 | 
			
		||||
	 */
 | 
			
		||||
	const applicationDataSetter = useCallback((identifier: string, data: any) => (
 | 
			
		||||
		changeApplicationData({
 | 
			
		||||
			[identifier]: data,
 | 
			
		||||
		})
 | 
			
		||||
	), [changeApplicationData]);
 | 
			
		||||
 | 
			
		||||
	// Initialize kernel context value.
 | 
			
		||||
	const kernelContextValue = useMemo<KernelContextData>(() => ({
 | 
			
		||||
		application: {
 | 
			
		||||
			data: kernelApplicationData,
 | 
			
		||||
			setData: applicationDataSetter,
 | 
			
		||||
		},
 | 
			
		||||
	}), [kernelApplicationData, applicationDataSetter]);
 | 
			
		||||
 | 
			
		||||
	return (
 | 
			
		||||
		<KernelContext.Provider value={kernelContextValue}>
 | 
			
		||||
			{children}
 | 
			
		||||
		</KernelContext.Provider>
 | 
			
		||||
	);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get kernel context data.
 | 
			
		||||
 */
 | 
			
		||||
export function useKernelContext(): KernelContextData
 | 
			
		||||
{
 | 
			
		||||
	return useContext(KernelContext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize or get kernel application data with given identifier.
 | 
			
		||||
 * @param identifier Application data identifier.
 | 
			
		||||
 * @param initialValue Application data initial value.
 | 
			
		||||
 */
 | 
			
		||||
export function useKernelApplicationData<T>(identifier: string, initialValue: T): [T, KernelApplicationDataDispatcher<T>]
 | 
			
		||||
{
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get kernel context.
 | 
			
		||||
	 */
 | 
			
		||||
	const kernelContext = useKernelContext();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Function to set application data.
 | 
			
		||||
	 */
 | 
			
		||||
	const setApplicationData = useCallback(
 | 
			
		||||
		(newValue: T) => kernelContext.application.setData(identifier, newValue),
 | 
			
		||||
		[kernelContext.application.setData]
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	// Return kernel application data.
 | 
			
		||||
	return [kernelContext.application.data?.[identifier] ?? initialValue, setApplicationData];
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -23,6 +23,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
 | 
			
		|||
		plugins: [
 | 
			
		||||
			react(),
 | 
			
		||||
			dts({
 | 
			
		||||
				rollupTypes: true,
 | 
			
		||||
				insertTypesEntry: true,
 | 
			
		||||
				exclude: ["demo", "node_modules"],
 | 
			
		||||
			}),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue