### Install slim.js using npm or yarn
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/getting-started.md
This snippet shows the commands to install the slim.js library using either npm or yarn package managers. These are the standard methods for adding JavaScript libraries to a project.
```bash
npm install slim-js
# or
yarn add slim-js
```
--------------------------------
### Install Slim.js using npm, yarn, or bower
Source: https://github.com/slimjs/slim.js/wiki/Geting-Started-with-slim.js
This snippet shows the commands to install the Slim.js library using different package managers. It covers npm, yarn, and bower for project integration.
```bash
npm install slim-js
yarn add slim-js
bower install slimjs
```
--------------------------------
### Define and register a web component with slim.js
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/getting-started.md
This JavaScript code demonstrates how to define a custom web component using slim.js. It includes defining the component's HTML template with data binding and registering the component with a custom tag name.
```javascript
import { Slim } from 'slim-js';
const myHTML = `
Welcome, {{this.username}}!
`;
class AwesomeComponent extends Slim {
constructor() {
super();
this.username = 'John Jimmy Junior';
}
}
Slim.element('my-awesome-component', myHTML, AwesomeComponent);
```
--------------------------------
### Include slim.js via CDN
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/getting-started.md
This snippet shows how to include the slim.js library in an HTML file using Content Delivery Network (CDN) links. It provides options for both IIFE/Global script tags and module script tags.
```html
```
--------------------------------
### Foreach Directive Example: Todo List in Slim.js
Source: https://context7.com/slimjs/slim.js/llms.txt
Demonstrates the usage of the Foreach directive in Slim.js to create a dynamic Todo List. It iterates over a list of todos to render each item, allowing for adding, toggling completion, and removing tasks. This example showcases template syntax, event handling, and state management within a Slim.js component.
```javascript
import { Slim } from 'slim-js';
import { tag, template } from 'slim-js/decorators';
import 'slim-js/directives';
@tag('todo-list')
@template(`
Todo List ({{this.todos.length}} items)
{{item.text}}
(Priority: {{item.priority}})
No todos found
`)
class TodoList extends Slim {
todos = [
{ id: 1, text: 'Learn slim.js', completed: true, priority: 'high' },
{ id: 2, text: 'Build an app', completed: false, priority: 'medium' },
{ id: 3, text: 'Deploy to production', completed: false, priority: 'low' }
];
filter = 'all';
nextId = 4;
get filteredTodos() {
switch (this.filter) {
case 'active': return this.todos.filter(t => !t.completed);
case 'completed': return this.todos.filter(t => t.completed);
default: return this.todos;
}
}
get completedCount() {
return this.todos.filter(t => t.completed).length;
}
addTodo(event) {
event.preventDefault();
const text = this.todoInput.value.trim();
if (text) {
this.todos = [...this.todos, {
id: this.nextId++,
text,
completed: false,
priority: 'medium'
}];
this.todoInput.value = '';
}
}
handleKeyPress(event) {
if (event.key === 'Enter') {
this.addTodo(event);
}
}
toggleTodo(item) {
item.completed = !item.completed;
this.todos = [...this.todos];
}
removeTodo(item) {
this.todos = this.todos.filter(t => t.id !== item.id);
}
clearCompleted() {
this.todos = this.todos.filter(t => !t.completed);
}
}
```
--------------------------------
### Example: :enter-key Directive
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/creating-directives.md
Demonstrates how to create a custom directive that listens for the 'Enter' key press on an input element and executes a specified function.
```APIDOC
## Example Directive: :enter-key
### Description
This example directive, `:enter-key`, adds a 'keypress' event listener to a target element. When the 'Enter' key is pressed, it executes a function defined in the attribute's value.
### Method
`DirectiveRegistry.add`
### Endpoint
N/A
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
- **directive** (Directive) - The directive object implementing the `:enter-key` logic.
- **attribute**: Returns true if the attribute name is `:enter-key`.
- **process**: Attaches a 'keypress' event listener to the `targetNode`. If the pressed key is 'Enter', it calls the function provided in the `attributeValue`. Returns `{ removeAttribute: true }` to remove the custom attribute from the DOM.
- **noExecution**: `true` to prevent Slim.js from treating the attribute value as a Handlebars expression.
### Request Example
```javascript
import { DirectiveRegistry } from 'slim-js';
DirectiveRegistry.add({
attribute: (attr, name) => name === ':enter-key',
process: (info) => {
const { targetNode, attributeValue } = info;
const fn = new Function(attributeValue);
const handleKeyboardEvent = (event) => {
if (event.key === 'Enter') {
fn.call(targetNode);
}
};
targetNode.addEventListener('keypress', handleKeyboardEvent);
return {
removeAttribute: true,
};
},
noExecution: true,
});
```
### Response
#### Success Response (200)
This directive does not return a value but modifies the DOM behavior.
#### Response Example
```html
```
### Usage
1. Import the directive file: `import './path/to/enterkey.directive.js';`
2. Apply the directive to an HTML element: ``
```
--------------------------------
### Example: :enter-key Directive for Slim.js
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/creating-directives.md
An example directive that registers a 'keypress' event listener on a target node. It executes a provided function when the 'Enter' key is pressed, demonstrating custom event handling within Slim.js directives.
```javascript
import { DirectiveRegistry } from 'slim-js';
DirectiveRegistry.add({
attribute: (attr, name) => name === ':enter-key',
process: (info) => {
const { targetNode, attributeValue } = info;
const fn = new Function(attributeValue);
const handleKeyboardEvent = (event) => {
if (event.key === 'Enter') {
fn.call(targetNode);
}
};
targetNode.addEventListener('keypress', handleKeyboardEvent);
return {
update: undefined, // no DOM updates
removeAttribute: true, // :enterKey will not appear in the browser
};
},
noExecution: true,
});
```
--------------------------------
### Using the Foreach Directive in Slim.js
Source: https://github.com/slimjs/slim.js/blob/master/README.md
This example shows how to use the `*foreach` directive in Slim.js to render a list of items from an array. It iterates over a sliced portion of the `this.users` array and displays user pictures and names. This directive is optional and part of Slim.js's directive system.
```html
{{item.name}}
```
--------------------------------
### Slim.js Custom Element Lifecycle Callbacks Example
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/component-lifecycle.md
Demonstrates the usage of various lifecycle callbacks in a Slim.js custom element. These callbacks allow developers to hook into different stages of the component's life, from before creation to after being added to the DOM.
```javascript
@tag('my-element')
@template(
`{{this.myValue}}`
)
class MyElement extends Slim {
onBeforeCreated() {
// ensures that myValue is not undefined, just before the bindings are executed
this.myValue = 1;
}
onCreated() {
// element created and bound to parent custom elements, the content is still not attached
this.loadSomeData().then((data) => doSomethingUseful(data));
}
onRender() {
// access to children is available
this.myButton.disabled = false;
}
onAdded() {
console.log('Added');
}
onRemoved() {
console.log('Removed');
}
}
```
--------------------------------
### Attribute Binding with Slim.js Directives
Source: https://context7.com/slimjs/slim.js/llms.txt
Demonstrates dynamic attribute binding in Slim.js components. It utilizes handlebars syntax for data binding and handles boolean attributes, string coercion, and style binding. This example requires the 'slim-js' library and its 'decorators' and 'directives' modules.
```javascript
import { Slim } from 'slim-js';
import { tag, template } from 'slim-js/decorators';
import 'slim-js/directives';
@tag('attribute-binding-demo')
@template(`
`)
class AttributeBindingDemo extends Slim {
isActive = true;
isLoading = false;
isChecked = false;
isRequired = true;
theme = 'light';
inputType = 'text';
placeholder = 'Enter text...';
maxLength = 100;
item = {
id: 123,
name: 'Sample Item',
status: 'active'
};
link = {
url: 'https://slimjs.com',
text: 'Visit slim.js',
external: true
};
getStyles() {
return `
background-color: ${this.theme === 'dark' ? '#333' : '#fff'};
color: ${this.theme === 'dark' ? '#fff' : '#333'};
padding: 20px;
border-radius: 8px;
`;
}
toggleActive() {
this.isActive = !this.isActive;
}
toggleTheme() {
this.theme = this.theme === 'light' ? 'dark' : 'light';
}
toggleLoading() {
this.isLoading = !this.isLoading;
}
}
```
--------------------------------
### Repeat Elements with s:repeat in Slim.js
Source: https://github.com/slimjs/slim.js/wiki/Repeating-elements-using-iterable-data-structures
This example demonstrates how to use the s:repeat attribute to dynamically generate list items from an array in a Slim.js component. The 'items' array is iterated, and each element is displayed as a list item. The 'item' variable holds the current array element, 'data_index' holds its index, and 'data_source' holds the original array.
```javascript
@tag("my-tag")
@template(`
{{item}}
`)
class MyTag extends Slim {
constructor () {
super()
this.items = ["Banana", "Orange", "Apple"]
}
}
```
--------------------------------
### Using #ref Directive in Slim.js for DOM Element References
Source: https://context7.com/slimjs/slim.js/llms.txt
This snippet demonstrates how to use the #ref directive in Slim.js to create references to DOM elements. These references are then accessible as properties on the component instance, starting from the `onCreated()` lifecycle hook. It showcases referencing form elements, inputs, buttons, and a canvas, and how to use these references for validation, event handling, and initialization.
```javascript
import { Slim } from 'slim-js';
import { tag, template } from 'slim-js/decorators';
import 'slim-js/directives';
@tag('form-demo')
@template(`
`)
class FormDemo extends Slim {
errors = { username: null, email: null };
isValid = false;
onCreated() {
// All refs are available here
console.log('Form element:', this.formElement);
console.log('Username input:', this.usernameInput);
}
onRender() {
// Initialize canvas for signature
const ctx = this.signatureCanvas.getContext('2d');
ctx.fillStyle = '#f0f0f0';
ctx.fillRect(0, 0, 400, 200);
// Focus first input
this.usernameInput.focus();
}
validateUsername() {
const value = this.usernameInput.value;
if (value.length < 3) {
this.errors = { ...this.errors, username: 'Username must be at least 3 characters' };
} else {
this.errors = { ...this.errors, username: null };
}
this.updateValidity();
}
validateEmail() {
const value = this.emailInput.value;
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(value)) {
this.errors = { ...this.errors, email: 'Please enter a valid email' };
} else {
this.errors = { ...this.errors, email: null };
}
this.updateValidity();
}
updateValidity() {
this.isValid = !this.errors.username && !this.errors.email &&
this.usernameInput.value && this.emailInput.value;
}
handleSubmit(event) {
event.preventDefault();
const formData = new FormData(this.formElement);
console.log('Submitting:', Object.fromEntries(formData));
}
resetForm() {
this.formElement.reset();
this.errors = { username: null, email: null };
this.isValid = false;
this.usernameInput.focus();
}
}
```
--------------------------------
### Enabling Interactivity for Native HTML Elements in Slim.js
Source: https://github.com/slimjs/slim.js/wiki/Events-&-Interactivity
This example shows how to enable native DOM event interactivity for native HTML elements within a Slim.js component. By using the reserved `interactive` attribute on the declared Slim element, you can ensure that native events are properly handled.
```html
```
--------------------------------
### Default Binding with s:repeat in Slim.js
Source: https://github.com/slimjs/slim.js/wiki/Repeating-elements-using-iterable-data-structures
When the 'as' keyword is omitted in the s:repeat attribute, Slim.js defaults to using 'data' as the variable name for the current array element. This example shows the equivalent HTML structure for the previous JavaScript example when 'as' is not specified.
```html
{{data}}
```
--------------------------------
### Use 'hello-world' Custom Element
Source: https://github.com/slimjs/slim.js/wiki/Home
This snippet shows how to use the custom HTML element 'hello-world' that has been defined using Slim.js. The element can be directly included in HTML, and its content will be rendered based on the 'hello-world' definition.
```html
Web-Components
```
--------------------------------
### Register Global Lifecycle Plugins with PluginRegistry.add
Source: https://context7.com/slimjs/slim.js/llms.txt
Demonstrates registering global lifecycle plugins for Slim components using PluginRegistry.add. These plugins can hook into various component phases like CREATE, RENDER, ADDED, and REMOVED, allowing for cross-cutting concerns such as logging, dependency injection, and analytics.
```javascript
import { Slim, PluginRegistry, Phase } from 'slim-js';
import { tag, template } from 'slim-js/decorators';
// Logging plugin - logs all component lifecycle events
PluginRegistry.add((phase, element) => {
const phaseName = {
[Phase.CREATE]: 'CREATE',
[Phase.RENDER]: 'RENDER',
[Phase.ADDED]: 'ADDED',
[Phase.REMOVED]: 'REMOVED'
}[phase];
console.log(`[${phaseName}] ${element.localName}`);
});
// Dependency injection plugin
const services = {
api: { fetch: (url) => fetch(url).then(r => r.json()) },
auth: { user: null, isLoggedIn: false },
config: { apiUrl: 'https://api.example.com' }
};
PluginRegistry.add((phase, element) => {
if (phase === Phase.CREATE) {
// Inject services into components that declare them
if (element.constructor.inject) {
element.constructor.inject.forEach(serviceName => {
if (services[serviceName]) {
element[serviceName] = services[serviceName];
}
});
}
}
});
// Analytics plugin
PluginRegistry.add((phase, element) => {
if (phase === Phase.ADDED && element.dataset.trackView) {
console.log('Analytics: Page view -', element.dataset.trackView);
}
});
// Component using injected services
@tag('plugin-demo')
@template(`
Plugin Demo
API URL: {{this.config?.apiUrl}}
User: {{this.auth?.user || 'Not logged in'}}
{{JSON.stringify(this.data, null, 2)}}
`)
class PluginDemo extends Slim {
static inject = ['api', 'auth', 'config'];
data = null;
async fetchData() {
try {
this.data = await this.api.fetch(this.config.apiUrl + '/data');
} catch (err) {
console.error('Fetch failed:', err);
}
}
}
```
--------------------------------
### Get All Descendants Flat Array with Slim::selectRecursive
Source: https://github.com/slimjs/slim.js/wiki/Accessing-Children
The `selectRecursive` method returns a flat array of all descendant elements of a given parent element. It counts the parent element itself but does not traverse into or count descendants of any nested Slim elements. This method is useful for getting a comprehensive list of all direct and indirect children within a specific subtree, excluding deeper Slim component internals.
```javascript
Slim.selectRecursive = function(parent) {
// Implementation details...
}
```
--------------------------------
### Create 'hello-world' Custom Element with Slim.js
Source: https://github.com/slimjs/slim.js/wiki/Home
This snippet demonstrates how to define a custom HTML element 'hello-world' using Slim.js. It includes a template for the element's content and a JavaScript class that extends Slim, handling attribute binding and initial property values. The 'autoBoundAttributes' property ensures that changes to the 'who' attribute are reflected in the component's template.
```javascript
Slim.tag(
'hello-world', // element tag name
'Hello, {{who}}', // element template as string
class HelloWorld extends Slim {
constructor () {
super();
this.who = 'World';
}
// native API
static get observedAttributes () {
return ['who'];
}
// bind attributes to properties
// when 'who' attribute changed - it is reflected to the property, and the component alters the relevant text node.
get autoBoundAttributes() {
return ['who'];
}
}
);
```
--------------------------------
### Include WebComponents polyfill in HTML
Source: https://github.com/slimjs/slim.js/wiki/Geting-Started-with-slim.js
This snippet demonstrates how to include the webcomponents-lite.js polyfill in an HTML file. This is necessary for browsers that do not natively support the Web Components specification.
```html
```
--------------------------------
### Load slim.js from CDN
Source: https://context7.com/slimjs/slim.js/llms.txt
How to include slim.js in your project by loading it directly from a CDN, supporting both IIFE/Global and ES Module formats.
```html
```
--------------------------------
### Control Shadow DOM Encapsulation with @useShadow Decorator (JavaScript)
Source: https://context7.com/slimjs/slim.js/llms.txt
The @useShadow decorator in Slim.js controls whether a component uses Shadow DOM for style encapsulation. Setting it to `false` allows the component to inherit global styles. This example demonstrates its usage with and without decorators.
```javascript
import { Slim } from 'slim-js';
import { tag, template, useShadow } from 'slim-js/decorators';
@tag('global-styled-component')
@template(`
{{this.title}}
{{this.content}}
`)
@useShadow(false) // Inherits global CSS styles
class GlobalStyledComponent extends Slim {
title = 'Card Title';
content = 'This component uses global styles from Bootstrap or other CSS frameworks.';
}
// Alternative without decorators
class AnotherComponent extends Slim {
static useShadow = false;
static template = '
Content without shadow DOM
';
}
customElements.define('another-component', AnotherComponent);
```
--------------------------------
### Advanced Data Binding with s:repeat in Slim.js
Source: https://github.com/slimjs/slim.js/wiki/Repeating-elements-using-iterable-data-structures
This example illustrates how to bind properties from both the repeated array elements and parent scope within s:repeat. The 'item' property is bound to the array element, while 'otherProperty' is bound from the parent scope to the inner text of each repeated list item.
```html
The item is {{item}} and this is {{otherProperty}}
```
--------------------------------
### Define Custom Element with Slim.js
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/API-Slim.md
Demonstrates how to create a custom web component using the Slim.js framework. This involves extending the base Slim class and defining its constructor and initial state.
```javascript
class MyCounter extends Slim {
constructor() {
super();
this.count = 0;
}
}
```
--------------------------------
### Define Custom Elements with Slim.element
Source: https://context7.com/slimjs/slim.js/llms.txt
Demonstrates creating custom elements using the Slim.element static method, suitable for simple components or those without decorators. It shows both pure render-only components and components with business logic.
```javascript
import { Slim } from 'slim-js';
import 'slim-js/directives';
// Pure render-only component
Slim.element('greeting-card', '
Hello, {{this.name}}!
Welcome to slim.js
');
// Component with business logic
class Counter extends Slim {
count = 0;
increment() {
this.count++;
}
decrement() {
this.count--;
}
}
Counter.template = '
{{this.count}}
';
customElements.define('my-counter', Counter);
// Usage in HTML:
//
//
```
--------------------------------
### Create Custom Element with Slim.element (JavaScript)
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/creating-an-element.md
Demonstrates creating custom elements using the Slim.element static function in plain JavaScript. It shows both a pure component and a component with internal state and business logic using a class that extends Slim.
```javascript
// Pure component
Slim.element(
'my-greeting',
/*html*/ `
Hello, {{this.who}}!
`
);
// Class Approach
class Greeter extends Slim {
greet(value) {
this.myGreetingRef.who = value;
}
}
Greeter.template = /*html*/ `
`;
customElements.define('welcome-app', Greeter);
```
--------------------------------
### Usage of Custom Directives in Slim.js Component
Source: https://context7.com/slimjs/slim.js/llms.txt
Demonstrates the usage of custom directives (:tooltip, :debounce-input, :enter-key) within a Slim.js component. It shows how to apply these directives to HTML elements and defines the component's methods to handle the directive logic. Dependencies include Slim.js decorators and the previously defined directives.
```javascript
@tag('custom-directive-demo')
@template(`
{{item}}
`)
class CustomDirectiveDemo extends Slim {
results = [];
search(event) {
console.log('Debounced search:', event.target.value);
// Simulated search results
this.results = ['Result 1', 'Result 2', 'Result 3'];
}
addTodo() {
const value = this.todoInput.value.trim();
if (value) {
this.results = [...this.results, value];
this.todoInput.value = '';
}
}
}
```
--------------------------------
### Create Render-Only Slim.js Component
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/API-Slim.md
Shows how to create a render-only web component using Slim.element, where the HTML template is provided directly without explicitly defining a custom class that extends Slim. The component's state is managed within the template itself.
```javascript
Slim.element(
'my-banner',
`
{{this.count}}
`
);
```
--------------------------------
### Import Slim.js using ES Modules
Source: https://github.com/slimjs/slim.js/blob/master/README.md
This snippet shows how to import the Slim.js library using standard ES module syntax. This is the recommended approach for modern JavaScript development when using bundlers or native module support.
```javascript
import { Slim } from 'slim-js';
```
--------------------------------
### Styling Slim Components with CSS Custom Properties
Source: https://github.com/slimjs/slim.js/wiki/Using-shadow-DOM
Illustrates how to use CSS custom properties for theming Slim components within Shadow DOM. A custom property '--my-color' is defined globally and then applied within the component's :host pseudo-class.
```css
/* Outside the component */
html {
--my-color: red;
}
/* Inside the custom element */
:host {
background-color: var(--my-color, white);
}
```
--------------------------------
### Manually Trigger Re-render with Utils.forceUpdate in Slim.js
Source: https://context7.com/slimjs/slim.js/llms.txt
Demonstrates how to use Utils.forceUpdate to manually trigger re-renders in Slim.js components. This is useful for mutable data patterns or when deeply nested object properties change. It takes the component instance and an optional property name to update.
```javascript
import { Slim, Utils } from 'slim-js';
import { tag, template } from 'slim-js/decorators';
import 'slim-js/directives';
@tag('mutable-data-demo')
@template(`
User: {{this.user.name}}
Score: {{this.user.stats.score}}
Level: {{this.user.stats.level}}
Items ({{this.items.length}})
{{item.name}}: {{item.quantity}}
`)
class MutableDataDemo extends Slim {
user = {
name: 'Player',
stats: {
score: 0,
level: 1
}
};
items = [
{ id: 1, name: 'Sword', quantity: 1 },
{ id: 2, name: 'Shield', quantity: 1 }
];
nextItemId = 3;
// Mutable update - requires forceUpdate
incrementScore() {
this.user.stats.score += 100;
// Only update the 'user' property bindings
Utils.forceUpdate(this, 'user');
}
levelUp() {
this.user.stats.level++;
this.user.stats.score = 0;
// Force update specific property
Utils.forceUpdate(this, 'user');
}
resetAll() {
this.user.name = 'Player';
this.user.stats.score = 0;
this.user.stats.level = 1;
this.items.forEach(item => item.quantity = 1);
// Force update all bindings
Utils.forceUpdate(this);
}
incrementItem(item) {
item.quantity++;
// Force update items array bindings
Utils.forceUpdate(this, 'items');
}
addItem() {
// Immutable approach - no forceUpdate needed
this.items = [...this.items, {
id: this.nextItemId++,
name: `Item ${this.nextItemId}`,
quantity: 1
}];
}
}
```
--------------------------------
### Include Slim.js using IIFE (No Modules)
Source: https://github.com/slimjs/slim.js/blob/master/README.md
This snippet demonstrates how to include the Slim.js library for environments that do not support ES modules, such as older browsers or specific script loading scenarios. The library will be available as a global 'Slim' object.
```html
```
--------------------------------
### Create Custom Element with Decorators (TypeScript)
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/welcome.md
Demonstrates how to create a custom web component 'my-counter' using Slim.js decorators in TypeScript. It defines a button that increments a counter and displays its value. This approach leverages TypeScript's class decorators for a more declarative syntax.
```typescript
import { Slim } from 'slim-js';
import { tag, template } from 'slim-js/decorators';
@tag('my-counter')
@template('')
class MyCounter extends Slim {
count = 0;
}
```
--------------------------------
### Initialize Google Analytics with Slim.js
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/index.html
This snippet initializes Google Analytics by creating a script tag for the analytics.js library and configuring the tracking ID. It assumes the presence of a global `ga` function, which is standard for Google Analytics.
```javascript
(function (i, s, o, g, r, a, m) { i['GoogleAnalyticsObject'] = r; (i[r] = i[r] || function () { (i[r].q = i[r].q || []).push(arguments); }), (i[r].l = 1 * new Date()); (a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]); a.async = 1; a.src = g; m.parentNode.insertBefore(a, m); })( window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga' );
ga('create', 'UA-97046917-1', 'auto');
ga('send', 'pageview');
```
--------------------------------
### Create Custom Element with Slim.element (JavaScript)
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/welcome.md
Shows how to define a custom web component 'my-counter' using the Slim.element() method in plain JavaScript. This method takes the tag name, template, and component class as arguments. It's a more traditional JavaScript approach compared to using decorators.
```javascript
import { Slim } from 'slim-js';
class MyCounter extends Slim {
count = 0;
}
Slim.element(
'my-counter',
'',
MyCounter
);
```
--------------------------------
### Binding Path Notation in Slim.js
Source: https://github.com/slimjs/slim.js/wiki/Data-Binding
Demonstrates the use of dot-notation for accessing nested properties within objects or arrays for data binding in Slim.js. This allows for deep traversal, such as accessing `user.name`. It's important to note that path binding responds to changes in the object reference itself, not to observable changes within the object's properties.
```html
Hello, {{user.name}}, your role is {{getUserRole(user)}}
```
--------------------------------
### NodeProcessInfo Type
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/creating-directives.md
Provides detailed information about the DOM node and attribute being processed by a directive.
```APIDOC
## NodeProcessInfo Type
### Description
An object containing contextual information passed to the `process` function of a directive.
### Type Definition
```typescript
type NodeProcessInfo = {
/**
* Usually, the slim.js component that owns the template. Templates can also be bound to objects or other HTMLElements.
*/
scopeNode: any | Element;
/**
* The Element containing the tested attribute
*/
targetNode: Element;
/**
* The localName of the target node.
*/
targetNodeName: string;
/**
* Reference to the tested attribute
*/
attribute: Attr;
/**
* The name of the tested attribute
*/
attributeName: string;
/**
* The DOMString value of the tested attribute
*/
attributeValue: string | null;
/**
* The handlebars custom code
*/
expression: string;
/**
* Additional payload chained through the DOM. For example, if the targetNode was generated by another directive, it can hold additional context
*/
context: any;
/**
* Property names expected to trigger updates when changed
*/
props: string[];
};
```
```
--------------------------------
### Create Custom Element with Decorators (TypeScript)
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/creating-an-element.md
Illustrates creating custom elements using Slim.js decorators in TypeScript. The @tag, @template, and @useShadow decorators are used to define the component's tag name, markup, and Shadow DOM behavior.
```typescript
import { Slim } from 'slim-js';
import { tag, template, useShadow } from 'slim-js/decorators';
@tag('my-app')
@template(/*html*/ `
`)
@useShadow(false)
class MyApp extends Slim {
private whoToGreet: string = 'John Doe';
protected greet(value = ''): void {
this.whoToGreet = value;
}
}
```
--------------------------------
### Slim.js Update Method for Data Binding
Source: https://github.com/slimjs/slim.js/wiki/Component-Lifecycle
Demonstrates the usage of the `Slim.prototype.update()` method to force the execution of bindables. It can update all bindables or specific ones when properties are provided as arguments, ensuring data consistency.
```javascript
...
onSomethingImportantHappened () {
this.updateImportantData();
this.update('data', 'someOtherImportantKey')
}
...
```
--------------------------------
### Slim.js Forced Update with Utils.forceUpdate
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/component-lifecycle.md
Illustrates how to manually trigger component updates in Slim.js using `Utils.forceUpdate`. This is useful when deeply nested properties change and the framework might not automatically detect the update, ensuring the UI reflects the latest data.
```javascript
import { Utils } from 'slim-js';
class MyComponent extends Slim {
someMethod() {
this.service.loadData().then((data) => {
this.data.someNestedProperty = data.value; // non immmutable approach, needs forced update
this.otherData.someNestedProperty = data.value;
Utils.forceUpdate(this, 'data', 'otherData'); // no need to flush all properties, just this one
});
}
someOtherMethod() {
// Some useful code that affects many properties
Utils.forceUpdate(this); // run all bindings. Will re-render only changed nodes.
}
}
```
--------------------------------
### Utilize Component Lifecycle Hooks in Slim.js (JavaScript)
Source: https://context7.com/slimjs/slim.js/llms.txt
Slim.js provides several lifecycle hooks that allow developers to tap into different phases of a component's existence, from initialization to cleanup. These hooks include `onBeforeCreated`, `onCreated`, `onRender`, `onAdded`, and `onRemoved`.
```javascript
import { Slim } from 'slim-js';
import { tag, template } from 'slim-js/decorators';
import 'slim-js/directives';
@tag('lifecycle-demo')
@template(`
{{this.title}}
Status: {{this.status}}
`)
class LifecycleDemo extends Slim {
title = 'Loading...';
status = 'initializing';
// Called before shadow DOM and bindings are created
onBeforeCreated() {
console.log('onBeforeCreated: Setting initial values');
this.title = 'Lifecycle Demo';
}
// Called after template processing, before content is attached to DOM
onCreated() {
console.log('onCreated: Template ready, starting data fetch');
this.status = 'created';
this.fetchData();
}
// Called after first render, child elements are accessible
onRender() {
console.log('onRender: Component rendered, actionBtn available:', this.actionBtn);
this.status = 'rendered';
this.actionBtn.focus();
}
// Called when component is added to DOM (connectedCallback)
onAdded() {
console.log('onAdded: Component added to document');
window.addEventListener('resize', this.handleResize);
}
// Called when component is removed from DOM (disconnectedCallback)
onRemoved() {
console.log('onRemoved: Cleanup listeners and resources');
window.removeEventListener('resize', this.handleResize);
}
handleResize = () => {
console.log('Window resized');
}
async fetchData() {
this.status = 'loading';
await new Promise(resolve => setTimeout(resolve, 1000));
this.status = 'ready';
}
doAction() {
this.status = 'action performed';
}
}
```
--------------------------------
### Create and Register Slim.js Web Component with Template
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/API-Slim.md
Utilizes the Slim.element static function to define a custom element with a specified tag name, HTML template, and base class. This function acts as a shorthand for `customElements.define` and sets the template on the base class.
```javascript
Slim.element(
'my-counter',
`
{{this.count}}
`,
class MyCounter extends Slim {
constructor() {
super();
this.count = 0;
}
}
);
```
--------------------------------
### Find All Matching Elements with Slim.prototype.findAll
Source: https://github.com/slimjs/slim.js/wiki/Accessing-Children
The `findAll` method searches an element's tree and returns an array of all descendant elements that match the provided CSS selector. Similar to `find`, it performs a deep search but does not penetrate nested shadow DOMs. If no matching elements are found, it returns an empty array.
```javascript
Slim.prototype.findAll = function(selector) {
// Implementation details...
}
```
--------------------------------
### Define a Custom Web Component with Slim.js
Source: https://github.com/slimjs/slim.js/blob/master/README.md
This snippet demonstrates how to define a custom web component using Slim.js decorators. It includes a simple counter functionality with increment and decrement buttons. Dependencies include 'slim-js' and its decorators.
```javascript
import { Slim } from 'slim-js';
import { tag, template } from 'slim-js/decorators';
@tag('my-awesome-element')
@template(`
{{this.count}}
`)
class extends Slim {
count = 0;
inc() { this.count++ }
dec() { this.count-- }
}
```
--------------------------------
### Triggering Shadow DOM Piercing Custom Events
Source: https://github.com/slimjs/slim.js/wiki/Using-shadow-DOM
Demonstrates how to create and dispatch a custom event that can bubble through Shadow DOM boundaries. Setting 'bubbles' and 'composed' to true is crucial for cross-shadow DOM communication.
```javascript
var event = new CustomEvent('event-name', {bubbles: true, composed: true})
```
--------------------------------
### Define Component Templates with @template Decorator
Source: https://context7.com/slimjs/slim.js/llms.txt
Shows how to use the @template decorator to define the HTML structure for a Slim component. It supports data binding with handlebars-like syntax `{{expression}}` and includes directives for conditional rendering and event handling.
```javascript
import { Slim } from 'slim-js';
import { tag, template } from 'slim-js/decorators';
import 'slim-js/directives';
@tag('search-box')
@template(
'
'
)
class SearchBox extends Slim {
query = '';
results = [];
isLoading = false;
error = null;
handleInput(event) {
this.query = event.target.value;
}
handleKeyPress(event) {
if (event.key === 'Enter') {
this.performSearch();
}
}
async performSearch() {
if (!this.query.trim()) return;
this.isLoading = true;
this.error = null;
try {
const response = await fetch(`/api/search?q=${encodeURIComponent(this.query)}`);
this.results = await response.json();
} catch (err) {
this.error = 'Search failed. Please try again.';
} finally {
this.isLoading = false;
}
}
}
```
--------------------------------
### Handlebars Syntax for Data Binding in HTML
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/using-directives.md
Demonstrates how to use handlebars-like syntax within HTML templates to bind component properties to DOM elements. This includes binding to attributes like 'src' and text content. Changes to properties prefixed with 'this.' trigger DOM updates.
```html
{{this.userInfo.username}}
```
--------------------------------
### Binding Data to CSS Styles with Handlebars
Source: https://github.com/slimjs/slim.js/blob/master/doc-site/public/docs/using-directives.md
Shows how to dynamically set CSS styles using handlebars syntax within a `
```
--------------------------------
### Include Slim.js using HTML with Modules
Source: https://github.com/slimjs/slim.js/blob/master/README.md
This snippet shows how to load the Slim.js library directly in an HTML file using a script tag with the 'type="module"' attribute. This approach is suitable for modern browsers that support native ES modules.
```html
```
--------------------------------
### Extend Component Behavior with Slim.js 'create' Plugin (JavaScript)
Source: https://github.com/slimjs/slim.js/wiki/Attaching-functional-plugins
This snippet demonstrates how to use the Slim.js 'create' plugin to inject custom behavior into components during their creation phase. It shows how to access and modify component properties based on their local name. This approach is useful for implementing features like dependency injection.
```javascript
import myDataModel from 'my-data-model'
Slim.plugin('create', element => {
if (element.localName === 'my-component') {
element.model = myDataModel
}
})
```