Update README.md for Gefest. And.. I meant at the last commit: I got tired for describing all changes
This commit is contained in:
parent
a4c5b441f6
commit
56a5639c57
@ -1,361 +1,100 @@
|
|||||||
# Gefest Framework
|
# Gefest Framework
|
||||||
|
|
||||||
Gefest is a lightweight, TypeScript-based framework for building and managing HTML elements programmatically. It provides a class-based approach to create reusable UI components with built-in support for attributes, classes, styles, and event handling.
|
Gefest is a lightweight TypeScript framework for building HTML UI components with a class-based API. It makes it easy to create reusable elements, bind events, manage styles and classes, and rerender elements dynamically.
|
||||||
|
|
||||||
## Features
|
## Overview
|
||||||
|
|
||||||
- **Class-based Element Creation**: Define HTML elements as TypeScript classes
|
Gefest provides:
|
||||||
- **Attribute Management**: Easy setting, getting, and removing of HTML attributes with reserved attribute validation
|
- A base `GefestElement` class for elements with nested content and attributes
|
||||||
- **CSS Class Handling**: Add and remove classes dynamically with full control over class lists
|
- Automatic `data-gefest-id` registration for DOM element tracking
|
||||||
- **Style System**: Extensible styling with custom style classes and inline personal styles
|
- Class and style management via helper methods
|
||||||
- **Event Handling**: Multiple event listeners with custom event emission and data passing
|
- Event handling with `onClick`, `on`, `once`, and `emit`
|
||||||
- **Element Registration**: Automatic ID generation and DOM integration with unique identifiers
|
- Expression of UI elements as TypeScript classes instead of raw HTML strings
|
||||||
- **Primitive Components**: Pre-built HTML element wrappers for common elements
|
- A simple engine that binds click handlers and supports rerendering
|
||||||
- **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
|
## Quick Start
|
||||||
|
|
||||||
Gefest is included as a module in this project. To use it in your TypeScript files:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { GefestEngine, GefestElement } from './engine';
|
|
||||||
import { GefestButton } from './primitives/button';
|
|
||||||
// ... other imports as needed
|
|
||||||
```
|
|
||||||
|
|
||||||
## Core Concepts
|
|
||||||
|
|
||||||
### GefestElement
|
|
||||||
|
|
||||||
The base abstract class for all Gefest elements. It provides:
|
|
||||||
|
|
||||||
- Content management (strings or nested elements)
|
|
||||||
- Attribute handling
|
|
||||||
- Class management
|
|
||||||
- Style application
|
|
||||||
- Event binding
|
|
||||||
- Automatic re-rendering on updates
|
|
||||||
|
|
||||||
### GefestEngine
|
|
||||||
|
|
||||||
Manages the lifecycle of Gefest elements:
|
|
||||||
|
|
||||||
- Registers elements with unique IDs
|
|
||||||
- Activates event handlers on DOM elements
|
|
||||||
- Provides the main entry point for applications
|
|
||||||
- Handles re-rendering of updated elements
|
|
||||||
|
|
||||||
### GefestStyle
|
|
||||||
|
|
||||||
Abstract base class for styling systems. Implement custom styles by extending this class.
|
|
||||||
|
|
||||||
## Basic Usage
|
|
||||||
|
|
||||||
### Creating Elements
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { GefestButton } from './primitives/button';
|
|
||||||
|
|
||||||
// Create a simple button
|
|
||||||
const button = new GefestButton("Click me!");
|
|
||||||
console.log(button.build()); // <button data-gefest-id="gefest-abc123">Click me!</button>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Setting Attributes
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const button = new GefestButton("Submit");
|
|
||||||
button.setAttribute('type', 'submit');
|
|
||||||
button.setAttribute('disabled', 'true');
|
|
||||||
```
|
|
||||||
|
|
||||||
### Managing Classes
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const button = new GefestButton("Button");
|
|
||||||
button.addClass('btn');
|
|
||||||
button.addClass('btn-primary');
|
|
||||||
button.removeClass('btn');
|
|
||||||
console.log(button.getClassList()); // ['btn-primary']
|
|
||||||
```
|
|
||||||
|
|
||||||
### Hiding Elements
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const button = new GefestButton("Hidden Button");
|
|
||||||
button.isHidden = true; // Sets the 'hidden' attribute on the element
|
|
||||||
```
|
|
||||||
|
|
||||||
### Event Handling
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const button = new GefestButton("Click me!");
|
|
||||||
button.onClick = () => {
|
|
||||||
console.log('Button clicked!');
|
|
||||||
// The framework automatically re-renders after click
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### Updating Elements
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const button = new GefestButton("Initial");
|
|
||||||
button.update(); // Re-renders the element in the DOM
|
|
||||||
```
|
|
||||||
|
|
||||||
### Running the Application
|
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { GefestEngine } from './engine';
|
import { GefestEngine } from './engine';
|
||||||
|
import { GefestButton } from './primitives/button';
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
// Create and configure your elements here
|
const button = new GefestButton('Click me');
|
||||||
const button = new GefestButton("Hello World");
|
button.addClass('btn');
|
||||||
button.onClick = () => alert('Hello!');
|
button.onClick = () => {
|
||||||
|
alert('Button clicked');
|
||||||
|
};
|
||||||
|
|
||||||
// Insert into DOM
|
|
||||||
document.body.innerHTML = button.build();
|
document.body.innerHTML = button.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
GefestEngine.main(main);
|
GefestEngine.main(main);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Core Concepts
|
||||||
|
|
||||||
|
### GefestElement
|
||||||
|
|
||||||
|
The base class for all Gefest components. It handles:
|
||||||
|
- Content rendering from strings or nested `GefestElement` instances
|
||||||
|
- HTML attributes and reserved attribute protection
|
||||||
|
- CSS class list management
|
||||||
|
- Inline personal styles
|
||||||
|
- Event registration and emission
|
||||||
|
- Unique element registration via `GefestEngine`
|
||||||
|
- Automatic rerendering when `update()` is called
|
||||||
|
|
||||||
|
### GefestEngine
|
||||||
|
|
||||||
|
The runtime engine that manages registered elements.
|
||||||
|
- `register(element)` assigns a unique `data-gefest-id`
|
||||||
|
- `activateOnClick()` binds click handlers for registered elements
|
||||||
|
- `main(mainFn)` runs your app and activates click bindings
|
||||||
|
- `render(gefestId)` rerenders one or all registered elements
|
||||||
|
|
||||||
|
### GefestStyle
|
||||||
|
|
||||||
|
A base class for custom styling strategies. Extend `GefestStyle` and implement `applyStyle(html, element)` to transform rendered HTML.
|
||||||
|
|
||||||
## Primitives
|
## Primitives
|
||||||
|
|
||||||
Gefest includes several pre-built primitive elements:
|
Gefest ships with simple element wrappers:
|
||||||
|
- `GefestButton` — `<button>`
|
||||||
### GefestButton
|
- `GefestA` — `<a>`
|
||||||
|
- `GefestImg` — `<img>`
|
||||||
Wraps HTML `<button>` elements.
|
- `GefestP` — `<p>`
|
||||||
|
- `GefestSpan` — `<span>`
|
||||||
```typescript
|
- `GefestHeader` — `<h1>`–`<h6>`
|
||||||
const button = new GefestButton("Click me");
|
- `GefestI` — `<i>`
|
||||||
button.setAttribute('type', 'submit');
|
- `GefestSmall` — `<small>`
|
||||||
```
|
- `GefestCenter` — `<center>`
|
||||||
|
|
||||||
### GefestA
|
|
||||||
|
|
||||||
Wraps HTML `<a>` elements.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const link = new GefestA("Visit site", "https://example.com");
|
|
||||||
link.setAttribute('target', '_blank');
|
|
||||||
```
|
|
||||||
|
|
||||||
### GefestImg
|
|
||||||
|
|
||||||
Wraps HTML `<img>` elements.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const image = new GefestImg("", "path/to/image.jpg");
|
|
||||||
image.setAttribute('alt', 'Description');
|
|
||||||
```
|
|
||||||
|
|
||||||
### Other Primitives
|
|
||||||
|
|
||||||
- `GefestP`: Paragraph (`<p>`)
|
|
||||||
- `GefestSpan`: Span (`<span>`)
|
|
||||||
- `GefestHeader`: Header (`<h1>`)
|
|
||||||
- `GefestI`: Italic (`<i>`)
|
|
||||||
- `GefestSmall`: Small text (`<small>`)
|
|
||||||
- `GefestCenter`: Centered content (`<center>`)
|
|
||||||
|
|
||||||
## Advanced Features
|
|
||||||
|
|
||||||
### Nested Elements
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const link = new GefestA("Read more", "#");
|
|
||||||
const button = new GefestButton([link, " about this"]);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Custom Elements
|
|
||||||
|
|
||||||
Create your own elements by extending `GefestElement`:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { GefestElement } from './element';
|
|
||||||
|
|
||||||
export class GefestDiv extends GefestElement {
|
|
||||||
protected wrapHTML(content: string): string {
|
|
||||||
const attrString = this.attributesToString();
|
|
||||||
return `<div ${attrString}>${content}</div>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Custom Styles
|
|
||||||
|
|
||||||
Implement custom styling by extending `GefestStyle`:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { GefestStyle, GefestElement } from './style';
|
|
||||||
|
|
||||||
export class BootstrapStyle extends GefestStyle {
|
|
||||||
applyStyle(html: string, element?: GefestElement): string {
|
|
||||||
// Apply Bootstrap classes or inline styles
|
|
||||||
if (element?.getClassList().includes('btn')) {
|
|
||||||
return html.replace('<button', '<button class="btn btn-primary"');
|
|
||||||
}
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Apply styles to elements:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const button = new GefestButton("Styled Button");
|
|
||||||
button.style = new BootstrapStyle();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Parsing HTML
|
|
||||||
|
|
||||||
Convert existing HTML strings to Gefest elements:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
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
|
||||||
|
|
||||||
#### Properties
|
#### Properties
|
||||||
- `gefestId: string` - Unique identifier for the element (readonly)
|
- `gefestId: string` — auto-generated unique identifier
|
||||||
- `style: GefestStyle | null` - Style to apply to the element
|
- `style: GefestStyle | (() => GefestStyle) | null`
|
||||||
- `onClick: (() => void) | null` - Click event handler (getter/setter)
|
- `onClick: (() => void) | null`
|
||||||
- `isHidden: boolean` - Whether the element should be hidden (sets the 'hidden' attribute when true)
|
- `isHidden: boolean`
|
||||||
|
- `id: string | null`
|
||||||
|
|
||||||
#### Methods
|
#### Methods
|
||||||
- `constructor(content: (GefestElement | string)[] | string)`
|
- `constructor(content?: (GefestElement | string)[] | string)`
|
||||||
- `build(isFromStyle?: boolean): string`
|
- `build(isFromStyle?: boolean): string`
|
||||||
- `update(): void` - Re-renders the element in the DOM
|
- `update(): void`
|
||||||
- `setAttribute(key: string, value: string): void`
|
- `setAttribute(key, value): void`
|
||||||
- `getAttribute(key: string): string | undefined`
|
- `getAttribute(key): string | undefined`
|
||||||
- `removeAttribute(key: string): void`
|
- `removeAttribute(key): void`
|
||||||
- `addClass(className: string): void`
|
- `addClass(className): void`
|
||||||
- `removeClass(className: string): void`
|
- `removeClass(className): void`
|
||||||
- `getClassList(): string[]`
|
- `getClassList(): string[]`
|
||||||
- `setPersonalStyle(style: string | null): void` - Set inline styles on the element
|
- `setPersonalStyle(style: string | null): void`
|
||||||
- `emit(event: GefestElementEvents, data?: unknown): void` - Emit custom events
|
- `emit(event, data?): void`
|
||||||
- `on(event: GefestElementEvents, handler: (data: unknown) => void): void` - Register event listener
|
- `on(event, handler): void`
|
||||||
- `once(event: GefestElementEvents, handler: (data: unknown) => void): void` - Register one-time event listener
|
- `once(event, handler): void`
|
||||||
- `checkReservedAttribute(key: string): void` - Validate if attribute key is reserved
|
- `checkReservedAttribute(key): void`
|
||||||
|
|
||||||
#### Static Methods
|
#### Static Methods
|
||||||
- `fromHTML(html: string): GefestElement`
|
- `fromHTML(html: string): GefestElement`
|
||||||
@ -366,69 +105,132 @@ button.removeAttribute('disabled');
|
|||||||
- `register(element: GefestElement): string`
|
- `register(element: GefestElement): string`
|
||||||
- `activateOnClick(): Promise<void>`
|
- `activateOnClick(): Promise<void>`
|
||||||
- `main(main: () => Promise<void>): Promise<void>`
|
- `main(main: () => Promise<void>): Promise<void>`
|
||||||
- `reRenderByGI(gefestId: string): void`
|
- `render(gefestId?: string | string[] | null): void`
|
||||||
|
|
||||||
### GefestStyle
|
### GefestStyle
|
||||||
|
|
||||||
#### Methods
|
#### Methods
|
||||||
- `applyStyle(html: string, element?: GefestElement): string`
|
- `applyStyle(html: string, element?: GefestElement): string`
|
||||||
|
|
||||||
## Examples
|
## Usage Examples
|
||||||
|
|
||||||
### Complete Application
|
### Create a button
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { GefestEngine } from './engine';
|
import { GefestButton } from './primitives/button';
|
||||||
import { GefestButton, GefestP } from './primitives';
|
|
||||||
|
|
||||||
async function main() {
|
const button = new GefestButton('Submit');
|
||||||
const title = new GefestP("Welcome to Gefest!");
|
button.addClass('btn');
|
||||||
title.addClass('title');
|
button.setAttribute('type', 'submit');
|
||||||
|
button.onClick = () => {
|
||||||
|
console.log('clicked');
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
const button = new GefestButton("Get Started");
|
### Apply inline styles
|
||||||
button.addClass('start-btn');
|
|
||||||
button.onClick = () => {
|
|
||||||
alert('Welcome!');
|
|
||||||
};
|
|
||||||
|
|
||||||
// For custom elements, define them as shown above
|
```typescript
|
||||||
const container = new (class extends GefestElement {
|
button.setPersonalStyle('background-color: blue; color: white; padding: 10px;');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hide an element
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
button.isHidden = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nested elements
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { GefestA } from './primitives/a';
|
||||||
|
|
||||||
|
const link = new GefestA('Read more', '#');
|
||||||
|
const button = new GefestButton([link, ' more']);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom element
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { GefestElement } from './element';
|
||||||
|
|
||||||
|
class GefestDiv extends GefestElement {
|
||||||
protected wrapHTML(content: string): string {
|
protected wrapHTML(content: string): string {
|
||||||
const attrString = this.attributesToString();
|
const attrString = this.attributesToString();
|
||||||
return `<div ${attrString}>${content}</div>`;
|
return `<div ${attrString}>${content}</div>`;
|
||||||
}
|
}
|
||||||
})([title, button]);
|
}
|
||||||
container.addClass('container');
|
```
|
||||||
|
|
||||||
document.body.innerHTML = container.build();
|
### Custom style
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { GefestStyle } from './style';
|
||||||
|
|
||||||
|
class BootstrapStyle extends GefestStyle {
|
||||||
|
applyStyle(html: string, element?: GefestElement): string {
|
||||||
|
if (element?.getClassList().includes('btn')) {
|
||||||
|
return html.replace('<button', '<button class="btn btn-primary"');
|
||||||
|
}
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button.style = new BootstrapStyle();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Event listeners
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
button.on('onClick', (data) => {
|
||||||
|
console.log('click data', data);
|
||||||
|
});
|
||||||
|
|
||||||
|
button.once('onClick', () => {
|
||||||
|
console.log('once only');
|
||||||
|
});
|
||||||
|
|
||||||
|
button.onClick = () => {
|
||||||
|
button.emit('onClick', { value: 1 });
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rerendering
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
button.update();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Complete app
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { GefestEngine } from './engine';
|
||||||
|
import { GefestButton, GefestHeader, GefestP } from './primitives';
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const title = new GefestHeader('Welcome', 2);
|
||||||
|
const button = new GefestButton('Start');
|
||||||
|
button.onClick = () => alert('Hello');
|
||||||
|
document.body.innerHTML = title.build() + button.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
GefestEngine.main(main);
|
GefestEngine.main(main);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Form Creation
|
## Notes
|
||||||
|
|
||||||
```typescript
|
- `class`, `style`, and `data-gefest-id` are reserved.
|
||||||
import { GefestButton } from './primitives/button';
|
- Use `addClass` / `removeClass` for CSS classes.
|
||||||
|
- Use `setPersonalStyle` for inline styles.
|
||||||
const submitBtn = new GefestButton("Submit");
|
- `GefestElement.fromHTML()` is experimental and may not preserve all behavior.
|
||||||
submitBtn.setAttribute('type', 'submit');
|
|
||||||
submitBtn.addClass('btn-submit');
|
|
||||||
|
|
||||||
const form = document.createElement('form');
|
|
||||||
form.innerHTML = submitBtn.build();
|
|
||||||
document.body.appendChild(form);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
To add new primitives or extend the framework:
|
To extend Gefest:
|
||||||
|
1. Add a class extending `GefestElement`
|
||||||
1. Create new classes extending `GefestElement`
|
2. Implement `wrapHTML()` with the desired tag
|
||||||
2. Implement the `wrapHTML` method to return the appropriate HTML tag
|
3. Add custom logic, classes, or events
|
||||||
3. Add event handling if needed
|
4. Test with `GefestEngine.main()` in the browser
|
||||||
4. Test with `GefestEngine.main()`
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This framework is part of the AmeVox project. See project license for details.
|
This framework is part of the AmeVox project. See the project license for details.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user