extml
Version:
Converts html tagged templates to ExtJS component object.
405 lines (289 loc) • 9.88 kB
Markdown
# 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](#core-concepts)
- [Installation](#installation)
- [Examples](#examples)
- [Basic Example](#basic-example)
- [Advanced Example](#advanced-example)
- [Integration with ExtJS Application](#integration-with-extjs-application)
- [Using the For Component](#using-the-for-component)
- [Key Features](#key-features)
- [State Management](#state-management)
- [Reactive Components](#reactive-components)
- [Scoped Styling](#scoped-styling)
- [Component Guidelines](#component-guidelines)
- [API Reference](#api-reference)
- [License](#license)
---
## 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:
- **UMD:** [https://cdn.jsdelivr.net/npm/extml/dist/extml.umd.min.js](https://cdn.jsdelivr.net/npm/extml/dist/extml.umd.min.js)
- **ES:** [https://cdn.jsdelivr.net/npm/extml/dist/extml.es.min.js](https://cdn.jsdelivr.net/npm/extml/dist/extml.es.min.js)
Install Extml via npm:
```bash
$ npm install -D extml
```
---
## Examples
### Live Demo
Try Extml live on [Sencha Fiddle](https://fiddle.sencha.com/#view/editor\&fiddle/3lv6).
### Basic Example
```javascript
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
```javascript
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
```javascript
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
```javascript
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:**
```javascript
const [value, setValue] = createState(0);
setValue(value() + 1);
```
### Reactive Components
**`createEffect`** allows you to perform actions when dependencies change:
```javascript
createEffect(() => {
console.log('Value changed:', value());
}, [value]);
```
### Scoped Styling
Define styles specific to a component using the `<style>` tag:
```javascript
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:
```javascript
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:
```javascript
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:**
```javascript
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:**
```javascript
const isPositive = conditionalState(value, 'Positive', 'Negative');
```
### `createDerivedState`
**Description:** Generates a state derived from other states.
**Example:**
```javascript
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:**
```javascript
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:**
```javascript
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](http://opensource.org/licenses/MIT).
---
## Author
[Fabio Ricali](http://rica.li)