@brandup/ui-app
v1.0.30
Published
Basic infrastructure framework for web applications.
Downloads
131
Readme
@brandup/ui-app
Lightweight, fast and extensible application framework. Full async support. Weight after minification is less than 10KB!
Installation
Install NPM package @brandup/ui-app.
npm i @brandup/ui-app
This package support TypeScript language.
Configure and run application
Configure your application with middlewares and run.
import { ApplicationBuilder } from "@brandup/ui-app";
import pages from "./middlewares/pages";
import "./styles.less";
// Customize application model
interface ExampleApplicationModel extends ApplicationModel {
}
// Customize application type
export class ExampleApplication extends Application<ExampleApplicationModel> {
}
const builder = new ApplicationBuilder<ExampleApplicationModel>();
builder
.useApp(ExampleApplication)
.useMiddleware(pages);
const appModel: ExampleApplicationModel = {};
const app = builder.build<ExampleApplicationModel>({ basePath: "/" }, appModel);
app.run({ /*optional context params*/ })
.then(context: StartContext => { })
.catch(reason => { });
Default HTMLElement of application is document.body
. Set custom element:
const appElement = document.getElementById("app")
app.run({ /*optional context params*/ }, appElement);
Navigation
Example links for application navigation app.nav({ url: "url" })
:
<a href="url" class="applink">text</a>
<button data-nav-url="url">text</button>
Replace current url app.nav({ url: "url", replace: true, scope: "replace scope" })
:
<a href="url" class="applink" data-nav-replace>text</a>
<a href="url" class="applink" data-nav-replace data-nav-scope="replace scope">text</a>
<button data-nav-url="url" data-nav-replace>text</button>
The element's click event will start a chain of navigate
method calls for all middleware.
During navigation and until it is completed, the loading
class is added to the element that started the navigation.
Submit form
<form class="appform">
<input type="text" name="value" />
</form>
The form's submit event will start a chain of submit
method calls for all middleware. Class appform
is required.
If the form method is GET
, then navigation with the form data will start.
Middlewares
Inject to application lifecycle event methods. Middleware methods are called one after another in the order in which they were registered in the ApplicationBuilder
.
class PagesMiddlewareImpl implements Middleware {
name = "pages"; // unique name of this middleware
start(context: StartContext<ExampleApplication>, next: MiddlewareNext) {
console.log("start");
// context.app - access to application members
// context.data - get or set context data
return next();
}
async loaded(context: StartContext<ExampleApplication>, next: MiddlewareNext) {
console.log("loaded");
return next();
}
async navigate(context: NavigateContext<ExampleApplication, PageNavigationData>, next: MiddlewareNext) {
if (context.replace)
location.replace(context.url);
else
location.assign(context.url);
return next();
}
async submit(context: SubmitContext<ExampleApplication>, next: MiddlewareNext) {
console.log("submit");
return next();
}
async stop(context: StopContext<ExampleApplication>, next: MiddlewareNext) {
console.log("stop");
return next();
}
}
/** External interface of middleware. */
export interface PagesMiddleware {
}
export default () => new PagesMiddlewareImpl();
Example SPA navigation middleware: example/src/frontend/middlewares/pages.ts
Access to middleware
Retrivie middleware by unique name:
const pages = app.middleware<PagesMiddleware>("pages");
Async execution
export class PagesMiddleware implements Middleware {
async navigate(context: NavigateContext, next: MiddlewareNext) {
// Exec before next middleware
await next();
// Exec after next middleware
}
}
Redirect navigation
export class AuthMiddleware implements Middleware {
async navigate(context: NavigateContext, next: MiddlewareNext) {
await context.redirect({ url: "url" });
}
async submit(context: SubmitContext, next: MiddlewareNext) {
await context.redirect({ url: "url" });
}
}
The redirect
method will always throw an exception with reason NAV_OVERIDE_ERROR
constant and end the current navigation.