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.
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.
Use Extml from a CDN:
- UMD: https://cdn.jsdelivr.net/npm/extml/dist/extml.umd.min.js
- ES: https://cdn.jsdelivr.net/npm/extml/dist/extml.es.min.js
Install Extml via npm:
$ npm install -D extml
Try Extml live on Sencha Fiddle.
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] }]
}
*/
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);
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());
}
});
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);
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);
createEffect
allows you to perform actions when dependencies change:
createEffect(() => {
console.log('Value changed:', value());
}, [value]);
Define styles specific to a component using the <style>
tag:
h`
<style>
:component {
color: red;
}
</style>
<ext-button text="Styled Button" />
`;
- 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 thetap
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.
Description: Toggles the value of a reactive state between true
and false
.
Parameters:
state
(function): The reactive state to toggle.
Examples:
-
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
-
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
Description: Creates a reactive state object.
Parameters:
initialValue
(any): Initial value of the state.
Returns: [state, setState]
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]);
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');
Description: Generates a state derived from other states.
Example:
const derived = createDerivedState(() => value() * 2);
Description: Creates a reference object for DOM or component tracking.
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"
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>
`;
Extml is open-source software licensed under the MIT License.