### Fez Test Structure Example Source: https://github.com/dux/fez/blob/main/test/README.md A JavaScript code snippet demonstrating how to write a new test for the Fez library, including component setup and state assertion. ```javascript test('My new test', () => { class MyComponent extends FezBase { init() { this.state.value = 'initial'; } } const component = new MyComponent(); component._node = new window.HTMLElement(); component.root = component._node; component.class = MyComponent; component.fezRegister(); component.init(); assert(component.state.value === 'initial', 'State should be initialized'); }); ``` -------------------------------- ### FAST Rendering Configuration in Fez Source: https://github.com/dux/fez/blob/main/AI_FEZ_GUIDE.md Provides examples of how to configure `FAST = true` for components that do not use slots, preventing render flicker, and conditional fast rendering based on node attributes. ```javascript // Always fast (no slots) class { FAST = true } // Conditional fast rendering class { FAST = (node) => node.hasAttribute('title') // Fast if has title, slow if needs innerHTML } ``` -------------------------------- ### FEZ Fetch API - Basic Usage Source: https://github.com/dux/fez/blob/main/README.md Illustrates the basic usage of the Fez.fetch API for making GET and POST requests. It shows how to use promises with async/await for handling responses and callbacks for asynchronous processing, highlighting flexible parameter ordering. ```js // GET request with promise const data = await Fez.fetch('https://api.example.com/data') // GET request with callback, does not create promise Fez.fetch('https://api.example.com/data', (data) => { console.log(data) }) // POST request const result = await Fez.fetch('POST', 'https://api.example.com/data', { key: 'value' }) ``` -------------------------------- ### Create and Use a Fez Counter Component Source: https://github.com/dux/fez/blob/main/index.html Demonstrates how to create a custom 'ui-counter' component using Fez and then use it within the HTML body. The component can accept a 'start' attribute to initialize its value. ```html
``` -------------------------------- ### Dux Fez Task List Rendering and Controls Source: https://github.com/dux/fez/blob/main/test/tpl.html This snippet shows how tasks are rendered in the Dux Fez template. It includes conditional rendering for when no tasks are found, iterating through tasks to display their status and action buttons (complete/remove), and provides buttons for adding a new task and clearing completed tasks. It also displays the raw state of the tasks. ```html {#if !@state.tasks[0]} No tasks found {/if} {#for task, index in @state.tasks} {#if task.animate} {else} {/if} ⋅ ⋅ × {/for} add task ⋅ clear completed { JSON.stringify(this.state.tasks, null, 2) } ``` -------------------------------- ### Task Management Methods in Dux Fez Source: https://github.com/dux/fez/blob/main/test/tpl.html Provides methods for managing tasks within the Dux Fez framework. These methods include toggling task completion, clearing all completed tasks, removing a specific task, updating a task's name, adding a new task with animation, and initializing the task list with predefined tasks. ```javascript toggleComplete(index) { const task = this.state.tasks[index] task.done = !task.done } clearCompleted() { this.state.tasks = this.state.tasks.filter((t) => !t.done) } removeTask(index) { this.state.tasks = this.state.tasks.filter((_, i) => i !== index); } setName(index, name) { this.state.tasks[index].name = name } addTask() { this.counter ||= 0 this.state.tasks.push({ name: `new task ${++this.counter}`, done: false, animate: true }) } animate(node) { $(node) .css('display', 'block') .animate({height: '33px', opacity: 1}, 200, () => { delete this.state.tasks[this.state.tasks.length - 1].animate $(node).css('height', 'auto') }) } init() { this.state.tasks = [ {name: 'First task', done: false}, {name: 'Second task', done: false}, {name: 'Third task', done: true}, ] } ``` -------------------------------- ### Define a Counter Component with FEZ Source: https://github.com/dux/fez/blob/main/README.md Example of a custom counter component using FEZ, demonstrating reactive state, event handling, conditional rendering, and scoped SCSS. ```html {{ state.count }} {{if state.count > 0}} {{if state.count == MAX }} MAX {{else}} {{#if state.count % 2 }} odd {{else}} even {{/if}} {{/if}} {{/if}} ``` -------------------------------- ### Shared Counter Example Using Global State Source: https://github.com/dux/fez/blob/main/README.md This example demonstrates how multiple Fez counter components can share and synchronize a global maximum count. Each counter updates the global `maxCount`, ensuring all instances reflect the highest count achieved across all components. ```javascript // Multiple counter components sharing max count class Counter extends FezBase { init(props) { this.state.count = parseInt(props.start || 0) } beforeRender() { // All counters share and update the global max this.globalState.maxCount ||= 0 // Find max across all counter instances let max = 0 Fez.state.forEach('maxCount', fez => { if (fez.state?.count > max) { max = fez.state.count } }) this.globalState.maxCount = max } render() { return ` Count: ${this.state.count} (Global max: ${this.globalState.maxCount}) ` } } ``` -------------------------------- ### Dynamic Fill Control Example Source: https://github.com/dux/fez/blob/main/demo/fez/ui-star.html Illustrates controlling the fill percentage of the star rating component dynamically. This is typically done via JavaScript or data binding. ```html ``` -------------------------------- ### Styling the Star Rating Component Source: https://github.com/dux/fez/blob/main/demo/fez/ui-star.html Provides an example of CSS styling for the star rating component, specifically adding margin between stars. ```css .fez-ui-star { margin-right: 5px; } ``` -------------------------------- ### Get First-Level Child Nodes (FEZ Instance Helper) Source: https://github.com/dux/fez/blob/main/demo/fez/ui-tabs.html The `this.childNodes()` function is a helper within the FEZ instance designed to retrieve all direct child nodes. It specifically excludes text nodes (#text) from the result set, providing a clean list of element-based children. This is useful for iterating over immediate descendants without needing to filter text nodes manually. ```javascript this.childNodes() ``` -------------------------------- ### Fez Component Structure with ES Module Imports and Dynamic Loading Source: https://github.com/dux/fez/blob/main/AI_FEZ_GUIDE.md Demonstrates the basic structure of a Fez component, including optional ES Module imports, dynamic loading of JavaScript and CSS, FAST rendering control, and lifecycle methods like init(), onMount(), onStateChange(), onDestroy(), onWindowResize(), and onWindowScroll(). ```html <script> // ES Module imports (optional) import library from 'https://cdn.jsdelivr.net/npm/library/+esm' // Or load scripts/styles dynamically Fez.head({js: 'https://cdn.example.com/script.js'}) Fez.head({css: 'https://cdn.example.com/styles.css'}) // FAST rendering control (optional) FAST = true // Renders immediately (no flicker) // OR as a function for conditional behavior FAST = (node) => !node.children.length // Fast only if no children init(props) { // Props are passed as parameter - use props.name, NOT this.prop('name') // do not rewrite state, just add to it this.state.count = props.count || 0 this.state.title = props.title || 'Default' } onMount(props) { // Props also available in onMount - use props.name if (props.autoFocus) { this.find('input').focus() } } // DOM-ready logic onStateChange(key, value) // React to state changes onDestroy() // Cleanup resources onWindowResize() // on Window resize onWindowScroll() // on window scroll // Custom methods increment() { this.state.count++ // Reactive assignment } </script> <style> /* Global styles (affects entire page) */ body { background: #f5f5f5; } /* Component-scoped styles - ALWAYS use nested SCSS syntax */ :fez { /* Direct styles on component root */ padding: 20px; /* Nested elements - this is the PREFERRED pattern */ button { background: gold; cursor: pointer; /* Deep nesting is encouraged */ span { color: black; font-weight: bold; } &:hover { background: orange; } } .card { border: 1px solid #ddd; .header { font-size: 18px; h3 { margin: 0; } } } } </style> <!-- Template --> <button onclick="fez.increment()" name={{ state.buttonName }}> Count: {{ state.count }} </button> ``` -------------------------------- ### Initializing Props in Fez Components (JavaScript) Source: https://github.com/dux/fez/blob/main/AI_FEZ_GUIDE.md Shows how to access and utilize props within the `init` method of a Fez component, including setting default values and handling function props. ```javascript init(props) { this.state.font_size = props.font_size || 24 this.state.background_color = props.background_color || '#000' this.state.is_active = props.is_active !== undefined // Function props are already resolved if (props.onselect) { this.onSelectHandler = props.onselect } } ``` -------------------------------- ### Importing External Libraries in Fez Source: https://github.com/dux/fez/blob/main/AI_FEZ_GUIDE.md Shows how to import ES Modules from CDNs using the `/+esm` path and how to dynamically load external JavaScript and CSS files into the Fez application's head. ```javascript // ES Module imports (use /+esm for CDN modules) import library from 'https://cdn.jsdelivr.net/npm/library/+esm' // Dynamic script/style loading Fez.head({js: 'https://cdn.example.com/script.js'}) Fez.head({css: 'https://cdn.example.com/styles.css'}) ``` -------------------------------- ### Fez Event Handling: Component Methods and Child Access Source: https://github.com/dux/fez/blob/main/AI_FEZ_GUIDE.md Demonstrates how to handle events in Fez components, including calling component methods directly and accessing methods from child components using the Fez constructor. ```html
Status
Hover me {{for item in state.items}}
  • {{ item.name }}
  • {{/for}}
    {{raw state.htmlContent}}
    ``` -------------------------------- ### Dux Fez Component: Pre-render Preparation Source: https://github.com/dux/fez/blob/main/demo/fez/ui-slider.html Illustrates the `this.beforeRender()` lifecycle method for preparing variables prior to rendering, offering a clean alternative to Svelte's `$: {...}` reactive declarations. ```javascript this.beforeRender(() => { // Prepare variables here }); ``` -------------------------------- ### Fez Utility Shortcuts for DOM and Fetch Source: https://github.com/dux/fez/blob/main/AI_FEZ_GUIDE.md Highlights useful utility shortcuts provided by Fez for DOM manipulation, timeouts, fetching data, form data retrieval, and resolving function references from strings or functions. ```javascript this.find('.selector') // Scoped querySelector this.setTimeout(fn, 1000) // Auto-cleaned timeout Fez.fetch('/data') // Built-in cached fetch this.formData() // Get form values // Resolve a function from a string or function reference Fez.getFunction(this.props.onclick) Fez.getFunction('alert("Hi")', window) // to check if value is true, that comes from props Fez.isTrue(value) ``` -------------------------------- ### Scoped SCSS Styling in Fez Components Source: https://github.com/dux/fez/blob/main/AI_FEZ_GUIDE.md Illustrates how to use nested SCSS syntax and the `:fez` selector for scoped component styles to prevent global CSS conflicts and leverage nesting for element hierarchies. ```scss :fez { .container { padding: 20px; .header { font-size: 24px; h1 { margin: 0; color: #333; } } button { &:hover { background: #f0f0f0; } &.active { background: #007bff; } } } } ``` -------------------------------- ### Passing Props in HTML with Fez Source: https://github.com/dux/fez/blob/main/AI_FEZ_GUIDE.md Demonstrates how to pass evaluated values (functions, objects, booleans) and string values as props to Fez components using colon prefixes for evaluated attributes. ```html ``` -------------------------------- ### Fez Component Creation and Subscription Source: https://github.com/dux/fez/blob/main/demo/fez/ui-pub-sub.html Demonstrates the creation of a Fez component named 'ui-pubsub' which subscribes to 'ping' events and updates its target element's inner HTML with the received data. It also includes a mechanism to publish random data to the 'ping' topic at regular intervals. ```javascript add listener Fez('ui-pubsub', class { update (info) { this.target.innerHTML = info } init() { this.target = this.find('.target') this.subscribe('ping', this.update) this.update('waiting for a ping...') } }) setInterval(()=>Fez.publish('ping', Math.random()), 1000) ``` -------------------------------- ### FEZ Custom Node Initialization and Usage Source: https://github.com/dux/fez/blob/main/README.md Shows how to initialize and globally expose a custom FEZ component, allowing it to be controlled from anywhere in the application. It also demonstrates how to select and interact with FEZ nodes using selectors. ```html ``` ```js Fez('ui-dialog', class { init() { // makes dialog globally available window.Dialog = this } close() { ... } }) // close dialog window, from anywhere Dialog.close() // you can load via Fez + node selector Fez('#main-dialog').close() ``` -------------------------------- ### Use a FEZ Component in HTML Source: https://github.com/dux/fez/blob/main/README.md Demonstrates how to load a FEZ component using the template tag and then instantiate it in your HTML. ```html ``` -------------------------------- ### React List Rendering with useRef and forwardRef Source: https://github.com/dux/fez/blob/main/benchmark.html Demonstrates how to render a list using React's `forwardRef` and `createRef` to imperatively update the list items. It measures the time taken for DOM updates. ```javascript const reactRoot = ReactDOM.createRoot(reactMount); const ListWithRef = React.forwardRef((props, ref) => { const [items, setItems] = React.useState([]); React.useImperativeHandle(ref, () => ({ setItems: (newItems) => setItems(newItems) }), []); return React.createElement('div', null, items.map((item, i) => React.createElement('span', { key: i }, item)) ); }); const reactRef = React.createRef(); reactRoot.render(React.createElement(ListWithRef, { ref: reactRef })); ``` -------------------------------- ### Include Fez and a Custom Component in HTML Source: https://github.com/dux/fez/blob/main/index.html Demonstrates how to integrate the Fez framework and a custom Fez component (ui-time) into an HTML page. It uses script tags to load the Fez library and the component definition. ```html Time ``` -------------------------------- ### Fez Special Attributes: Binding, References, Hooks, and Evaluated Attributes Source: https://github.com/dux/fez/blob/main/AI_FEZ_GUIDE.md Explains Fez's special attributes like `fez-bind` for two-way data binding, `fez-this` for element references, `fez-use` for DOM hooks, and the use of the colon prefix for evaluated attributes (functions, objects, etc.) in templates. ```html
    ``` -------------------------------- ### Dux Fez Component: Window Resize Handling Source: https://github.com/dux/fez/blob/main/demo/fez/ui-slider.html Shows how to use `this.onWindowResize()` to execute code when the window is resized. This listener is automatically cleared when the component's node is removed. ```javascript this.onWindowResize(() => { // Execute code on window resize }); ``` -------------------------------- ### FEZ Component Structure - HTML Template Syntax Source: https://github.com/dux/fez/blob/main/README.md Demonstrates the structure of a FEZ component, including how to include elements in the document head, define component logic with scripts, apply global and local styles, and use various templating directives for conditional rendering, loops, blocks, and data binding. ```html <head> <!-- everything in head will be copied to document head--> <script>console.log('Added to document head, first script to execute.')</script> </head> <script> class { init(props) { ... } // when fez node is initialized, before template render onMount(props) { ... } // called after first template render } </script> <script> // class can be omitted if only functions are passed init(props) { ... } </script> <style> b { color: red; /* will be global style*/ } :fez { /* component styles */ } </style> <style> color: red; /* if "body {" or ":fez {" is not found, style is considered local component style */ </style> <div> ... <!-- any other html after head, script or style is considered template--> <!-- resolve any condition --> {{if foo}} ... {{/if}} <!-- unless directive - opposite of if --> {{unless fez.list.length}} <p>No items to display</p> {{/unless}} <!-- runs in node scope, you can use for loop --> {{each fez.list as name, index}} ... {{/each}} {{for name, index in fez.list}} ... {{/for}} <!-- Block definitions --> {{block image}} <img src={{ props.src}} /> {{/block}} {{block:image}} <!-- Use the header block --> {{block:image}} <!-- Use the header block --> {{raw data}} <!-- unescape HTML --> {{json data}} <!-- JSON dump in PRE.json tag --> <!-- fez-this will link DOM node to object property (inspired by Svelte) --> <!-- linkes to -> this.listRoot --> <ul fez-this="listRoot"> <!-- when node is added to dom fez-use will call object function by name, and pass current node --> <!-- this.animate(node) --> <li fez-use="animate"> <!-- fez-bind for two-way data binding on form elements --> <input type="text" fez-bind="state.username" /> <!-- fez-class for adding classes with optional delay. class will be added to SPAN element, 100ms after dom mount (to trigger animations) --> <span fez-class="active:100">Delayed class</span> <!-- preserve state by key, not affected by state changes-->> <p fez-keep="key">...</p> <!-- memoize DOM content by key (component-scoped) --> <!-- stores DOM on first render, restores on subsequent renders with same key --> <div fez-memoize="unique-key">expensive content</div> <!-- :attribute for evaluated attributes (converts to JSON) --> <div :data-config="state.config"></div> </div> ``` -------------------------------- ### Dynamic Component Loading with `