seqflow-js
Advanced tools
Comparing version 0.0.1-beta.18 to 0.0.1-beta.19
@@ -46,3 +46,3 @@ import { BrowserRouter, InMemoryRouter, NavigationEvent, Router } from './router'; | ||
*/ | ||
renderSync: (html: string | JSX.Element) => void; | ||
renderSync: (html: ChildrenType) => void; | ||
/** | ||
@@ -107,5 +107,5 @@ * Wait for multiple events to happen | ||
*/ | ||
createDOMElement(tagName: string, options?: { | ||
createDOMElement(tagName: string | SeqflowFunction<unknown>, options?: { | ||
[key: string]: string; | ||
}, ...children: ChildenType[]): Node; | ||
}, ...children: HTMLElement[]): Node; | ||
/** | ||
@@ -115,6 +115,11 @@ * Create a DOM Fragment element. It is used internally by the framework. | ||
createDOMFragment({ children, }: { | ||
children?: ChildenType[]; | ||
children?: ChildrenType; | ||
}): DocumentFragment; | ||
} | ||
export type SeqflowFunction<T> = (this: SeqflowFunctionContext, data: T) => Promise<void>; | ||
export type SeqflowFunctionData<T> = T & { | ||
children?: ChildrenType; | ||
}; | ||
export type SeqflowFunction<T> = ((this: SeqflowFunctionContext, data: SeqflowFunctionData<T>) => Promise<void>) & { | ||
tagName?: (props: T) => string; | ||
}; | ||
export interface ApplicationConfiguration { | ||
@@ -133,18 +138,15 @@ } | ||
export declare function start<Component extends SeqflowFunction<FirstComponentData>, FirstComponentData extends Record<string, any> & { | ||
children?: ChildenType[]; | ||
children?: ChildrenType; | ||
}>(root: HTMLElement, firstComponent: Component, componentOption: FirstComponentData | undefined, seqflowConfiguration: Partial<Omit<SeqflowConfiguration, "log"> & { | ||
log?: Partial<LogFunction>; | ||
}>): AbortController; | ||
type ChildenType = HTMLElement | HTMLElement[]; | ||
type ChildrenType = string | HTMLElement | HTMLElement[]; | ||
declare global { | ||
namespace JSX { | ||
type Element = HTMLElement | HTMLElement[]; | ||
type ARG<T = object> = T & { | ||
children?: ChildenType; | ||
}; | ||
type ElementType<T> = string | ((this: SeqflowFunctionContext, data?: Record<string, any>) => Promise<void>); | ||
type Element = HTMLElement; | ||
type ElementType = string | ((this: SeqflowFunctionContext, data?: SeqflowFunctionData<any>) => Promise<void>); | ||
type IntrinsicEl = Omit<{ | ||
[K in keyof HTMLElementTagNameMap]: Omit<Partial<{ | ||
[V in keyof HTMLElementTagNameMap[K]]: HTMLElementTagNameMap[K][V]; | ||
}>, "style"> & ARG<{ | ||
}>, "style"> & SeqflowFunctionData<{ | ||
style?: Partial<CSSStyleDeclaration> | string; | ||
@@ -157,3 +159,3 @@ onClick?: (ev: MouseEvent) => void; | ||
[V in keyof HTMLElementTagNameMap["input"]]: HTMLElementTagNameMap["input"][V]; | ||
}>, "style" | "list"> & ARG<{ | ||
}>, "style" | "list"> & SeqflowFunctionData<{ | ||
style?: Partial<CSSStyleDeclaration> | string; | ||
@@ -170,5 +172,5 @@ onClick?: (ev: MouseEvent) => void; | ||
onClick?: (ev: MouseEvent) => void; | ||
wrapperClass?: string; | ||
wrapperClass?: string | string[]; | ||
} | ||
} | ||
} |
{ | ||
"name": "seqflow-js", | ||
"version": "0.0.1-beta.18", | ||
"version": "0.0.1-beta.19", | ||
"description": "SeqFlow is a modern web framework that is designed to be simple and easy to use. It optimizes the development process by providing a simple and easy-to-understand API. It is a good choice for those who want to create web applications without the complexity of other frameworks.", | ||
@@ -11,9 +11,6 @@ "main": "./dist/index.mjs", | ||
"@testing-library/dom": "^10.0.0", | ||
"@types/css-modules": "^1.0.5", | ||
"@types/jsdom": "^21.1.6", | ||
"@vitest/coverage-v8": "^1.5.2", | ||
"depcheck": "^1.4.7", | ||
"jsdom": "^24.0.0", | ||
"npm-run-all": "^4.1.5", | ||
"tsd": "^0.31.0", | ||
"typedoc": "^0.25.13", | ||
"vite": "^5.2.10", | ||
@@ -45,4 +42,5 @@ "vite-plugin-dts": "^3.9.0", | ||
"biome:check": "biome check --apply src tests", | ||
"build": "vite build -c vite.config.js" | ||
"build": "vite build -c vite.config.js", | ||
"depcheck": "depcheck --ignores @vitest/coverage-v8 ." | ||
} | ||
} |
101
src/index.ts
@@ -60,3 +60,3 @@ import * as DomainsPackage from "./domains"; | ||
*/ | ||
renderSync: (html: string | JSX.Element) => void; | ||
renderSync: (html: ChildrenType) => void; | ||
/** | ||
@@ -134,5 +134,5 @@ * Wait for multiple events to happen | ||
createDOMElement( | ||
tagName: string, | ||
tagName: string | SeqflowFunction<unknown>, | ||
options?: { [key: string]: string }, | ||
...children: ChildenType[] | ||
...children: HTMLElement[] | ||
): Node; | ||
@@ -145,9 +145,14 @@ /** | ||
}: { | ||
children?: ChildenType[]; | ||
children?: ChildrenType; | ||
}): DocumentFragment; | ||
} | ||
export type SeqflowFunction<T> = ( | ||
export type SeqflowFunctionData<T> = T & { | ||
children?: ChildrenType; | ||
}; | ||
export type SeqflowFunction<T> = (( | ||
this: SeqflowFunctionContext, | ||
data: T, | ||
) => Promise<void>; | ||
data: SeqflowFunctionData<T>, | ||
) => Promise<void>) & { | ||
tagName?: (props: T) => string; | ||
}; | ||
@@ -172,3 +177,3 @@ // biome-ignore lint/suspicious/noEmptyInterface: This type is fulfilled by the user | ||
function startComponent<T extends { children?: ChildenType[]; key?: string }>( | ||
function startComponent<T extends { children?: ChildrenType; key?: string }>( | ||
parentContext: SeqflowFunctionContext, | ||
@@ -356,3 +361,3 @@ el: HTMLElement, | ||
this: SeqflowFunctionContext, | ||
{ children }: { children?: ChildenType[] }, | ||
{ children }: { children?: ChildrenType }, | ||
): DocumentFragment { | ||
@@ -367,6 +372,9 @@ this.app.log.debug({ | ||
} | ||
if (!Array.isArray(children)) { | ||
children = [children]; | ||
const cc: (HTMLElement | string)[] = []; | ||
if (Array.isArray(children)) { | ||
cc.push(...children); | ||
} else { | ||
cc.push(children); | ||
} | ||
const c = children.flat(Number.POSITIVE_INFINITY); | ||
const c = cc.flat(Number.POSITIVE_INFINITY); | ||
for (const child of c) { | ||
@@ -400,5 +408,5 @@ if (typeof child === "string") { | ||
this: SeqflowFunctionContext, | ||
tagName: string, | ||
tagName: string | SeqflowFunction<unknown>, | ||
options?: { [key: string]: unknown }, | ||
...children: ChildenType[] | ||
...children: HTMLElement[] | ||
): Node { | ||
@@ -413,2 +421,8 @@ this.app.log.debug({ | ||
for (const key in options) { | ||
// We allow `undefined` values for DX | ||
// If the value is `undefined`, we skip it | ||
if (options[key] === undefined) { | ||
continue; | ||
} | ||
if (key === "className") { | ||
@@ -500,2 +514,6 @@ el.setAttribute("class", options[key] as string); | ||
// If we use `<></>` syntax, the `tagName` is a function | ||
// But that function IS the `this.createDOMFragment` | ||
// I don't know how to type this, so I have to use `@ts-ignore` | ||
// @ts-ignore | ||
if (tagName === this.createDOMFragment) { | ||
@@ -510,3 +528,8 @@ return this.createDOMFragment({ children }); | ||
const wrapper = document.createElement("div"); | ||
let wrapperTagName = "div"; | ||
if (typeof tagName.tagName === "function") { | ||
wrapperTagName = tagName.tagName(opt); | ||
} | ||
const wrapper = document.createElement(wrapperTagName); | ||
componentChildren.push({ | ||
@@ -517,3 +540,11 @@ key: opt.key as string, | ||
if (opt.wrapperClass) { | ||
wrapper.classList.add(opt.wrapperClass as string); | ||
const wrapperClass: string[] = []; | ||
if (Array.isArray(opt.wrapperClass)) { | ||
wrapperClass.push(...opt.wrapperClass); | ||
} else { | ||
wrapperClass.push(...(opt.wrapperClass as string).split(" ")); | ||
} | ||
for (const c of wrapperClass) { | ||
wrapper.classList.add(c); | ||
} | ||
} | ||
@@ -533,3 +564,3 @@ | ||
}, | ||
renderSync(this: SeqflowFunctionContext, html: string | JSX.Element) { | ||
renderSync(this: SeqflowFunctionContext, html: ChildrenType) { | ||
if (typeof html === "string") { | ||
@@ -586,3 +617,3 @@ this._el.innerHTML = html; | ||
FirstComponentData extends Record<string, any> & { | ||
children?: ChildenType[]; | ||
children?: ChildrenType; | ||
}, | ||
@@ -659,3 +690,3 @@ >( | ||
options?: { [key: string]: string }, | ||
...children: ChildenType[] | ||
...children: HTMLElement[] | ||
): Node { | ||
@@ -675,3 +706,3 @@ const el = document.createElement(tagName); | ||
}, | ||
renderSync(html: string | JSX.Element) { | ||
renderSync(html: ChildrenType) { | ||
if (typeof html === "string") { | ||
@@ -682,3 +713,13 @@ this._el.innerHTML = html; | ||
this._el.innerHTML = ""; | ||
this._el.appendChild(html as Node); | ||
if (Array.isArray(html)) { | ||
for (const h of html) { | ||
if (typeof h === "string") { | ||
this._el.appendChild(document.createTextNode(h)); | ||
continue; | ||
} | ||
this._el.appendChild(h); | ||
} | ||
} else { | ||
this._el.appendChild(html); | ||
} | ||
}, | ||
@@ -762,3 +803,3 @@ }; | ||
type ChildenType = HTMLElement | HTMLElement[]; | ||
type ChildrenType = string | HTMLElement | HTMLElement[]; | ||
@@ -768,10 +809,6 @@ declare global { | ||
// The return type of <button /> | ||
type Element = HTMLElement | HTMLElement[]; | ||
type Element = HTMLElement; | ||
export type ARG<T = object> = T & { | ||
children?: ChildenType; | ||
}; | ||
// This is the type of the first parameter of the jsxFactory | ||
type ElementType<T> = | ||
type ElementType = | ||
| string | ||
@@ -781,3 +818,3 @@ | (( | ||
// biome-ignore lint/suspicious/noExplicitAny: We don't care about the component properties | ||
data?: Record<string, any>, | ||
data?: SeqflowFunctionData<any>, | ||
) => Promise<void>); | ||
@@ -793,3 +830,3 @@ | ||
> & | ||
ARG<{ | ||
SeqflowFunctionData<{ | ||
style?: Partial<CSSStyleDeclaration> | string; | ||
@@ -808,3 +845,3 @@ onClick?: (ev: MouseEvent) => void; | ||
> & | ||
ARG<{ | ||
SeqflowFunctionData<{ | ||
style?: Partial<CSSStyleDeclaration> | string; | ||
@@ -821,5 +858,5 @@ onClick?: (ev: MouseEvent) => void; | ||
onClick?: (ev: MouseEvent) => void; | ||
wrapperClass?: string; | ||
wrapperClass?: string | string[]; | ||
} | ||
} | ||
} |
{ | ||
"compilerOptions": { | ||
"strict": true, | ||
"lib": ["es2015", "dom"], | ||
"lib": ["ES2019", "DOM", "DOM.Iterable", "DOM.AsyncIterable"], | ||
"jsx": "react", | ||
@@ -6,0 +6,0 @@ "jsxFactory": "this.createDOMElement", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
358694
9
3626