Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/lideming/webfx
My Web UI Framework
https://github.com/lideming/webfx
javascript javascript-framework javascript-library jsx typescript webfx
Last synced: 26 days ago
JSON representation
My Web UI Framework
- Host: GitHub
- URL: https://github.com/lideming/webfx
- Owner: lideming
- License: mit
- Created: 2020-03-30T23:37:06.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-11-01T00:40:20.000Z (about 1 year ago)
- Last Synced: 2024-10-10T07:30:56.933Z (27 days ago)
- Topics: javascript, javascript-framework, javascript-library, jsx, typescript, webfx
- Language: TypeScript
- Homepage: https://webfx.yuuza.net
- Size: 1.22 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Webfx
Web UI framework and utilities.
It was originally created for [MusicCloud][musiccloud-repo].
[![npm](https://img.shields.io/npm/dy/@yuuza/webfx?label=%40yuuza%2Fwebfx&logo=npm)](https://www.npmjs.com/package/@yuuza/webfx)
## Demos
- [Counter & viewlib](https://webfx.yuuza.net/counter.html)
([HTML + JS](https://github.com/lideming/webfx/blob/master/demo/counter.html))
([JSX](https://github.com/lideming/webfx/blob/master/demo/counter.jsx))- [Human-ping](https://webfx.yuuza.net/human-ping.html)
([HTML + JS](https://github.com/lideming/webfx/blob/master/demo/human-ping.html))- And of cource [MusicCloud (GitHub repo)][musiccloud-repo]
[musiccloud-repo]: https://github.com/lideming/MusicCloud
## Project Structure
- `buildDOM.ts` - View and DOM builder
- `view.ts` - The core of View
- `packages/`
- `utils` - [Utilities](packages/utils)
- `i18n` - [Internationalization (i18n) helper](packages/i18n)
- `views/` - Some built-in Views and helpers
- `Basics`
- `ListView`
- `Dialog`
- `Menu`
- `Overlay`
- `Toast`
- `LoadingIndicator`
- `Section`
- `style.css` - CSS for the built-in views
- `dist/` - Bundles
- `webfx.js` - UMD bundle for browsers (+ `.min.js` version)
- `webfxcore.min.js` - UMD bundle without the viewlib and style
- `webfx.esm.js` - ESM bundle## Installation
### Import from modules
Install the module locally using `npm`:
```shell
npm install @yuuza/webfx
```Import from ES modules:
```ts
import { View, ButtonView } from "@yuuza/webfx";
```### Load into the browser directly
Add webfx to your web page:
```html
```
Or if you don't need the viewlib:
```html
```
Then the module can be accessed from global variable `webfx`:
```js
const { View, ButtonView, mountView } = webfx;
```## Usage
### A basic view component
```js
// Define a very basic view class
class Hello extends View {
createDom() {
// Returns a DOM expression object for rendering.
return {
tag: "p.text.bold#hello",
text: "hello webfx",
};
}
}// Create an instance of the view and mount it onto the .
mountView(document.body, new Hello());
```**Renders**:
```html
hello webfx
```Note: You can omit the `createDom()` can be omited if you want an empty `
`.### DOM Expression
A DOM Expression is an object of type `BuildDomNode`, or a `View` object, a string, a number, or a function that returns a string or number.
```ts
type BuildDomNode = {
tag?: BuildDomTag; // A string that indicates a DOM tag name, class names, and id, similar to a CSS selector.
child?: BuildDomExpr[] | BuildDomExpr; // One or more DOM expressions as the children.
text?: FuncOrVal; // A shortcut for `textContent`. It can be a function, see below.
hidden?: FuncOrVal; // The `hidden` property, but can be a function, see below.
init?: Action; // A callback that is called when the DOM is created.
update?: Action; // A callback that is called when the view is updated.
// ...internal properties omitted...
};
```The `text` and `hidden` callbacks will be called in `updateDom()`.
### Properties and Child Elements
Webfx does not have `state`s; they are just properties.
You can use the `child` key in the DOM expression for child elements.
```js
// Inject Webfx CSS.
webfx.injectWebfxCss();class Counter extends View {
constructor() {
super();
this.count = 0;
}createDom() {
return {
tag: "div.counter",
child: [
"Count: ",
() => this.count,
{ tag: "br" },
new ButtonView({
text: "Click me",
onActive: () => {
this.updateWith({ count: this.count + 1 });
},
}),
],
};
}
}// Mount the view onto the body element.
mountView(document.body, new Counter());
```**Renders:**
```html
Count: 9
Click me
```### Hook Methods
Webfx provides two hook methods:
- `postCreateDom()`: called when the DOM is just created.
- `updateDom()`: called after `postCreateDom()`. Can also be called manually by `updateDom()`.`updateWith()` is a shortcut for changing properties and calling `updateDom()`.
Note: When overriding these methods, call the `super` method.
```js
webfx.injectWebfxCss();class Counter extends View {
constructor() {
super();
this.count = 0;
}createDom() {
return {
tag: "div.counter",
child: [
"Count: ",
{
tag: "span",
text: () => this.count,
init: (dom) => {
console.info("the DOM is created", dom);
},
update: (dom) => {
dom.style.fontSize = `${14 + this.count}px`;
},
},
{ tag: "br" },new ButtonView({
text: "Click me",
onActive: () => {
this.updateWith({ count: this.count + 1 });
},
}),
],
};
}postCreateDom() {
super.postCreateDom();
console.info("the counter DOM is created", this.dom);
}updateDom() {
super.updateDom();
console.info("the counter DOM is updated", this.dom);
}
}// Mount the view onto the body element.
mountView(document.body, new Counter());
```### ListView
(TBD)
### Using JSX/TSX
Before using JSX/TSX, make sure to set `jsx()` as the JSX factory in the transpiler.
You can do this in one of two ways:
- Set `"jsxFactory": "jsx"` in `tsconfig.json`.
- Use `/** @jsx jsx */` in your source code.```jsx
/** @jsx jsx */
import { View, ButtonView, jsx } from "@yuuza/webfx";webfx.injectWebfxCss();
class Counter extends View {
constructor() {
super();
this.count = 0;
}createDom() {
return (
Count: {() => this.count}
{
this.updateWith({ count: this.count + 1 });
}}
>
Click me
);
}
}// Mount the view onto the body element.
mountView(document.body, new Counter());
```## Todos
- [ ] Implement functional DOM tree updating.
- [ ] Add React-like function components with hooks.(TBD)