initial repository.
changes: $View.events add 'beforeSwitch' and 'afterSwitch' events.
update: $View.switch() will fire event before replacing content.
new: add $View.currentContent for getting current view content.
This commit is contained in:
defaultkavy 2024-10-02 11:30:57 +08:00
commit 8817e5da1b
Signed by: defaultkavy
GPG Key ID: DFBB22C4E69D7826
5 changed files with 137 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
bun.lockb

12
index.ts Normal file
View File

@ -0,0 +1,12 @@
import 'elexis';
import { $View } from './lib/$View';
declare module 'elexis' {
export namespace $ {
export interface TagNameElementMap {
'view': typeof $View;
}
}
}
$.registerTagName('view', $View)
export * from './lib/$View';

78
lib/$View.ts Normal file
View File

@ -0,0 +1,78 @@
import { $Container, $ContainerOptions, $EventManager, $Node } from "elexis";
export interface $ViewOptions extends $ContainerOptions {}
export class $View extends $Container {
protected viewCache = new Map<string, $Node>();
events = new $EventManager<$ViewEventMap>().register('beforeSwitch', 'afterSwitch', 'rendered')
contentId: string | null = null;
constructor(options?: $ViewOptions) {
super('view', options);
}
setView(id: string, $node: $Node) {
this.viewCache.set(id, $node);
return this;
}
deleteView(id: string) {
this.viewCache.delete(id);
return this;
}
deleteAllView() {
this.viewCache.clear();
return this;
}
switchView(id: string) {
if (id === this.contentId) return this;
const nextContent = this.viewCache.get(id);
if (nextContent === undefined) return this;
const previousContent = this.currentContent;
let preventDefault = false;
const rendered = () => {
this.contentId = id;
this.events.fire('rendered', {$view: this, previousContent, nextContent})
}
const switched = () => {
this.events.fire('afterSwitch', {$view: this, previousId: id});
}
this.events.fire('beforeSwitch', {
$view: this,
preventDefault: () => preventDefault = true,
targetId: id,
previousContent,
nextContent,
switched,
rendered
})
if (!preventDefault) {
console.debug('not prevent default')
this.content(nextContent);
rendered();
switched();
}
return this;
}
get currentContent() {
if (!this.contentId) return;
return this.viewCache.get(this.contentId);
}
}
export interface $ViewEventMap {
'beforeSwitch': [$ViewBeforeSwitchEvent];
'afterSwitch': [{$view: $View, previousId: string}];
'rendered': [{$view: $View, previousContent: $Node | undefined, nextContent: $Node}]
}
export interface $ViewBeforeSwitchEvent {
$view: $View;
targetId: string;
previousContent: $Node | undefined;
nextContent: $Node;
preventDefault: () => void;
switched: () => void;
rendered: () => void;
}

25
package.json Normal file
View File

@ -0,0 +1,25 @@
{
"name": "@elexis/view",
"description": "A tool for manage multiple content",
"version": "0.1.0",
"author": {
"name": "defaultkavy",
"email": "defaultkavy@gmail.com",
"url": "https://git.defaultkavy.com/defaultkavy"
},
"repository": {
"type": "git",
"url": "git+https://git.defaultkavy.com/elexis/view.git"
},
"module": "index.ts",
"bugs": {
"url": "https://git.defaultkavy.com/elexis/view/issues"
},
"homepage": "https://git.defaultkavy.com/elexis/view",
"keywords": ["web", "front-end", "lib", "fluent", "framework"],
"license": "ISC",
"type": "module",
"dependencies": {
"elexis": "../../elexis"
}
}

20
tsconfig.json Normal file
View File

@ -0,0 +1,20 @@
{
"compilerOptions": {
"lib": ["dom", "ES2022"],
"module": "esnext",
"target": "esnext",
"moduleResolution": "bundler",
"moduleDetection": "force",
"allowImportingTsExtensions": true,
"noEmit": true,
"composite": true,
"strict": true,
"downlevelIteration": true,
"skipLibCheck": true,
"jsx": "react-jsx",
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"experimentalDecorators": true
},
}