### 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)

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 ``` -------------------------------- ### 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(`
Status: {{this.isActive ? 'Active' : 'Inactive'}}
Styled content
Item: {{this.item.name}}
{{this.link.text}}
`) 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(` `) 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(`
{{this.errors.username}}
{{this.errors.email}}
`) 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 ``` -------------------------------- ### 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(`
    `) 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}})

    `) 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( '
    {{this.error}}
    ' ) 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 } }) ```