appblocks
Version:
A lightweight javascript library for building micro apps for the front-end.
707 lines (480 loc) • 13.2 kB
Markdown
# API Reference
Complete reference for AppBlocks configuration options, methods, and APIs.
## Table of Contents
- [Configuration Options](#configuration-options)
- [Instance Methods](#instance-methods)
- [Built-in Methods](#built-in-methods)
- [State Properties](#state-properties)
- [Utilities](#utilities)
---
## Configuration Options
Options passed to `new AppBlock(config)`:
### el
**Type:** `HTMLElement` (required)
The DOM element where the AppBlock will render.
```js
el: document.getElementById('app')
```
### template
**Type:** `HTMLTemplateElement` (optional)
A `<template>` element containing the app's markup. If not provided, AppBlocks uses the content of `el`.
```js
template: document.getElementById('appTemplate')
```
**Alternative:** Use `el` content directly:
```js
// No template provided - uses content from el
var app = new AppBlock({
el: document.getElementById('app')
// AppBlocks will use existing content in #app
});
```
### data
**Type:** `Object` (optional, default: `{}`)
The reactive data object for your application.
```js
data: {
message: "Hello",
count: 0,
items: [],
user: {
name: "Alice",
email: "alice@example.com"
}
}
```
[📖 Learn more about Data](data.md)
### methods
**Type:** `Object` (optional, default: `{}`)
Custom methods for your application logic.
**Signature:** `methodName(appInstance, ...params) {}`
```js
methods: {
increment(app) {
app.setData({ count: app.data.count + 1 });
},
greet(app, name) {
return "Hello, " + name + "!";
}
}
```
[📖 Learn more about Methods](methods.md)
### filters
**Type:** `Object` (optional, default: `{}`)
Custom filters for transforming data in templates.
**Signature:** `filterName(appInstance, value) { return transformedValue }`
```js
filters: {
uppercase(app, value) {
return value.toUpperCase();
},
currency(app, value) {
return '$' + parseFloat(value).toFixed(2);
}
}
```
[📖 Learn more about Filters](filters.md)
### directives
**Type:** `Object` (optional, default: `{}`)
Custom directives for controlling element rendering.
**Signature:** `directiveName(appInstance, node, pointers) { return boolean }`
```js
directives: {
'c-custom': function(app, node, pointers) {
// Custom logic
return true; // Show element
}
}
```
[📖 Learn more about Directives](directives.md)
### events
**Type:** `Object` (optional, default: `{}`)
Event listeners for user interactions.
**Format:** `"eventName selector": function(event, matchedElement) {}`
```js
events: {
'click #submit-btn': function(e, element) {
this.Parent.setData({ submitted: true });
},
'input .search-field': function(e, element) {
this.Parent.setData({ query: element.value });
},
// Complex selectors with descendant combinators
'click .todo-list li .delete-btn': function(e, element) {
// Handle nested element clicks
}
}
```
**Event Delegation:** AppBlocks uses event delegation. The event listener is attached to the root element (`el`) and uses `element.closest()` to match the selector. This supports complex selectors with spaces and descendant combinators.
### name
**Type:** `String` (optional, default: `"AppBlock"`)
A unique name for the AppBlock instance, useful for debugging.
```js
name: "TodoApp"
```
Errors from this app will include the name: `[TodoApp] Error message`
### renderEngine
**Type:** `String` (optional, default: `"Idiomorph"`)
The rendering strategy to use.
**Options:**
- `"Idiomorph"` - Smart DOM diffing (preserves element state)
- `"plain"` - Full DOM replacement (faster but resets state)
```js
renderEngine: "Idiomorph" // Recommended
```
**Idiomorph (default):**
- Uses [Idiomorph](https://github.com/bigskysoftware/idiomorph) for intelligent DOM diffing
- Only updates changed elements
- Preserves element state (focus, scroll position, form values)
- Slightly slower but provides better UX
**Plain:**
- Replaces entire DOM tree
- Faster rendering
- Resets all element states
- Use for static content or when state preservation isn't needed
### delimiters
**Type:** `Array<String>` (optional, default: `['{', '}']`)
Custom placeholder delimiters for templates.
```js
delimiters: ['[[', ']]']
```
```html
<template id="appTemplate">
<p>[[data.message]]</p>
<p>[[data.name|uppercase]]</p>
</template>
```
**Requirements:**
- Must be an array of exactly 2 non-empty strings
- First element is the opening delimiter
- Second element is the closing delimiter
- Invalid configurations fall back to default `['{', '}']` with a console error
### allowBuiltins
**Type:** `Array<String>` (optional, default: `[]`)
Allow specific JavaScript built-in objects in expression evaluation (for `c-if`, `c-ifnot`, etc.).
```js
allowBuiltins: ['Math', 'Date']
```
```html
<template id="appTemplate">
<p c-if="Math.max(data.score, 50) > 60">High score!</p>
<p>{Math.round(data.value * 100) / 100}</p>
</template>
```
**Security:** By default, built-ins are blocked to prevent unsafe code execution. Only enable trusted built-ins when needed.
**Common built-ins:**
- `Math` - Mathematical operations
- `Date` - Date manipulation
- `String`, `Number`, `Array`, `Object` - Type utilities
---
## Instance Methods
Methods available on AppBlock instances (`app.methodName()`):
### setData()
Updates data and triggers automatic re-rendering.
**Signature:** `setData(newData, replaceData = false)`
**Parameters:**
- `newData` (Object): Data to update
- `replaceData` (Boolean): If `true`, replaces all data. Default: `false` (merges)
```js
// Partial update (merge)
app.setData({ count: 5 });
// Complete replacement
app.setData({ count: 5 }, true);
```
[📖 Learn more about Data Updates](data.md#updating-data)
### render()
Manually triggers a re-render. Useful when updating data directly without `setData()`.
**Signature:** `render(callback)`
**Parameters:**
- `callback` (Function, optional): Called after render completes
```js
// Direct data update
app.data.count++;
app.data.message = "Updated";
// Manually render
app.render(function() {
console.log('Render complete');
});
```
### resetState()
Resets request state flags (`isLoading`, `isSuccessful`, `hasError`).
**Signature:** `resetState()`
```js
app.resetState();
// All state flags are now false
```
Useful before making a new request to clear previous states.
### fetchRequest()
Makes an HTTP request using the Fetch API with automatic state management.
**Signature:** `fetchRequest(url, options, callbacks, delay)`
**Parameters:**
- `url` (String): Request URL
- `options` (Object): Fetch options (method, headers, body, etc.)
- `callbacks` (Object): Success, error, and finally callbacks
- `delay` (Number, optional): Delay in milliseconds
```js
app.fetchRequest(
'https://api.example.com/data',
{
method: 'GET',
headers: { 'Content-Type': 'application/json' }
},
{
success: function(data) {
app.setData({ items: data });
},
error: function(err) {
console.error(err);
},
finally: function() {
console.log('Request complete');
}
},
300 // 300ms delay
);
```
[📖 Learn more about Requests](requests.md#fetchrequest)
### axiosRequest()
Makes an HTTP request using Axios with automatic state management.
**Signature:** `axiosRequest(config, callbacks, delay)`
**Requires:** Axios library must be loaded
**Parameters:**
- `config` (Object): Axios configuration
- `callbacks` (Object): Success, error, and finally callbacks
- `delay` (Number, optional): Delay in milliseconds
```js
app.axiosRequest(
{
url: 'https://api.example.com/data',
method: 'POST',
data: { name: 'John' }
},
{
success: function(response) {
app.setData({ result: response.data });
},
error: function(err) {
console.error(err);
}
}
);
```
[📖 Learn more about Requests](requests.md#axiosrequest)
---
## Built-in Methods
Methods automatically available in `app.methods`:
### beforeRender()
Called before each render. Override to run custom logic.
**Signature:** `beforeRender(appInstance)`
```js
methods: {
beforeRender(app) {
console.log('About to render with data:', app.data);
}
}
```
### afterRender()
Called after each render completes. Override to run custom logic.
**Signature:** `afterRender(appInstance)`
```js
methods: {
afterRender(app) {
console.log('Render complete');
// Example: Initialize third-party plugins
initializeTooltips();
}
}
```
### isLoading()
Returns `true` if a request is in progress.
**Signature:** `isLoading(appInstance)` → `Boolean`
```html
<p c-if="isLoading()">Loading...</p>
```
### isSuccessful()
Returns `true` if the last request succeeded.
**Signature:** `isSuccessful(appInstance)` → `Boolean`
```html
<div c-if="isSuccessful()">
Data loaded successfully!
</div>
```
### hasError()
Returns `true` if the last request failed.
**Signature:** `hasError(appInstance)` → `Boolean`
```html
<div c-if="hasError()">
An error occurred. Please try again.
</div>
```
---
## State Properties
Properties on the AppBlock instance:
### data
**Type:** `Object`
The reactive data object.
```js
app.data.count; // Access
app.data.count = 10; // Direct update (requires manual render)
```
### state
**Type:** `Object`
Internal state object with request status flags.
```js
app.state = {
loading: false,
success: false,
error: false
}
```
**Access via methods:** Use `isLoading()`, `isSuccessful()`, `hasError()` in templates instead of accessing `state` directly.
### el
**Type:** `HTMLElement`
The root DOM element of the AppBlock.
```js
app.el.classList.add('ready');
```
### template
**Type:** `DocumentFragment`
The template content.
```js
// Usually you don't access this directly
console.log(app.template);
```
### methods
**Type:** `Object`
The methods object.
```js
// Call a method
app.methods.myMethod(app, arg1, arg2);
```
### filters
**Type:** `Object`
The filters object.
```js
// Call a filter
var result = app.filters.uppercase(app, 'hello');
```
### directives
**Type:** `Object`
The directives object.
```js
// Usually you don't access this directly
console.log(app.directives);
```
### events
**Type:** `Object`
The events object.
```js
// Usually you don't access this directly
console.log(app.events);
```
### name
**Type:** `String`
The name of the AppBlock instance.
```js
console.log(app.name); // "TodoApp"
```
### renderEngine
**Type:** `String`
The active render engine.
```js
console.log(app.renderEngine); // "Idiomorph" or "plain"
```
---
## Utilities
Helper functions available at `app.utils`:
### getNode()
Returns the first element matching a selector within the AppBlock.
**Signature:** `getNode(selector)` → `Element | null`
```js
var button = app.utils.getNode('#submit-btn');
```
[📖 Learn more about Utilities](utils.md#getnode)
### getNodes()
Returns all elements matching a selector within the AppBlock.
**Signature:** `getNodes(selector)` → `NodeList`
```js
var items = app.utils.getNodes('.list-item');
```
[📖 Learn more about Utilities](utils.md#getnodes)
### appendIn()
Inserts HTML at the end of an element.
**Signature:** `appendIn(html, node)`
```js
app.utils.appendIn('<p>New content</p>', targetElement);
```
[📖 Learn more about Utilities](utils.md#appendin)
### prependIn()
Inserts HTML at the beginning of an element.
**Signature:** `prependIn(html, node)`
```js
app.utils.prependIn('<p>New content</p>', targetElement);
```
[📖 Learn more about Utilities](utils.md#prependin)
### hasOwn()
Checks if an object has a specific own property.
**Signature:** `hasOwn(obj, key)` → `Boolean`
```js
if (app.utils.hasOwn(data, 'name')) {
// Property exists
}
```
[📖 Learn more about Utilities](utils.md#hasown)
### isObject()
Determines if a value is a plain object.
**Signature:** `isObject(value)` → `Boolean`
```js
if (app.utils.isObject(data.user)) {
// Is an object
}
```
[📖 Learn more about Utilities](utils.md#isobject)
### deepClone()
Creates a deep copy of a value.
**Signature:** `deepClone(value)` → `Any`
```js
var copy = app.utils.deepClone(app.data.user);
```
[📖 Learn more about Utilities](utils.md#deepclone)
---
## Quick Reference
### Creating an AppBlock
```js
var app = new AppBlock({
el: document.getElementById('app'),
template: document.getElementById('appTemplate'),
name: 'MyApp',
renderEngine: 'Idiomorph',
delimiters: ['{', '}'],
allowBuiltins: [],
data: { /* ... */ },
methods: { /* ... */ },
filters: { /* ... */ },
directives: { /* ... */ },
events: { /* ... */ }
});
```
### Common Operations
```js
// Update data and re-render
app.setData({ count: 5 });
// Update data directly and manually render
app.data.count = 5;
app.render();
// Make HTTP request
app.fetchRequest(url, options, callbacks, delay);
// Reset request state
app.resetState();
// Access utilities
app.utils.getNode('#element');
```
---
## See Also
- [Getting Started](README.md)
- [Data Management](data.md)
- [Filters](filters.md)
- [Directives](directives.md)
- [Methods](methods.md)
- [HTTP Requests](requests.md)
- [Utilities](utils.md)