Compare commits

...

11 commits
v1.6.1 ... main

Author SHA1 Message Date
989f1f04d2
Version 1.8.3 and update yarn.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-11-30 18:25:05 +01:00
7bbd04e47a
Fix icon position in headings.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-11-30 18:24:34 +01:00
4f2c5a5245
Version 1.8.2
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-11-29 18:13:10 +01:00
206d51e4cb
Update dependencies.
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline failed
2024-11-29 18:06:19 +01:00
43c0297b04
Transform kernel application data to kernel React-like contexts.
All checks were successful
ci/woodpecker/tag/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-09-29 10:10:50 +02:00
60dfd776c6
Add Kernel context and Kernel application data.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-09-29 00:11:04 +02:00
e7266d0ab6
Update dependencies and tweak library build configuration. 2024-09-29 00:09:30 +02:00
a5f16cd3fc
Add tip component to exported components.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-09-27 19:06:48 +02:00
6252ed3045
Add a tip component.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-09-27 19:04:12 +02:00
06b2b9f5e1
Set default alignment of buttons text to center.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-09-27 18:46:52 +02:00
33b1fa2002
Export fonts variables.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-09-26 10:48:15 +02:00
17 changed files with 1156 additions and 865 deletions

View file

@ -38,6 +38,9 @@ import {Box} from "../src/Components/Box";
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 {useKernelContext} from "../src/KernelGlobalContext";
import {KernelContext} from "./DemoKernelContext";
export function DemoApp()
{
@ -72,6 +75,8 @@ export function DemoApp()
const [failingComponentsCount, setFailingComponentsCount] = useState(0);
const [kernelContext, setKernelContext] = useKernelContext(KernelContext);
return (
<Application>
<MainMenu>
@ -163,6 +168,10 @@ export function DemoApp()
<Radio name={"radio-test"}>Radio box test</Radio>
<Radio name={"radio-test"}>Radio box test</Radio>
<Tip>
A tip component, very useful in forms which require some explanations.
</Tip>
<Select options={{
"a": "AAAAAA",
"b": "BBBBBB",
@ -604,6 +613,23 @@ export function DemoApp()
</NotifyErrorsBoundary>
</Card>
<h2>
Global states
</h2>
<Card>
<label>
Kernel context data
<input type={"text"} name={"kernel-context-data"}
value={kernelContext}
onChange={(event) => setKernelContext(event.currentTarget.value)} />
</label>
<Buttons placement={"center"}>
<button type={"button"} onClick={easySubapp}>Open demo subapp to see if it works</button>
</Buttons>
</Card>
</Application>
);
}

View file

@ -0,0 +1,6 @@
import {createKernelContext} from "../src/KernelGlobalContext";
/**
* Create kernel context.
*/
export const KernelContext = createKernelContext("");

View file

@ -1,6 +1,8 @@
import React from "react";
import {Subapp, useSubapp} from "../src/Components/Subapps/Subapps";
import {Card} from "../src/Components/Card";
import {useKernelContext} from "../src/KernelGlobalContext";
import {KernelContext} from "./DemoKernelContext";
/**
* A demo Subapp component.
@ -10,6 +12,9 @@ export function DemoSubapp()
// Get subapp close function.
const {uuid, close} = useSubapp();
// Get kernel context data.
const [kernelContext] = useKernelContext(KernelContext);
return (
<Subapp title={"My complex subapp"}>
<Card>
@ -17,6 +22,8 @@ export function DemoSubapp()
<p>UUID : <code>{uuid}</code></p>
{kernelContext && <p><strong>Kernel context data</strong>: <code>{kernelContext}</code></p>}
<button onClick={close}>Close the subapp</button>
</Card>
</Subapp>

View file

@ -45,7 +45,9 @@ export * from "./src/Components/Select/Suggestible";
export * from "./src/Components/Steps/Steps";
export * from "./src/Components/Steps/StepsContext";
export * from "./src/Components/Subapps/Subapps";
export * from "./src/Components/Tips/Tip";
export * from "./src/Async";
export * from "./src/GlobalState";
export * from "./src/KernelGlobalContext";
export * from "./src/Utils";

View file

@ -1,5 +1,5 @@
{
"version": "1.6.1",
"version": "1.8.3",
"name": "@kernelui/core",
"description": "Kernel UI Core.",
"scripts": {
@ -27,24 +27,24 @@
},
"devDependencies": {
"@phosphor-icons/react": "^2.1.7",
"@types/node": "^20.14.10",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/node": "^22.7.4",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/uuid": "^10",
"@vitejs/plugin-react": "^4.3.0",
"@vitejs/plugin-react": "^4.3.4",
"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": "^7.0.1",
"typescript": "^5.6.2",
"vite": "^6.0.1",
"vite-plugin-dts": "^4.3.0"
},
"peerDependencies": {
"@phosphor-icons/react": "^2.1.7",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.24.1"
"react-router-dom": "^7.0.1"
},
"packageManager": "yarn@4.5.0"
"packageManager": "yarn@4.5.3"
}

View file

@ -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 {KernelGlobalContextProvider} from "../KernelGlobalContext";
/**
* Main Kernel UI app component which initializes everything.
@ -14,17 +15,19 @@ export function Kernel({header, footer, router}: {
})
{
return (
<IconContext.Provider value={{
size: "1em",
weight: "bold",
}}>
<NotificationsProvider>
<CurtainsProvider>
{header}
<RouterProvider router={router} />
{footer}
</CurtainsProvider>
</NotificationsProvider>
</IconContext.Provider>
<KernelGlobalContextProvider>
<IconContext.Provider value={{
size: "1em",
weight: "bold",
}}>
<NotificationsProvider>
<CurtainsProvider>
{header}
<RouterProvider router={router} />
{footer}
</CurtainsProvider>
</NotificationsProvider>
</IconContext.Provider>
</KernelGlobalContextProvider>
);
}

View file

@ -0,0 +1,17 @@
import React from "react";
import {classes} from "../../Utils";
import {Info} from "@phosphor-icons/react";
/**
* Simple text tip component.
*/
export function Tip({className, children, ...props}: React.PropsWithChildren<React.HTMLAttributes<HTMLParagraphElement>>)
{
return (
<p className={classes("tip", className)} {...props}>
<Info weight={"duotone"} />
{children}
</p>
);
}

133
src/KernelGlobalContext.tsx Normal file
View file

@ -0,0 +1,133 @@
import React, {useCallback, useContext, useMemo, useState} from "react";
import {v4 as uuidv4} from "uuid";
/**
* Create Kernel context.
* @param defaultValue Kernel context default value.
*/
export function createKernelContext<T>(defaultValue: T): KernelContext<T>
{
return {
uuid: uuidv4(),
defaultValue: defaultValue,
};
}
/**
* Kernel context definition object.
*/
export interface KernelContext<T>
{
/**
* Kernel context UUID.
*/
uuid: string;
/**
* Kernel context default value.
*/
defaultValue: T;
}
/**
* Kernel context setter function type.
*/
export type KernelContextSetter<IdentifierType extends string|symbol|number = string, ValueType = any> = (identifier: IdentifierType, value: ValueType) => void;
/**
* Kernel contexts type.
*/
export type KernelContexts = Record<string, any>;
/**
* Kernel context dispatcher function type.
*/
export type KernelContextDispatcher<ValueType = any> = (value: ValueType) => void;
/**
* Kernel global context data.
*/
export interface KernelGlobalContextData
{
contexts: KernelContexts;
setContext: KernelContextSetter;
}
/**
* React Kernel global context.
*/
export const KernelGlobalContext = React.createContext<KernelGlobalContextData>({
contexts: {},
setContext: () => {},
});
/**
* Kernel global context provider.
*/
export function KernelGlobalContextProvider({children}: React.PropsWithChildren<{}>)
{
// Kernel contexts initialization.
const [kernelContexts, setKernelContexts] = useState<KernelContexts>({});
/**
* Change kernel contexts.
*/
const changeKernelContexts = useCallback((kernelContextsUpdate: Partial<KernelContexts>) => {
setKernelContexts({
...kernelContexts,
...kernelContextsUpdate,
});
}, [kernelContexts, setKernelContexts]);
/**
* Kernel context setter function.
*/
const kernelContextSetter = useCallback((identifier: string, data: any) => (
changeKernelContexts({
[identifier]: data,
})
), [changeKernelContexts]);
// Initialize kernel global context value.
const kernelContextValue = useMemo<KernelGlobalContextData>(() => ({
contexts: kernelContexts,
setContext: kernelContextSetter,
}), [kernelContexts, kernelContextSetter]);
return (
<KernelGlobalContext.Provider value={kernelContextValue}>
{children}
</KernelGlobalContext.Provider>
);
}
/**
* Get kernel global context data.
*/
function useKernelGlobalContext(): KernelGlobalContextData
{
return useContext(KernelGlobalContext);
}
/**
* Initialize or get kernel context with given identifier.
* @param context Context object.
*/
export function useKernelContext<T>(context: KernelContext<T>): [T, KernelContextDispatcher<T>]
{
/**
* Get kernel global context.
*/
const kernelGlobalContext = useKernelGlobalContext();
/**
* Function to set kernel context.
*/
const setContext = useCallback(
(newValue: T) => kernelGlobalContext.setContext(context.uuid, newValue),
[kernelGlobalContext.setContext],
);
// Return kernel context and its dispatcher.
return [kernelGlobalContext.contexts?.[context.uuid] ?? context.defaultValue, setContext];
}

View file

@ -7,13 +7,13 @@ html, body
html, body, input, button, textarea
{
font-size: 1em;
font-family: @sans-serif-fonts;
font-family: var(--sans-serif-fonts);
font-weight: 500;
}
pre, code
{
font-family: @monospace-fonts;
font-family: var(--monospace-fonts);
}
body

View file

@ -20,3 +20,4 @@
@import "components/_steps-counter";
@import "components/_subapp";
@import "components/_table";
@import "components/_tip";

View file

@ -2,6 +2,13 @@
@import "@fontsource-variable/source-serif-4";
@import "@fontsource-variable/jetbrains-mono";
@sans-serif-fonts: "Manrope Variable", sans-serif;
@serif-fonts: "Source Serif 4 Variable", serif;
@monospace-fonts: "Jetbrains Mono Variable", monospace;
:root
{
@sans-serif-fonts: "Manrope Variable", sans-serif;
@serif-fonts: "Source Serif 4 Variable", serif;
@monospace-fonts: "Jetbrains Mono Variable", monospace;
--sans-serif-fonts: @sans-serif-fonts;
--serif-fonts: @serif-fonts;
--monospace-fonts: @monospace-fonts;
}

View file

@ -20,6 +20,7 @@ a.button, button, input[type="submit"], input[type="reset"]
font-weight: 600;
text-decoration: none;
vertical-align: middle;
text-align: center;
cursor: pointer;

View file

@ -4,6 +4,12 @@ h1, h2, h3, h4, h5, h6
&.center, &.main
{ text-align: center; }
> svg
{
position: relative;
bottom: -0.15em;
}
}
h1

View file

@ -13,7 +13,7 @@
color: var(--primary);
font-family: @monospace-fonts;
font-family: var(--monospace-fonts);
font-size: 1.5em;
font-weight: 700;
vertical-align: baseline;

View file

@ -0,0 +1,28 @@
p.tip
{
position: relative;
margin: auto;
width: 30em;
padding: 0.3em 0.5em 0.3em 3em;
border-radius: 0.3em;
box-sizing: border-box;
border: solid var(--background-darkest) thin;
color: var(--foreground-lightest);
svg
{
position: absolute;
top: 0.3em;
left: 0.5em;
display: inline-block;
margin: 0;
color: var(--primary);
font-size: 1.5em;
vertical-align: middle;
}
}

View file

@ -23,6 +23,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
plugins: [
react(),
dts({
rollupTypes: true,
insertTypesEntry: true,
exclude: ["demo", "node_modules"],
}),

1725
yarn.lock

File diff suppressed because it is too large Load diff