Skip to content

fabioricali/html-to-extjs-object

Repository files navigation

Extml

Overview

Extml simplifies the creation and management of ExtJS components through an intuitive HTML-based markup system. It enables reactive programming, dynamic state handling, and seamless integration with ExtJS's modern toolkit.


Table of Contents


Core Concepts

Extml allows developers to:

  • Leverage HTML Markup: Create ExtJS components using simple HTML templates.
  • Reactive Programming: Update components dynamically based on state changes.
  • Scoped Styling: Define styles specific to components and their children.

Installation

Alternative Installation

Use Extml from a CDN:

Install Extml via npm:

$ npm install -D extml

Examples

Live Demo

Try Extml live on Sencha Fiddle.

Basic Example

import { h } from 'extml';

function myButton() {
    return h`
        <ext-button text="Click Me" ontap=${() => alert('Button clicked!')} />
    `;
}

const component = myButton();
console.log(component);
/* Outputs:
{
  xtype: 'button',
  text: 'Click Me',
  listeners: [{ tap: [Function] }]
}
*/

Advanced Example

import {
    h,
    createState,
    createRef,
    createEffect,
    createDerivedState,
    conditionalState
} from "extml";

function timelineComponent() {
    const [currentTime, setCurrentTime] = createState(0);
    const [isPlaying, setIsPlaying] = createState(false);

    const currentRelativeTime = createDerivedState(() => {
        const time = currentTime();
        return time < 10 ? `0:0${time}` : `0:${time}`;
    });

    const videoRef = createRef();

    createEffect(() => {
        const video = videoRef();
        if (!video) return;

        video.addEventListener('timeupdate', () => setCurrentTime(video.currentTime));
        video.addEventListener('play', () => setIsPlaying(true));
        video.addEventListener('pause', () => setIsPlaying(false));
    }, [videoRef]);

    return h`
        <ext-container>
            <video ref=${videoRef} controls style="width: 100%;">
                <source src="example.mp4" type="video/mp4" />
            </video>
            <div>Current Time: ${currentRelativeTime}</div>
            <div>Status: ${conditionalState(isPlaying, 'Playing', 'Paused')}</div>
        </ext-container>
    `;
}

const component = timelineComponent();
console.log(component);

Integration with ExtJS Application

Ext.application({
    name : 'Fiddle',

    launch : function() {
        const { h } = window.extml;

        const myButton = function() {
            return h`
                <ext-button
                    text="Click me! (see the console)"
                    ontap=${(me) => console.log(me)}
                />
            `;
        };

        const myPanel = function() {
            return h`
                <style>
                    :component {
                        border: 4px solid red!important;
                        padding: 8px;
                    }
                    .my-div {
                        color: red;
                    }

                    .my-button {
                        font-size: 19px;
                    }
                </style>
                <ext-panel title="My Panel Title">
                    <${myButton}/>
                    <div class="my-div">
                        Html is allowed ;) <a href="https://www.google.it" target="_blank">Go to Google</a>
                        <ext-button class="my-button" text="Ext Button inside a div" ontap=${() => alert('hello')}/>
                        <div>the result of 1+2 is ${1+2}</div>
                    </div>
                </ext-panel>
            `;
        };

        this.viewport.add(myPanel());
    }
});

Using the For Component

import { h, For } from "extml";

function listComponent(items) {
    return h`
        <ext-container>
            <${For}
                each=${items}
                getKey=${(item) => item.id}
                effect=${(item) => h`
                    <ext-panel title=${item.title}>
                        <div>${item.content}</div>
                    </ext-panel>
                `}
            />
        </ext-container>
    `;
}

const items = [
    { id: 1, title: "Item 1", content: "Content 1" },
    { id: 2, title: "Item 2", content: "Content 2" },
    { id: 3, title: "Item 3", content: "Content 3" }
];

const component = listComponent(items);
console.log(component);

Key Features

State Management

Extml provides a robust state management system:

  • createState: Creates a reactive state.
  • createDerivedState: Generates states derived from other states.
  • Example:
    const [value, setValue] = createState(0);
    setValue(value() + 1);

Reactive Components

createEffect allows you to perform actions when dependencies change:

createEffect(() => {
    console.log('Value changed:', value());
}, [value]);

Scoped Styling

Define styles specific to a component using the <style> tag:

h`
    <style>
        :component {
            color: red;
        }
    </style>
    <ext-button text="Styled Button" />
`;

Component Guidelines

  • Component Tags: All ExtJS component tags must use the ext- prefix (e.g., <ext-button>).
  • Event Listeners: Use the on prefix for defining event listeners (e.g., ontap for the tap event).
  • HTML Compatibility: You can mix native HTML tags with ExtJS components in your templates.
  • Scoped Styles: Define component-specific styles within a <style> block.

API Reference

toggleState

Description: Toggles the value of a reactive state between true and false.

Parameters:

  • state (function): The reactive state to toggle.

Examples:

  1. Toggling a single boolean state:

    import { createState, toggleState } from 'extml';
    
    const [myState] = createState(false);
    toggleState(myState);
    console.log(myState()); // true
    toggleState(myState);
    console.log(myState()); // false
  2. Toggling a property within a state object:

    import { createState, toggleState } from 'extml';
    
    const [state] = createState({ done: false, text: 'Hello' });
    toggleState(state.done);
    console.log(state.text()); // "Hello"
    console.log(state.done()); // true
    toggleState(state.done);
    console.log(state.done()); // false

createState

Description: Creates a reactive state object.

Parameters:

  • initialValue (any): Initial value of the state.

Returns: [state, setState]

createEffect

Description: Executes a function when dependencies change.

Parameters:

  • effect (function): The function to execute.
  • dependencies (array): Reactive states to watch.

Example:

createEffect(() => console.log(value()), [value]);

conditionalState

Description: Creates a state that toggles between two values based on a condition.

Parameters:

  • state (function): Reactive state.
  • trueValue (any): Value when the condition is true.
  • falseValue (any): Value when the condition is false.

Example:

const isPositive = conditionalState(value, 'Positive', 'Negative');

createDerivedState

Description: Generates a state derived from other states.

Example:

const derived = createDerivedState(() => value() * 2);

createRef

Description: Creates a reference object for DOM or component tracking.

createExtRef

Description: Creates a reference object for tracking ExtJS components instead of DOM elements.

Examples:

import { createExtRef } from 'extml';

const extRef = createExtRef();

// Later in your component:
h`
    <ext-panel ref=${extRef}></ext-panel>
`;

// Access the ExtJS component:
const extComponent = extRef();
console.log(extComponent.xtype); // "panel"

bindState

Description: This property allows you to link a state to a component that works with change event like form fields.

Examples:

import { createState } from 'extml';

const [myState] = createState();

// Then in your component:
h`
    <ext-textfield bindState=${myState} placeholder="write here"></ext-textfield>
    <div>value: ${myState}</div>
`;

License

Extml is open-source software licensed under the MIT License.


Author

Fabio Ricali

About

Convert html to ExtJS object

Resources

Stars

Watchers

Forks

Packages

No packages published