# 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.

## 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
- **Element Registration**: Automatic ID generation and DOM integration
- **Primitive Components**: Pre-built HTML element wrappers

## Installation

Gefest is included as a module in this project. To use it in your TypeScript files:

```typescript
import { GefestEngine, GefestElement } from './modules/Gefest/engine';
import { GefestButton } from './modules/Gefest/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

### 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

### 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!');
};
```

### Running the Application

```typescript
import { GefestEngine } from './engine';

async function main() {
    // Create and configure your elements here
    const button = new GefestButton("Hello World");
    button.onClick = () => alert('Hello!');

    // Insert into DOM
    document.body.innerHTML = button.build();
}

GefestEngine.main(main);
```

## Primitives

Gefest includes several pre-built primitive elements:

### GefestButton

Wraps HTML `<button>` elements.

```typescript
const button = new GefestButton("Click me");
button.setAttribute('type', 'submit');
```

### GefestA

Wraps HTML `<a>` elements.

```typescript
const link = new GefestA("Visit site", "https://example.com");
link.setAttribute('target', '_blank');
```

### Other Primitives

- `GefestP`: Paragraph (`<p>`)
- `GefestSpan`: Span (`<span>`)
- `GefestHeader`: Header (`<h1>`)
- `GefestI`: Italic (`<i>`)
- `GefestSmall`: Small text (`<small>`)
- `GefestCenter`: Centered content (custom wrapper)

## 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>');
```

## API Reference

### GefestElement

#### Properties
- `gefestId: string` - Unique identifier for the element
- `style: GefestStyle | null` - Style to apply to the element
- `onClick: (() => void) | null` - Click event handler
- `isHidden: boolean` - Whether the element should be hidden (sets the 'hidden' attribute when true)

#### Methods
- `constructor(content: (GefestElement | string)[] | string)`
- `build(isFromStyle?: boolean): string`
- `setAttribute(key: string, value: string): void`
- `getAttribute(key: string): string | undefined`
- `removeAttribute(key: string): void`
- `addClass(className: string): void`
- `removeClass(className: string): void`
- `getClassList(): string[]`
- `setPersonalStyle(style: string | null): void`

#### Static Methods
- `fromHTML(html: string): GefestElement`

### GefestEngine

#### Static Methods
- `register(element: GefestElement): string`
- `activateOnClick(): Promise<void>`
- `main(main: () => Promise<void>): Promise<void>`

### GefestStyle

#### Methods
- `applyStyle(html: string, element?: GefestElement): string`

## Examples

### Complete Application

```typescript
import { GefestEngine } from './modules/Gefest/engine';
import { GefestButton, GefestP } from './modules/Gefest/primitives';

async function main() {
    const title = new GefestP("Welcome to Gefest!");
    title.addClass('title');

    const button = new GefestButton("Get Started");
    button.addClass('start-btn');
    button.onClick = () => {
        alert('Welcome!');
    };

    const container = new GefestDiv([title, button]);
    container.addClass('container');

    document.body.innerHTML = container.build();
}

GefestEngine.main(main);
```

### Form Creation

```typescript
import { GefestButton } from './primitives/button';

const submitBtn = new GefestButton("Submit");
submitBtn.setAttribute('type', 'submit');
submitBtn.addClass('btn-submit');

const form = document.createElement('form');
form.innerHTML = submitBtn.build();
document.body.appendChild(form);
```

## Contributing

To add new primitives or extend the framework:

1. Create new classes extending `GefestElement`
2. Implement the `wrapHTML` method to return the appropriate HTML tag
3. Add event handling if needed
4. Test with `GefestEngine.main()`

## License

This framework is part of the AmeVox project. See project license for details.
