add event handling

This commit is contained in:
FullGreaM 2026-04-27 03:32:55 +03:00
parent 0fe8129f52
commit 4713807f94
2 changed files with 148 additions and 12 deletions

View File

@ -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`

View File

@ -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;