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
|
## Features
|
||||||
|
|
||||||
- **Class-based Element Creation**: Define HTML elements as TypeScript classes
|
- **Class-based Element Creation**: Define HTML elements as TypeScript classes
|
||||||
- **Attribute Management**: Easy setting, getting, and removing of HTML attributes
|
- **Attribute Management**: Easy setting, getting, and removing of HTML attributes with reserved attribute validation
|
||||||
- **CSS Class Handling**: Add and remove classes dynamically
|
- **CSS Class Handling**: Add and remove classes dynamically with full control over class lists
|
||||||
- **Style System**: Extensible styling with custom style classes
|
- **Style System**: Extensible styling with custom style classes and inline personal styles
|
||||||
- **Event Handling**: Built-in click event management with automatic re-rendering
|
- **Event Handling**: Multiple event listeners with custom event emission and data passing
|
||||||
- **Element Registration**: Automatic ID generation and DOM integration
|
- **Element Registration**: Automatic ID generation and DOM integration with unique identifiers
|
||||||
- **Primitive Components**: Pre-built HTML element wrappers
|
- **Primitive Components**: Pre-built HTML element wrappers for common elements
|
||||||
- **Dynamic Updates**: Re-render elements on the fly
|
- **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
|
## Installation
|
||||||
|
|
||||||
@ -217,6 +220,117 @@ Convert existing HTML strings to Gefest elements:
|
|||||||
const element = GefestElement.fromHTML('<button class="btn">Click</button>');
|
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
|
## API Reference
|
||||||
|
|
||||||
### GefestElement
|
### GefestElement
|
||||||
@ -237,7 +351,11 @@ const element = GefestElement.fromHTML('<button class="btn">Click</button>');
|
|||||||
- `addClass(className: string): void`
|
- `addClass(className: string): void`
|
||||||
- `removeClass(className: string): void`
|
- `removeClass(className: string): void`
|
||||||
- `getClassList(): string[]`
|
- `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
|
#### Static Methods
|
||||||
- `fromHTML(html: string): GefestElement`
|
- `fromHTML(html: string): GefestElement`
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { GefestEngine } from './engine';
|
|||||||
import { GefestStyle } from './style';
|
import { GefestStyle } from './style';
|
||||||
|
|
||||||
// The general class of Gefest
|
// The general class of Gefest
|
||||||
type gefestElementEvents = "onClick";
|
type GefestElementEvents = "onClick";
|
||||||
export abstract class GefestElement {
|
export abstract class GefestElement {
|
||||||
style: GefestStyle | null = null;
|
style: GefestStyle | null = null;
|
||||||
isHidden: boolean = false;
|
isHidden: boolean = false;
|
||||||
@ -11,16 +11,34 @@ export abstract class GefestElement {
|
|||||||
protected content: (GefestElement | string)[] | string;
|
protected content: (GefestElement | string)[] | string;
|
||||||
protected attributes: Record<string, string> = {};
|
protected attributes: Record<string, string> = {};
|
||||||
protected classList: Set<string> = new Set();
|
protected classList: Set<string> = new Set();
|
||||||
//protected eventHandlers: Record<string, (eventType: string, eventData: unknown) => void> = {};
|
protected eventHandlers: ((eventType: GefestElementEvents, eventData: unknown) => void)[] = [];
|
||||||
protected eventHandlers: ((eventType: string, eventData: unknown) => void)[] = [];
|
|
||||||
|
|
||||||
protected clickHandler: (() => void) | null = null;
|
protected clickHandler: (() => void) | null = null;
|
||||||
|
|
||||||
emit(event: gefestElementEvents, data: unknown = undefined) {
|
emit(event: GefestElementEvents, data: unknown = undefined) {
|
||||||
for (let handler of this.eventHandlers)
|
for (let handler of this.eventHandlers)
|
||||||
new Promise((rs) => rs(handler(event, data)));
|
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) {
|
set onClick(handler: (() => void) | null) {
|
||||||
if (handler) {
|
if (handler) {
|
||||||
this.clickHandler = handler;
|
this.clickHandler = handler;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user