{"id":15579,"library":"css-chain-test","title":"CssChain & ApiChain Utility","description":"css-chain-test (version 1.1.9) is a JavaScript/TypeScript package that serves as a demonstration and test suite for the underlying `CssChain` and `ApiChain` modules. These modules provide a lightweight, chainable API for manipulating collections of DOM elements or plain JavaScript objects. `CssChain` extends native DOM element methods and Array prototypes to allow for fluent, jQuery-like selection and manipulation, enabling operations such as adding event listeners or setting attributes on multiple elements in a single chained call. `ApiChain` offers similar chaining capabilities for arbitrary arrays of JavaScript objects. The package features recent updates focusing on improved TypeScript typings, enhanced shadow DOM support, and unified chain return types. It distinguishes itself by directly extending native browser APIs with a focus on a minimal footprint and modern module support, offering an alternative to heavier DOM manipulation libraries. The release cadence appears active, with frequent minor updates addressing features and typings.","status":"active","version":"1.1.9","language":"javascript","source_language":"en","source_url":"https://github.com/sashafirsov/css-chain-test","tags":["javascript","typescript"],"install":[{"cmd":"npm install css-chain-test","lang":"bash","label":"npm"},{"cmd":"yarn add css-chain-test","lang":"bash","label":"yarn"},{"cmd":"pnpm add css-chain-test","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The `CssChain` function acts as both a selector and a chain initiator. For ESM, use named import. CommonJS `require` might result in an object containing `CssChain` rather than the function directly, or issues with default export patterns.","wrong":"const CssChain = require('css-chain-test');","symbol":"CssChain","correct":"import { CssChain } from 'css-chain-test';"},{"note":"The `$` alias for `CssChain` is a common pattern for brevity, but it must be imported as a named export and aliased, not as a default export.","wrong":"import $ from 'css-chain-test';","symbol":"$ (alias for CssChain)","correct":"import { CssChain as $ } from 'css-chain-test';"},{"note":"ApiChain provides a similar chaining interface for plain JavaScript objects, often imported alongside CssChain for mixed DOM/data manipulation.","wrong":"const ApiChain = require('css-chain-test').ApiChain;","symbol":"ApiChain","correct":"import { ApiChain } from 'css-chain-test';"}],"quickstart":{"code":"import { CssChain as $, ApiChain } from 'css-chain-test';\n\n// === CssChain: DOM Manipulation ===\n// Create some dummy HTML for demonstration\ndocument.body.innerHTML = `\n  <div id=\"app\">\n    <button class=\"my-button\" title=\"Click me\">Button 1</button>\n    <button class=\"my-button\" title=\"Don't click me\">Button 2</button>\n    <a href=\"#\" class=\"my-link\">Link 1</a>\n    <input type=\"text\" class=\"my-input\" value=\"Initial Value\">\n    <div class=\"container\">\n        <span class=\"nested-span\">Nested Span</span>\n    </div>\n  </div>\n`;\n\n// Select all buttons and add a click listener, then remove their title\n$('button.my-button')\n  .on('click', (event) => {\n    const target = event.target as HTMLElement;\n    console.log(`Button clicked: ${target.textContent} (title was: ${target.title})`);\n    target.style.backgroundColor = 'lightblue';\n  })\n  .attr('data-clicked', 'true') // Set a data attribute\n  .removeAttribute('title'); // Remove the title attribute after setup\n\n// Select an input and set its value, then retrieve it\nconst inputField = $('input.my-input');\ninputField.value = 'New Value Set By CssChain'; // Set property for all selected inputs\nconsole.log(`Input value (from first element): ${inputField.value}`); // Get property from first element\n\n// Chain multiple event listeners for a link\n$('a.my-link')\n  .on('mouseover', (ev) => (ev.target as HTMLElement).classList.add('hovered'))\n  .on('mouseleave', (ev) => (ev.target as HTMLElement).classList.remove('hovered'))\n  .text('Hover and click this link!');\n\n// Query for children within a selected container\n$('div#app')\n  .$('.nested-span') // Alias for querySelectorAll\n  .text('Updated Nested Span Text')\n  .css('color', 'green');\n\n// === ApiChain: Object Manipulation ===\nconst data = [\n  { id: 1, name: 'Alice', active: true },\n  { id: 2, name: 'Bob', active: false },\n  { id: 3, name: 'Charlie', active: true }\n];\n\nconst chainedData = ApiChain(data);\n\n// Set a property on all objects\nchainedData.active = false;\nconsole.log('All data objects made inactive:', chainedData.map(d => d.active));\n\n// Get a property from the first object\nconst firstId = chainedData.id;\nconsole.log('ID of the first object:', firstId);\n\n// You can still use array methods\nconst activeUsers = chainedData.filter(user => user.active); // Will be empty now\nconsole.log('Active users after setting all to false:', activeUsers);\n\n// Let's create a new chain and modify it\nconst moreData = ApiChain([\n    { category: 'A', value: 10 },\n    { category: 'B', value: 20 },\n    { category: 'A', value: 15 }\n]);\n\nconst sumValues = moreData.reduce((sum, item) => sum + item.value, 0);\nconsole.log('Sum of values in moreData:', sumValues);\n\n// Filter and then set a property\nmoreData.filter(item => item.category === 'A').status = 'processed';\nconsole.log('More data after processing category A:', moreData);","lang":"typescript","description":"This quickstart demonstrates both CssChain for DOM manipulation (selecting elements, adding events, setting attributes/properties, chaining queries) and ApiChain for object array manipulation (setting properties, filtering, reducing) in a web browser environment."},"warnings":[{"fix":"Use `$('input').map(el => el.value)` or `$('input').forEach(el => console.log(el.value))` to access properties on all elements.","message":"Reading properties from a `CssChain` collection (e.g., `$('input').value`) only returns the value from the *first* element in the collection. To retrieve values from all matching elements, use `map()` or explicit iteration.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Be aware that assignments affect the entire collection. If you need to update a single element, select it specifically (e.g., `$('#my-input').value = 'single'`).","message":"When assigning a property to a `CssChain` collection (e.g., `$('input').value = 'new'`), the property is set for *all* elements currently within that collection.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Review type definitions and ensure compatibility with the unified chain return types. Re-test chaining logic, especially for custom extensions or complex sequences.","message":"Prior to version 1.1.9, the return types for some chained methods might have been inconsistent. Applications strictly relying on specific TypeScript return types or chaining assumptions might need minor adjustments after upgrading.","severity":"breaking","affected_versions":"<1.1.9"},{"fix":"Always use `remove(eventName, cb)` to detach listeners when elements are removed from the DOM or no longer needed. Consider using delegated event listeners for performance in large collections.","message":"Using `on()` (alias for `addEventListener`) or `remove()` (alias for `removeEventListener`) with a `CssChain` collection attaches or detaches the event listener to *each* element in the collection. Ensure proper cleanup to avoid memory leaks if elements or listeners are frequently added/removed.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure `CssChain` is imported as a named export for ESM (`import { CssChain } from 'css-chain-test';`) and called directly as a function: `CssChain('selector')`. For CommonJS, use `const { CssChain } = require('css-chain-test');`.","cause":"Attempting to call `CssChain` as a constructor (`new CssChain()`) or an incorrect import mechanism (e.g., CommonJS `require` in an ESM context, or vice-versa) prevented the function from being correctly accessed.","error":"TypeError: (0, _css_chain_test__WEBPACK_IMPORTED_MODULE_0__.CssChain) is not a function"},{"fix":"Always check the `.length` of the collection before attempting to read properties (e.g., `if ($('selector').length > 0) { /* ... */ }`), or implement robust error handling for `undefined` return values.","cause":"This error occurs when attempting to access a property (like `.value` or `.textContent`) or an attribute on a `CssChain` or `ApiChain` collection that is empty, meaning no elements matched the selector or the initial array was empty. Getters for empty collections return `undefined`.","error":"Cannot read properties of undefined (reading 'value')"},{"fix":"For older browser targets, include a polyfill for `Element.matches` (e.g., from `core-js` or similar). Ensure the code is running in a modern DOM-compatible environment.","cause":"This error typically indicates that the `Element.matches()` API, which `CssChain` might rely on (e.g., in `parent(css)`), is not supported in the current execution environment (e.g., an older browser, or a non-browser environment without a polyfill).","error":"Element.matches is not a function"}],"ecosystem":"npm"}