add event handling
This commit is contained in:
parent
0fe8129f52
commit
4713807f94
@ -5,13 +5,16 @@ Gefest is a lightweight, TypeScript-based framework for building and managing HT
|
||||
## Features
|
||||
|
||||
- **Class-based Element Creation**: Define HTML elements as TypeScript classes
|
||||
- **Attribute Management**: Easy setting, getting, and removing of HTML attributes
|
||||
- **CSS Class Handling**: Add and remove classes dynamically
|
||||
- **Style System**: Extensible styling with custom style classes
|
||||
- **Event Handling**: Built-in click event management with automatic re-rendering
|
||||
- **Element Registration**: Automatic ID generation and DOM integration
|
||||
- **Primitive Components**: Pre-built HTML element wrappers
|
||||
- **Dynamic Updates**: Re-render elements on the fly
|
||||
- **Attribute Management**: Easy setting, getting, and removing of HTML attributes with reserved attribute validation
|
||||
- **CSS Class Handling**: Add and remove classes dynamically with full control over class lists
|
||||
- **Style System**: Extensible styling with custom style classes and inline personal styles
|
||||
- **Event Handling**: Multiple event listeners with custom event emission and data passing
|
||||
- **Element Registration**: Automatic ID generation and DOM integration with unique identifiers
|
||||
- **Primitive Components**: Pre-built HTML element wrappers for common elements
|
||||
- **Dynamic Updates**: Re-render elements on the fly with automatic DOM synchronization
|
||||
- **HTML Parsing**: Convert HTML strings to Gefest elements with `fromHTML()`
|
||||
- **Personal Inline Styling**: Set and manage inline CSS styles directly on elements
|
||||
- **Async Event System**: Promise-based event handling with custom event data
|
||||
|
||||
## Installation
|
||||
|
||||
@ -217,6 +220,117 @@ Convert existing HTML strings to Gefest elements:
|
||||
const element = GefestElement.fromHTML('<button class="btn">Click</button>');
|
||||
```
|
||||
|
||||
### Personal Styling
|
||||
|
||||
Set inline styles directly on elements:
|
||||
|
||||
```typescript
|
||||
const button = new GefestButton("Styled");
|
||||
button.setPersonalStyle('background-color: blue; color: white; padding: 10px;');
|
||||
```
|
||||
|
||||
Remove personal styles:
|
||||
|
||||
```typescript
|
||||
button.setPersonalStyle(null); // Removes inline styles
|
||||
```
|
||||
|
||||
### Event System
|
||||
|
||||
#### Using onClick Handler
|
||||
|
||||
```typescript
|
||||
const button = new GefestButton("Click me");
|
||||
button.onClick = () => {
|
||||
console.log('Button was clicked!');
|
||||
};
|
||||
```
|
||||
|
||||
#### Registering Multiple Event Listeners
|
||||
|
||||
Use the `on()` method to register multiple event handlers for the same event:
|
||||
|
||||
```typescript
|
||||
const button = new GefestButton("Multi-Listener");
|
||||
|
||||
// First listener
|
||||
button.on("onClick", (data) => {
|
||||
console.log('Handler 1 called', data);
|
||||
});
|
||||
|
||||
// Second listener
|
||||
button.on("onClick", (data) => {
|
||||
console.log('Handler 2 called', data);
|
||||
});
|
||||
```
|
||||
|
||||
#### Registering One-Time Event Listeners
|
||||
|
||||
Use the `once()` method to register an event handler that only fires once:
|
||||
|
||||
```typescript
|
||||
const button = new GefestButton("One-Time");
|
||||
|
||||
// This handler will only execute on the first click
|
||||
button.once("onClick", (data) => {
|
||||
console.log('First click only!', data);
|
||||
// Handler is automatically removed after first execution
|
||||
});
|
||||
```
|
||||
|
||||
#### Emitting Events
|
||||
|
||||
Emit custom events with optional data:
|
||||
|
||||
```typescript
|
||||
const button = new GefestButton("Action");
|
||||
|
||||
button.on("onClick", (data) => {
|
||||
console.log('Click event with data:', data);
|
||||
});
|
||||
|
||||
button.onClick = () => {
|
||||
// onClick handler is automatically emitted with event data
|
||||
button.emit("onClick", { timestamp: Date.now(), action: 'clicked' });
|
||||
};
|
||||
```
|
||||
|
||||
### Element Re-rendering
|
||||
|
||||
Trigger manual re-renders when element state changes:
|
||||
|
||||
```typescript
|
||||
const button = new GefestButton("Click me");
|
||||
let clickCount = 0;
|
||||
|
||||
button.onClick = () => {
|
||||
clickCount++;
|
||||
// Update content or attributes
|
||||
button.update(); // Re-renders in the DOM
|
||||
};
|
||||
```
|
||||
|
||||
### Attribute Management
|
||||
|
||||
Full control over element attributes:
|
||||
|
||||
```typescript
|
||||
const button = new GefestButton("Submit");
|
||||
|
||||
// Set attribute
|
||||
button.setAttribute('type', 'submit');
|
||||
button.setAttribute('aria-label', 'Submit form');
|
||||
|
||||
// Get attribute
|
||||
const type = button.getAttribute('type'); // 'submit'
|
||||
|
||||
// Remove attribute
|
||||
button.removeAttribute('disabled');
|
||||
|
||||
// Check for reserved attributes (will throw error)
|
||||
// button.setAttribute('class', 'btn'); // Error: 'class' is reserved
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### GefestElement
|
||||
@ -237,7 +351,11 @@ const element = GefestElement.fromHTML('<button class="btn">Click</button>');
|
||||
- `addClass(className: string): void`
|
||||
- `removeClass(className: string): void`
|
||||
- `getClassList(): string[]`
|
||||
- `setPersonalStyle(style: string | null): void`
|
||||
- `setPersonalStyle(style: string | null): void` - Set inline styles on the element
|
||||
- `emit(event: GefestElementEvents, data?: unknown): void` - Emit custom events
|
||||
- `on(event: GefestElementEvents, handler: (data: unknown) => void): void` - Register event listener
|
||||
- `once(event: GefestElementEvents, handler: (data: unknown) => void): void` - Register one-time event listener
|
||||
- `checkReservedAttribute(key: string): void` - Validate if attribute key is reserved
|
||||
|
||||
#### Static Methods
|
||||
- `fromHTML(html: string): GefestElement`
|
||||
|
||||
@ -2,7 +2,7 @@ import { GefestEngine } from './engine';
|
||||
import { GefestStyle } from './style';
|
||||
|
||||
// The general class of Gefest
|
||||
type gefestElementEvents = "onClick";
|
||||
type GefestElementEvents = "onClick";
|
||||
export abstract class GefestElement {
|
||||
style: GefestStyle | null = null;
|
||||
isHidden: boolean = false;
|
||||
@ -11,16 +11,34 @@ export abstract class GefestElement {
|
||||
protected content: (GefestElement | string)[] | string;
|
||||
protected attributes: Record<string, string> = {};
|
||||
protected classList: Set<string> = new Set();
|
||||
//protected eventHandlers: Record<string, (eventType: string, eventData: unknown) => void> = {};
|
||||
protected eventHandlers: ((eventType: string, eventData: unknown) => void)[] = [];
|
||||
protected eventHandlers: ((eventType: GefestElementEvents, eventData: unknown) => void)[] = [];
|
||||
|
||||
protected clickHandler: (() => void) | null = null;
|
||||
|
||||
emit(event: gefestElementEvents, data: unknown = undefined) {
|
||||
emit(event: GefestElementEvents, data: unknown = undefined) {
|
||||
for (let handler of this.eventHandlers)
|
||||
new Promise((rs) => rs(handler(event, data)));
|
||||
}
|
||||
|
||||
on(event: GefestElementEvents, handler: (data : unknown) => void) {
|
||||
this.eventHandlers.push((calledEvent: GefestElementEvents, calledData: unknown) => {
|
||||
if (calledEvent === event)
|
||||
return handler(calledData);
|
||||
});
|
||||
}
|
||||
|
||||
once(event: GefestElementEvents, handler: (data : unknown) => void) {
|
||||
const addedHandler = (calledEvent: GefestElementEvents, calledData: unknown) => {
|
||||
if (calledEvent === event) {
|
||||
const index = this.eventHandlers.indexOf(addedHandler);
|
||||
this.eventHandlers.splice(index, 1);
|
||||
return handler(calledData);
|
||||
}
|
||||
};
|
||||
|
||||
this.eventHandlers.push(addedHandler);
|
||||
}
|
||||
|
||||
set onClick(handler: (() => void) | null) {
|
||||
if (handler) {
|
||||
this.clickHandler = handler;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user