### Fetch API GET Request Example Source: https://github.com/gnat/surreal/blob/main/README.md This snippet demonstrates how to make a GET request to a '/thing' endpoint using the Fetch API and log a success message if the response is okay. It also shows how to replace the inner HTML of the clicked element with the response text. ```javascript me().on("click", async event => { let e = me(event) // EXAMPLE 1: Hit /thing endpoint. if((await fetch("/thing")).ok) console.log("Got thing.") // EXAMPLE 2: Get /thing endpoint and replace me() try { let response = await fetch('/thing') if (response.ok) e.innerHTML = await response.text() else console.warn('fetch(): Bad response') } catch (error) { console.warn(`fetch(): ${error}`) } }) ``` -------------------------------- ### Install Surreal.js via NPM Source: https://github.com/gnat/surreal/blob/main/_autodocs/configuration.md Install the Surreal.js package using npm and then import it into your JavaScript files. ```bash npm install @geenat/surreal ``` ```javascript import surreal from '@geenat/surreal' ``` -------------------------------- ### XMLHttpRequest GET Request Example Source: https://github.com/gnat/surreal/blob/main/README.md This snippet shows how to make a GET request to a '/thing' endpoint using XMLHttpRequest. It includes an example for simply sending the request and another for updating the inner HTML of the clicked element with the response text upon successful completion. ```javascript me().on("click", event => { let e = me(event) // EXAMPLE 1: Hit /thing endpoint. var xhr = new XMLHttpRequest() xhr.open("GET", "/thing") xhr.send() // EXAMPLE 2: Get /thing endpoint and replace me() var xhr = new XMLHttpRequest() xhr.open("GET", "/thing") xhr.onreadystatechange = () => { if (xhr.readyState == 4 && xhr.status >= 200 && xhr.status < 300) e.innerHTML = xhr.responseText } xhr.send() }) ``` -------------------------------- ### Working with Arrays Example Source: https://github.com/gnat/surreal/blob/main/_autodocs/README.md Shows how to apply operations and attach event listeners to multiple elements selected by `any()`. ```javascript any('button').classAdd('ready').on('click', handleClick) ``` -------------------------------- ### Convert Between Single Element and Multiple Elements Source: https://github.com/gnat/surreal/blob/main/_autodocs/QUICK-REFERENCE.md Shows how to use `me()` to get a single element and `any()` to get a collection of elements. Demonstrates converting a single element to an array-like collection and vice-versa. ```javascript // Get first button let btn = me('button') // Convert to array let arr = any(btn) // Get first from array let first = me(any('button')) ``` -------------------------------- ### Basic Class Manipulation Example Source: https://github.com/gnat/surreal/blob/main/_autodocs/README.md Demonstrates adding, removing, and toggling CSS classes on elements using Surreal.js. ```javascript me('button').classAdd('active') any('.item').classRemove('hidden') me().classToggle('expanded') ``` -------------------------------- ### Event Handling Example Source: https://github.com/gnat/surreal/blob/main/_autodocs/README.md Shows how to attach a click event listener to a button, disable it, and fade it out upon click. ```javascript me('button').on('click', (e) => { let btn = me(e) btn.disable() btn.fadeOut() }) ``` -------------------------------- ### Selecting Element with Relative Start Source: https://github.com/gnat/surreal/blob/main/README.md Demonstrates selecting an element using a relative start point, specified by `me(selector, parentElement)`. This is an alternative to `me('-')` for selecting elements within a specific context. ```javascript me('[n1]', me()).value = "hello" ``` -------------------------------- ### Animation Timeline Example Source: https://github.com/gnat/surreal/blob/main/_autodocs/README.md Demonstrates a simple asynchronous animation sequence changing an element's background color over time. ```javascript (async (el = me('div')) => { el.styles({ transition: 'all 0.3s' }) el.styles({ background: 'red' }) await sleep(300) el.styles({ background: 'blue' }) })() ``` -------------------------------- ### Non-Chainable Methods Example Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Shows examples of non-chainable methods like 'remove' which end the chain, and 'attribute' which returns a value and thus ends the chain. ```javascript me('div').remove() // void - ends chain let value = me('input').attribute('value') // string - ends chain ``` -------------------------------- ### any(selector, start, warning) Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/selectors.md Select multiple DOM elements and return them as an array. Always returns an array (empty array if nothing matches). ```APIDOC ## any(selector, start, warning) ### Description Select multiple DOM elements and return them as an array. Always returns an array (empty array if nothing matches). ### Method `any(selector=null, start=document, warning=true)` ### Parameters #### Path Parameters - **selector** (string | Event | HTMLElement | SVGElement | NodeList | Array) - Optional - CSS selector string, Event object, HTML/SVG element, or list of elements. If null, returns array containing parent of current ` ``` -------------------------------- ### Chaining Methods Example Source: https://github.com/gnat/surreal/blob/main/_autodocs/README.md Illustrates method chaining in Surreal.js to apply multiple operations (class addition and style application) to selected elements. ```javascript me('.card') .classAdd('active') .styles('background: blue') ``` -------------------------------- ### Inline Styles Example (String) Source: https://github.com/gnat/surreal/blob/main/_autodocs/README.md Applies inline CSS styles to an element using a string. ```javascript me('div').styles('color: red; padding: 1rem') ``` -------------------------------- ### me(selector, start, warning) Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/selectors.md Select a single DOM element, guaranteed to return one element or null. If multiple elements match, returns the first one. ```APIDOC ## me(selector, start, warning) ### Description Select a single DOM element, guaranteed to return one element or null. If multiple elements match, returns the first one. ### Method `me(selector=null, start=document, warning=true)` ### Parameters #### Path Parameters - **selector** (string | Event | HTMLElement | SVGElement | NodeList | Array) - Optional - CSS selector string, Event object, HTML/SVG element, or list of elements. If null, uses the parent element of the current ` ``` #### Example 2: Select element by CSS selector ```javascript // Select first button me('button').classAdd('primary') // Select element by ID me('#header').styles('background: navy') // Select element by class me('.active').attribute('data-status', 'ready') ``` #### Example 3: Select element before current script ```html ``` #### Example 4: Handle event with element saving ```javascript me().on("click", ev => { let el = me(ev) // Extract element from event if (!el) return // Null safety el.classToggle('active') }) ``` #### Example 5: Search within a specific start location ```javascript let container = me('#main') me('button', container).classAdd('main-button') ``` #### Example 6: Silent selector failure ```javascript // No warning if "nonexistent" doesn't exist me("#nonexistent", document, false)?.classAdd('hidden') ``` ``` -------------------------------- ### jQuery Style Naming Conventions Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Examples of using jQuery-style methods for class manipulation. ```javascript me().addClass('active') me().removeClass('hidden') ``` -------------------------------- ### Chainable Methods Example Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Illustrates a sequence of chainable methods to modify an element's class, styles, attributes, and attach an event listener. ```javascript me('div') .classAdd('card') .styles('padding: 1rem') .attribute('data-id', '123') .on('click', handleClick) ``` -------------------------------- ### Timeline Animation with Async/Await Source: https://github.com/gnat/surreal/blob/main/example.html This example uses async/await to create a timeline animation, changing element styles over time. It also demonstrates appending and animating a new element. ```javascript (async (e = me()) => { // Special case where we can save element right away. e.styles({"transition": "all 2s"}) e.styles({"background":"#0030F7", "color":"#002200"}) await sleep(2000) e.styles({"background":"#006BFF", "color":"#000033"}) await sleep(2000) e.styles({"background":"#00A1FF", "color":"#005500"}) await sleep(2000) e.styles({"background":"#00C08C", "color":"#660033"}) await sleep(2000) // New element! var e2 = me(createElement("div")) e2.styles({"transition":"all 2s", "opacity":"0", "height":"0%"}) e2.innerText = "🔥🔥🔥🔥🔥🔥" e.appendChild(e2) await sleep(1000) e2.styles({"opacity":"1", "height":"fit-content"}) })() ``` -------------------------------- ### Immediate Timeline Animation of Styles Source: https://github.com/gnat/surreal/blob/main/README.md This example animates an element's background color immediately upon script execution. It uses an async IIFE with `me()`, `styles()`, `sleep()`, and `remove()`. ```html
Change color every second.
``` -------------------------------- ### Camel Case Naming Conventions Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Examples of using camel case methods for class manipulation and setting class names. ```javascript me().classAdd('active') me().classRemove('hidden') me().className = 'card' ``` -------------------------------- ### Inline Styles Example (Object) Source: https://github.com/gnat/surreal/blob/main/_autodocs/README.md Applies inline CSS styles to an element using a JavaScript object. ```javascript me('div').styles({ backgroundColor: 'blue', borderRadius: '8px' }) ``` -------------------------------- ### Attribute Management Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Demonstrates how to get, set a single, or set multiple attributes on an HTML element using Surreal.js. ```javascript // Get attribute let value = me('input').attribute('value') // Set single attribute me('form').attribute('data-submitted', true) // Set multiple attributes me('form').attribute({ 'data-type': 'contact', 'aria-label': 'Contact form', 'novalidate': true }) ``` -------------------------------- ### DOM Selection Functions Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Selects a single element or the first match, or all matching elements as an array. The 'start' and 'warning' parameters are optional. ```javascript me(selector, start, warning) // Select 1 element or first match any(selector, start, warning) // Select all matching elements as array ``` -------------------------------- ### Chained DOM Manipulation Source: https://github.com/gnat/surreal/blob/main/README.md Start a chain of DOM manipulation functions using `me()` or `any()`. This is the recommended style for cleaner code. ```javascript me().classAdd('red') ``` ```javascript any("button").classAdd('red') ``` ```javascript me().on("click", ev => me(ev).fadeOut() ) ``` ```javascript any('button').on('click', ev => { me(ev).styles('color: red') }) ``` ```javascript any('button').run(_ => { alert(_) }) ``` ```javascript me().styles('color: red') ``` ```javascript me().styles({ 'color':'red', 'background':'blue' }) ``` ```javascript me().attribute('active', true) ``` -------------------------------- ### Attribute Manipulation Example (Multiple) Source: https://github.com/gnat/surreal/blob/main/_autodocs/README.md Sets multiple attributes on an element using an object. ```javascript me('form').attribute({ 'data-id': '123', 'novalidate': true }) ``` -------------------------------- ### Custom Zoom-In Effect Implementation Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/effects.md Example of creating a custom zoom-in effect using `styles()` and `tick()`. It sets initial styles, waits for them to apply, then animates to the final state. ```javascript // Custom zoom-in effect (async (el = me('div')) => { el.styles({ transition: 'all 0.3s', transform: 'scale(0)', opacity: '0' }) await tick() el.styles({ transform: 'scale(1)', opacity: '1' }) })() ``` -------------------------------- ### Retry Logic with Exponential Backoff Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/utilities.md Provides an example of implementing a fetch request with retry logic, using `sleep()` for exponential backoff between retries. ```javascript async function fetchWithRetry(url, maxRetries = 3) { let retries = 0 while (retries < maxRetries) { try { let response = await fetch(url) if (response.ok) return response } catch (e) { retries++ await sleep(1000 * retries) // Exponential backoff } } throw new Error('Max retries exceeded') } ``` -------------------------------- ### Handle Keyboard Shortcuts Source: https://github.com/gnat/surreal/blob/main/_autodocs/QUICK-REFERENCE.md Listens for keyboard events on the document to trigger actions based on key combinations. This example shows how to prevent the default browser save action and send a custom save event. ```javascript me('document').on('keydown', event => { if (event.ctrlKey && event.key === 's') { halt(event) // Prevent default save me('form').send('keyboard-save') } }) ``` -------------------------------- ### Fade In Element with Limit Source: https://github.com/gnat/surreal/blob/main/example.html This example shows how to fade in an element with a limit on the number of times the action can be performed. It uses a simple counter to enforce the limit. ```javascript me().on("click", ev => { // Simple way to limit number of actions. if(me(ev)?.fadeInLimit <= 1) return; else { me(ev).fadeInLimit = 1; me(ev).fadeIn() } }) ``` -------------------------------- ### Scoping with Block Example Source: https://github.com/gnat/surreal/blob/main/README.md Demonstrates how to use block scoping with curly braces `{}` to limit the scope of `let` variables and `function` declarations. This helps in managing variable lifetimes and avoiding naming conflicts. ```javascript { let note = "hi"; function hey(text) { alert(text) }; me().on('click', ev => { hey(note) }) } ``` -------------------------------- ### Scoping with me() Block Example Source: https://github.com/gnat/surreal/blob/main/README.md Illustrates creating a scoped function attached to a `me()` element. This allows for custom methods to be called on specific elements, enhancing reusability and organization. ```javascript me().hey = (name) => { alert(name) } me().on('click', (ev) => { me(ev).hey("hi") }) ``` -------------------------------- ### Core API Functions Source: https://github.com/gnat/surreal/blob/main/_autodocs/README.md Provides functions for selecting single or multiple DOM elements. Supports optional start nodes and warnings. ```javascript me(selector, start, warning) // Select 1 element any(selector, start, warning) // Select many elements ``` -------------------------------- ### Timeline Animation: Animate Element Styles and Remove Source: https://github.com/gnat/surreal/blob/main/README.md This example demonstrates animating an element's background color over time and then removing it. It uses `me()`, `on()`, `styles()`, `sleep()`, and `remove()`. ```html
I change color every second.
``` -------------------------------- ### Color Manipulation Plugin Example Source: https://github.com/gnat/surreal/blob/main/_autodocs/configuration.md This plugin adds `randomColor` and `rainbow` methods to elements for applying random or cycling colors. Use `me()` or `any()` to select elements and then call the plugin methods. ```javascript function pluginColors(e) { e.randomColor = function() { const colors = ['red', 'blue', 'green', 'purple', 'orange'] const random = colors[Math.floor(Math.random() * colors.length)] this.styles(`color: ${random}`) return this } e.rainbow = function() { let color = 0 const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'] const interval = setInterval(() => { this.styles(`color: ${colors[color]}`) color = (color + 1) % colors.length }, 100) return this } } surreal.plugins.push(pluginColors) // Now use: me('button').randomColor() any('.text').rainbow() ``` -------------------------------- ### Custom Event Listener Example Source: https://github.com/gnat/surreal/blob/main/_autodocs/README.md Attaches an event listener to react to a custom 'validated' event and add a class based on the event details. ```javascript me('form').on('validated', (e) => { if (e.detail.success) { me(e).classAdd('success') } }) ``` -------------------------------- ### Configuration Options Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Allows adding convenience globals to the window object and registering custom plugins. ```javascript globalsAdd() // Add convenience globals to window surreal.plugins // Array to register custom plugins ``` -------------------------------- ### Create DOM Element with Content and Event Listener Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/utilities.md Demonstrates creating an element, setting its text content, adding attributes, and attaching an event listener. ```javascript let button = createElement('button') button.textContent = 'Click Me' me(button) .attribute('data-id', '123') .on('click', (ev) => { alert('Clicked!') }) me('#container').appendChild(button) ``` -------------------------------- ### Internal fadeOut Mechanism Example Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/effects.md Illustrates the internal CSS transition logic used by the `fadeOut` effect, including setting styles, waiting for the tick, and applying transition properties. ```javascript // fadeOut internally does: styles(e, { transform: 'scale(1)', transition: `all ${ms}ms ease-out`, overflow: 'hidden' }) await tick() // Let styles apply styles(e, { transform: 'scale(0.9)', opacity: '0' }) await sleep(ms) // Optional: remove(e) ``` -------------------------------- ### Practical Attribute Manipulation Examples Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/dom-manipulation.md Illustrates common use cases for attribute manipulation, such as updating file inputs, managing form validation states with ARIA attributes, and setting custom data attributes for tracking. ```javascript // Update file input with dropped files me('#file-input').attribute('files', event.dataTransfer.files) // Form validation - set ARIA attributes let input = me('input') if (isInvalid) { input.attribute('aria-invalid', true) input.attribute('data-error', 'Required field') } else { input.attribute('aria-invalid', null) // Remove input.attribute('data-error', null) } // Custom data attributes for tracking me('.modal').attribute({ 'data-id': modalId, 'data-opened': new Date().toISOString(), 'aria-modal': 'true' }) ``` -------------------------------- ### Get and Set Element Attributes Source: https://github.com/gnat/surreal/blob/main/README.md Manages element attributes. Can get, set, or remove single or multiple attributes. For multiple elements, use `any(...).run(...)` or `any(...).forEach(...)`. ```javascript me().attribute('data-x') ``` ```javascript me().attribute('data-x', true) ``` ```javascript me().attribute({ 'data-x':'yes', 'data-y':'no' }) ``` ```javascript me().attribute('data-x', null) ``` ```javascript me().attribute({ 'data-x': null, 'data-y':null }) ``` -------------------------------- ### Configuration Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Provides options for global configuration and extending Surreal with custom plugins. ```APIDOC ## Configuration ### `globalsAdd()` Adds convenience global functions to the `window` object, making Surreal functions directly accessible without prefix. ### `surreal.plugins` An array where custom plugins can be registered to extend Surreal's functionality. ``` -------------------------------- ### Attribute Manipulation Example (Single) Source: https://github.com/gnat/surreal/blob/main/_autodocs/README.md Sets a single attribute on an element or retrieves its value. ```javascript me('input').attribute('disabled', true) let value = me('input').attribute('value') ``` -------------------------------- ### Custom Event Dispatch Example Source: https://github.com/gnat/surreal/blob/main/_autodocs/README.md Sends a custom event named 'validated' with associated details. ```javascript me('form').send('validated', { success: true }) ``` -------------------------------- ### Using `any()` for Bulk Operations Source: https://github.com/gnat/surreal/blob/main/_autodocs/configuration.md Demonstrates the efficiency of using `any()` for applying operations to multiple elements compared to iterating with `run()`. ```javascript any('button').classAdd('primary') // Better any('button').run(btn => { btn.classList.add('primary') }) // More code ``` -------------------------------- ### Dismissible alert example Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/effects.md Demonstrates fading out an alert element upon a button click, removing it from the DOM after 300ms. ```html
This is an important message
``` -------------------------------- ### Snake Case Naming Conventions Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Examples of using snake case methods for class manipulation and removing all event listeners. ```javascript me().class_add('active') me().class_remove('hidden') me().off_all() ``` -------------------------------- ### Create Element with Event Handler Source: https://github.com/gnat/surreal/blob/main/_autodocs/QUICK-REFERENCE.md Create an element, set its text content, attach an event listener using `.on()`, and then append it to the DOM. ```javascript let button = createElement('button') button.textContent = 'Click Me' me(button) .attribute('data-id', '123') .on('click', () => alert('Clicked!')) me('div').appendChild(button) ``` -------------------------------- ### Chainable vs. Functional Method Calls Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Demonstrates the recommended chainable method style for DOM manipulation and the alternative functional style via namespace. ```javascript // Chainable (method style) - recommended me('button').classAdd('active').styles('color: red') // Functional (traditional) - also supported classAdd(me('button'), 'active') styles(me('button'), 'color: red') // Via namespace surreal.me('button').classAdd('active') ``` -------------------------------- ### Get an Attribute Value Source: https://github.com/gnat/surreal/blob/main/_autodocs/QUICK-REFERENCE.md Use `attribute()` to retrieve the value of an element's attribute. Specify the attribute name as a string. ```javascript let value = me('input').attribute('value') let dataId = me('div').attribute('data-id') ``` -------------------------------- ### Create Complex Form Structure Source: https://github.com/gnat/surreal/blob/main/_autodocs/QUICK-REFERENCE.md Demonstrates creating a form with input and submit button elements, applying attributes, and appending them to the body. Uses chaining for attribute setting and event handling. ```javascript let form = createElement('form') let input = createElement('input') let button = createElement('button') me(input).attribute('type', 'text').attribute('placeholder', 'Enter name') me(button).attribute('type', 'submit').textContent = 'Submit' form.appendChild(input) form.appendChild(button) me(form) .classAdd('login-form') .on('submit', handleSubmit) me('body').appendChild(form) ``` -------------------------------- ### Get Single Element Inline Source: https://github.com/gnat/surreal/blob/main/_autodocs/QUICK-REFERENCE.md Use `me()` to select an element directly within its HTML context, ideal for inline behavior. ```html
``` -------------------------------- ### Array Iteration Methods Source: https://github.com/gnat/surreal/blob/main/README.md Demonstrates using standard JavaScript array methods like `forEach` and `map` on elements selected by `any()`. ```javascript any('button')?.forEach(...) ``` ```javascript any('button')?.map(...) ``` -------------------------------- ### Attributes Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/dom-manipulation.md Get, set, or remove attributes on elements. Supports single attributes, multiple attributes via an object, and boolean attributes. ```APIDOC ## Attributes ### `attribute(name, value)` / `attr(name, value)` / `attributes(name, value)` Get, set, or remove attributes on element(s). #### Signature ```javascript attribute(element, name, value) → string | null | HTMLElement | NodeList | Array e.attribute(name, value) → string | null | HTMLElement | NodeList | Array ``` #### Parameters - **element** (HTMLElement | NodeList | Array) - Required (method form) - The element(s) to modify. For get operations, must be a single element. - **name** (string | object) - Required - Attribute name (string) or object of attribute name-value pairs for bulk operations. - **value** (string | boolean | null) - Optional - Value to set. `undefined` = get operation. `null` = remove attribute. `true` = set empty attribute. #### Return Type - **Get operation:** `string | null` (the attribute value, null if not found) - **Set/Remove operation:** `HTMLElement | NodeList | Array` (for chaining) - **Null safety:** Returns empty array for multi-element get operations #### Behavior - **Get** (name only): Returns attribute value. Works on single elements only. - **Set** (name + value): Sets attribute to value. - **Remove** (name + null): Removes the attribute. - **Bulk** (object): Sets/removes multiple attributes at once. #### Examples #### Single attribute - Get ```javascript // Get an attribute (single element only) let status = me('#status').attribute('data-status') console.log(status) // string or null // Safe null access let value = me('input')?.attribute('value') ``` #### Single attribute - Set ```javascript // Set a single attribute me('button').attribute('data-x', 'active') // Boolean attributes me('input').attribute('disabled', true) me('input').attribute('disabled', false) // Remove by setting to null me('button').attribute('data-temp', null) // Alternative names me().attr('aria-label', 'Close dialog') me().attributes('title', 'Click to expand') ``` #### Multiple attributes - Bulk operations ```javascript // Set multiple attributes with an object me('form').attribute({ 'data-type': 'contact', 'data-version': '2', 'aria-label': 'Contact form' }) // Mix setting and removing me('input').attribute({ 'placeholder': 'Enter text', 'data-temp': null, // Remove data-temp 'disabled': true // Disable input }) ``` #### Multiple elements - Set/Remove ```javascript // Set attribute on all matching elements any('input[type="checkbox"]').attribute('data-checked', false) // Remove attribute from all elements any('[data-temp]').attribute('data-temp', null) // Chain with other operations any('button').attribute('disabled', true).styles('opacity: 0.5') ``` ``` -------------------------------- ### Plugin System: Create and Use Custom Method Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Illustrates how to create a custom plugin function that adds a new method 'myMethod' to Surreal.js elements, and then how to use this custom method. ```javascript // Create custom method function pluginCustom(e) { e.myMethod = function(param) { // Your code return e // Return for chaining } } surreal.plugins.push(pluginCustom) // Use it me('button').myMethod('value').classAdd('processed') ``` -------------------------------- ### Create and Append DOM Element Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/utilities.md Shows how to create a new DOM element using `createElement()` and append it to the document body after applying styles and classes. ```javascript let newDiv = createElement('div') me(newDiv).classAdd('card').styles('padding: 1rem') me('body').appendChild(newDiv) ``` -------------------------------- ### run() Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/dom-manipulation.md Executes a callback function on each selected element. This method is chainable and allows for complex DOM operations within a callback. ```APIDOC ## run() ### Description Executes a callback function on each selected element. This method is chainable and allows for complex DOM operations within a callback. ### Method `run(callback)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **callback** (Function) - Required - The function to execute for each element. It receives the element as its only argument. ### Request Example ```javascript // Run function on single element me('button').run(btn => { btn.textContent = btn.textContent.toUpperCase() }) // Run on multiple elements any('li').run(li => { console.log(li.textContent) }) ``` ### Response #### Success Response (200) - **HTMLElement | NodeList | Array** - The element(s) for chaining. ``` -------------------------------- ### Async/Await Patterns: Sequential, Tick, and Staggered Operations Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Illustrates asynchronous operations using async/await, including sequential style changes with 'tick()', waiting with 'sleep()', and staggered element activation. ```javascript // Sequential operations (async (el = me('div')) => { el.styles({ opacity: '0' }) await tick() // Wait for style to apply el.styles({ transition: 'opacity 0.3s', opacity: '1' }) })() // Wait for completion await sleep(1000) // Staggered operations for (let item of any('.item')) { me(item).classAdd('active') await sleep(100) } ``` -------------------------------- ### Dynamically Creating Complex Elements Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Demonstrates how to dynamically create complex HTML elements using 'createElement', then manipulate them with Surreal.js methods for styling, attributes, and appending to the DOM. ```javascript let card = createElement('div') me(card) .classAdd('card') .attribute('data-id', '123') .styles({ padding: '1rem', borderRadius: '8px', boxShadow: '0 2px 4px rgba(0,0,0,0.1)' }) let title = createElement('h2') title.textContent = 'Card Title' card.appendChild(title) me('body').appendChild(card) ``` -------------------------------- ### Create and Style an Element Source: https://github.com/gnat/surreal/blob/main/_autodocs/QUICK-REFERENCE.md Use `createElement()` to create a new DOM element and then chain SurrealJS methods like `.classAdd()` and `.styles()` to configure it before appending. ```javascript let card = createElement('div') me(card).classAdd('card').styles({ padding: '1rem', borderRadius: '8px', boxShadow: '0 2px 4px rgba(0,0,0,0.1)' }) me('body').appendChild(card) ``` -------------------------------- ### Integrating Surreal.js with HTMX Source: https://github.com/gnat/surreal/blob/main/_autodocs/configuration.md Example of using Surreal.js event listeners within an HTMX-powered button to add a success class after a request completes. ```html ``` -------------------------------- ### Get Attribute Value Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/dom-manipulation.md Retrieve the value of a specific attribute from a single element using `attribute()` or its aliases. Returns `null` if the attribute is not found. ```javascript // Get an attribute (single element only) let status = me('#status').attribute('data-status') console.log(status) // string or null // Safe null access let value = me('input')?.attribute('value') ``` -------------------------------- ### Alternatives for DOM Manipulation on Load Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/utilities.md Compares different methods for applying classes to elements once they are ready, including script placement, optional chaining, and onloadAdd. ```javascript // Alternative 1: Place // Alternative 2: Use optional chaining // me('#content')?.classAdd('loaded') // Alternative 3: Use onloadAdd for guaranteed execution onloadAdd(() => { me('#content').classAdd('loaded') }) ``` -------------------------------- ### run(element, f) Source: https://github.com/gnat/surreal/blob/main/_autodocs/API-SIGNATURES.md Executes a function on each element in a collection. This is a shorthand for `forEach` and is chainable. ```APIDOC ## run(element, f) ### Description Executes a function on each element in a collection. This is a shorthand for `forEach` and is chainable. ### Parameters - **element** (HTMLElement | NodeList | Array) - The element(s) to iterate over. - **f** (Function(element)) - The function to execute for each element. ### Returns - `HTMLElement | NodeList | Array` - The element(s) the function was run on. ``` -------------------------------- ### Attribute Manipulation: attribute() Source: https://github.com/gnat/surreal/blob/main/_autodocs/API-SIGNATURES.md Manages element attributes. Can be used to get, set, or remove attributes, or perform bulk operations. Chainable for set/remove operations. ```typescript // Get operation attribute( element: HTMLElement, name: string, value?: undefined ) → string | null ``` ```typescript // Set/Remove operation attribute( element: HTMLElement | NodeList | Array, name: string, value: string | boolean | null ) → HTMLElement | NodeList | Array ``` ```typescript // Bulk operation attribute( element: HTMLElement | NodeList | Array, name: { [key: string]: string | boolean | null } ) → HTMLElement | NodeList | Array ``` -------------------------------- ### Select Parent Element with `any()` Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/selectors.md Use `any()` without a selector to get an array containing the parent element of the current script tag, useful when expecting an array. ```javascript any() ``` -------------------------------- ### Creating a Custom Surreal.js Plugin Source: https://github.com/gnat/surreal/blob/main/README.md This snippet defines a function `pluginHello` that adds a `hello` method to Surreal.js elements. It demonstrates how to extend Surreal's functionality by pushing custom plugins into the `surreal.plugins` array. ```javascript function pluginHello(e) { function hello(e, name="World") { console.log(`Hello ${name} from ${e}`) return e // Make chainable. } // Add sugar e.hello = (name) => { return hello(e, name) } } surreal.plugins.push(pluginHello) ``` -------------------------------- ### Run Function on Each Element in a Collection Source: https://github.com/gnat/surreal/blob/main/_autodocs/QUICK-REFERENCE.md Demonstrates iterating over a collection of elements using `forEach`, `run()`, and `map`. `run()` is a convenient alias for `forEach`, and `map()` is used when return values are needed. ```javascript // forEach style any('button').forEach(btn => { btn.textContent = btn.textContent.toUpperCase() }) // Using run() any('button').run(btn => { btn.textContent = btn.textContent.toUpperCase() }) // Using map (if you need return values) let titles = any('h2').map(h => h.textContent) ``` -------------------------------- ### Return Type Rules Source: https://github.com/gnat/surreal/blob/main/_autodocs/API-SIGNATURES.md Explains the conventions for return types in Surreal.js methods, including chainable methods, non-chainable methods, get operations, and multi-element operations. ```typescript - Chainable methods: Return the element(s) for continued chaining - Non-chainable methods: Return void (end the chain) - Get operations: Return the retrieved value (string, null, etc.) - Multi-element methods: Work on both single elements and arrays - Array methods: `forEach()`, `map()`, `filter()` all work on results from `any()` ``` -------------------------------- ### attribute(element, name, value) Source: https://github.com/gnat/surreal/blob/main/_autodocs/API-SIGNATURES.md Gets, sets, or removes attributes on one or more elements. The behavior depends on the arguments provided. It can be chainable when setting or removing attributes. ```APIDOC ## attribute(element, name, value) ### Description Gets, sets, or removes attributes on one or more elements. The behavior depends on the arguments provided. It can be chainable when setting or removing attributes. ### Parameters - **element** (HTMLElement | NodeList | Array) - The element(s) to operate on. - **name** (string | object) - The name of the attribute to get/set, or an object of attribute key-value pairs to set. - **value** (string | boolean | null | undefined) - Optional - The value to set for the attribute. If `undefined`, it performs a get operation. If `null`, it removes the attribute. ### Returns - `string | null` - If getting an attribute. - `HTMLElement | NodeList | Array` - If setting or removing an attribute. ``` -------------------------------- ### Common Parameter Types Source: https://github.com/gnat/surreal/blob/main/_autodocs/API-SIGNATURES.md Illustrates common parameter types used across Surreal.js functions, such as selectors, start locations, callbacks, timing, and CSS values. ```typescript // Selectors selector: string | Event | HTMLElement | SVGElement | NodeList | Array | null // Start location start: HTMLElement | Document = document // Callback functions f: Function(element) handler: Function(event) callback: Function(element) // Timing (milliseconds) ms: number duration: number = 1000 // CSS name: string // CSS class name value: string | object | null // CSS styles or attribute value ``` -------------------------------- ### Registering Custom Effects Plugin Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/effects.md Shows how to register custom effects by defining a plugin function and pushing it to the `surreal.plugins` array. The custom effect function should return `e` for chaining. ```javascript function pluginMyEffects(e) { e.myEffect = function(duration) { // Your effect code here return e // Return for chaining if desired } } surreal.plugins.push(pluginMyEffects) ``` -------------------------------- ### Validate CSS selector Source: https://github.com/gnat/surreal/blob/main/_autodocs/API-SIGNATURES.md Returns true if the provided string is a valid CSS selector that matches elements. Optionally takes a starting element and a warning flag. ```typescript isSelector( selector?: string, start?: HTMLElement | Document, warning?: boolean ) → boolean ``` -------------------------------- ### Dispatch and Listen for Custom Events Source: https://github.com/gnat/surreal/blob/main/_autodocs/QUICK-REFERENCE.md Use `.send()` to dispatch custom events with data and `.on()` to listen for them. ```javascript // Dispatch event with data me('form').send('submit-success', { message: 'Form submitted!', timestamp: Date.now() }) // Listen for custom event me('form').on('submit-success', event => { console.log(event.detail.message) me(event).classAdd('success') }) ``` -------------------------------- ### Utilities Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md A collection of utility functions for asynchronous operations, animation frame requests, DOM creation, and managing `onload` handlers. ```APIDOC ## Utilities (5 global functions + 1 internal) ### `sleep(ms, data)` Returns a Promise that resolves after a specified number of milliseconds `ms`. Optionally carries `data`. ### `tick()` Returns a Promise that resolves on the next animation frame. ### `rAF(f)` Shorthand for `requestAnimationFrame`, executing function `f` on the next animation frame. ### `rIC(f)` Shorthand for `requestIdleCallback`, executing function `f` when the browser is idle. ### `createElement(tagName)` Creates a new HTML element with the specified tag name. Alias: `create_element`. ### `onloadAdd(f)` Adds a function `f` to be executed when the DOM is fully loaded. Aliases: `onload_add`, `addOnload`, `add_onload`. ``` -------------------------------- ### Search within a Specific DOM Context Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/selectors.md Limit the search scope for selectors by providing a starting element. This is useful for scoping selections within a particular container. ```javascript let container = me('#main') me('button', container).classAdd('main-button') ``` -------------------------------- ### Select and Manipulate Elements Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Shows how to select a single element and chain methods like 'classAdd' and 'styles', or select multiple elements and attach event listeners. ```javascript // Single element me('button').classAdd('primary').styles('padding: 1rem') // Multiple elements any('button').classAdd('clickable').on('click', handleClick) ``` -------------------------------- ### Saving Element References for Async Operations Source: https://github.com/gnat/surreal/blob/main/_autodocs/api-reference/event-handling.md Capture the element reference using `me(event)` within an event handler to use it later, for example, after an asynchronous operation completes. ```javascript me('button').on('click', async event => { let el = me(event) // Save element reference el.disable() await sleep(1000) el.styles('background: green') }) ``` -------------------------------- ### Close Element from Child Event Source: https://github.com/gnat/surreal/blob/main/example.html This example shows how a child element can trigger a 'close' event on its parent, which then fades out the parent. It uses event delegation and custom events. ```javascript me().on("close", async event => { me(event).fadeOut() }) // Recieve "close" event. me().on("click", event => { me(event).disable(); me(event).send("close") }) ``` -------------------------------- ### Multi-element Operations Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Demonstrates how chainable methods can be applied to multiple elements selected using 'any()', affecting all matched elements. ```javascript // All chainable methods work on arrays too any('button') .classAdd('primary') .on('click', handleClick) .attribute('data-role', 'main') ``` -------------------------------- ### Perform Asynchronous Operations with `sleep` Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Utilize `async/await` with the `sleep` utility function to introduce delays in your JavaScript execution. This example waits for 1 second before adding a class to a button. ```javascript (async () => { await sleep(1000) me('button').classAdd('ready') })() ``` -------------------------------- ### Utilities Functions Source: https://github.com/gnat/surreal/blob/main/_autodocs/README.md Helper functions for asynchronous operations, animation frames, and DOM creation. ```APIDOC ## Utilities ### `sleep(ms, data)` Asynchronously pauses execution for a specified duration. ### `tick()` Waits for the next animation frame. ### `rAF(callback)` Schedules a callback to run on the next animation frame. ### `rIC(callback)` Schedules a callback to run during idle time (requestIdleCallback). ### `createElement(tagName)` Creates a new DOM element with the specified tag name. ### `onloadAdd(callback)` Adds a callback to the window.onload event chain. ``` -------------------------------- ### Element Selection Types Source: https://github.com/gnat/surreal/blob/main/_autodocs/INDEX.md Provides examples of various selector types supported by Surreal.js, including element, class, ID, attribute, combinators, multiple selectors, and relative selectors. ```javascript me() // Parent of current ``` -------------------------------- ### Include Surreal.js via File Download Source: https://github.com/gnat/surreal/blob/main/_autodocs/configuration.md Include the downloaded surreal.js file in your HTML's head section. ```html ```