@@ -451,3 +451,141 @@ export function render(
451451 } ;
452452 } ) ( ) ;
453453}
454+
455+
456+
457+ // /**
458+ // * A type representing the possible children for the tag function.
459+ // * Can be a DOM node, a string, a number, null/undefined, or a nested array of other children.
460+ // */
461+ // type TagChild = Node | string | number | null | undefined | TagChild[];
462+
463+ // /**
464+ // * Creates an HTML element programmatically with a flexible and concise syntax.
465+ // *
466+ // * This hyperscript-style function is a powerful utility for building DOM structures
467+ // * in JavaScript without resorting to messy string concatenation. It's an ideal
468+ // * companion for `watch-selector`'s rendering primitives like `For*` and `Show*`.
469+ // *
470+ // * @param name The tag name of the element to create (e.g., 'div', 'button', 'span').
471+ // * @param args A rest parameter that can include:
472+ // * - **An attributes object**: A plain object where keys are attribute names.
473+ // * - **Children**: Strings, numbers, DOM nodes, or other `tag()` calls.
474+ // * - **Arrays of children**: Nested arrays are automatically flattened.
475+ // * @returns The created HTMLElement.
476+ // *
477+ // * @example
478+ // * // Basic usage
479+ // * const myDiv = tag('div', { class: 'container' }, 'Hello World');
480+ // * // <div class="container">Hello World</div>
481+ // *
482+ // * @example
483+ // * // Nested structure with event handlers and styles
484+ // * const app = tag('main', { id: 'app' },
485+ // * tag('h1', { style: { color: 'navy' } }, 'My App'),
486+ // * tag('p', 'This is a list of items:'),
487+ // * tag('ul',
488+ // * ['Item 1', 'Item 2', 'Item 3'].map(item => tag('li', item))
489+ // * ),
490+ // * tag('button',
491+ // * {
492+ // * id: 'action-btn',
493+ // * disabled: false,
494+ // * // Event handlers are automatically attached
495+ // * onclick: (e) => alert('Button clicked!'),
496+ // * },
497+ // * 'Click Me'
498+ // * )
499+ // * );
500+ // * document.body.appendChild(app);
501+ // *
502+ // * @example
503+ // * // Integration with watch-selector's `For*` primitive
504+ // * watch('#user-list', function*() {
505+ // * const users = createState('users', [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}]);
506+ // *
507+ // * yield* For(
508+ // * users.get(),
509+ // * user => user.id,
510+ // * user => tag('div', { class: 'user-card' },
511+ // * tag('p', `ID: ${user.id}`),
512+ // * tag('strong', `Name: ${user.name}`)
513+ // * )
514+ // * );
515+ // * });
516+ // */
517+ // export function tag(
518+ // name: string,
519+ // ...args: (Record<string, any> | TagChild)[]
520+ // ): HTMLElement {
521+ // const element = document.createElement(name);
522+
523+ // /**
524+ // * Helper function to recursively append children to the element.
525+ // * It handles strings, numbers, Nodes, and nested arrays.
526+ // */
527+ // function appendChildren(children: TagChild[]) {
528+ // for (const child of children) {
529+ // if (child === null || child === undefined) {
530+ // continue; // Ignore null/undefined children
531+ // }
532+
533+ // if (Array.isArray(child)) {
534+ // // Recursively handle nested arrays
535+ // appendChildren(child);
536+ // } else if (child instanceof Node) {
537+ // // Append DOM nodes directly
538+ // element.appendChild(child);
539+ // } else {
540+ // // Convert strings, numbers, etc., to text nodes
541+ // element.appendChild(document.createTextNode(String(child)));
542+ // }
543+ // }
544+ // }
545+
546+ // // Iterate through the arguments to process attributes and children
547+ // for (const arg of args) {
548+ // if (arg === null || arg === undefined) {
549+ // continue;
550+ // }
551+
552+ // if (Array.isArray(arg)) {
553+ // // Argument is an array of children
554+ // appendChildren(arg);
555+ // } else if (arg instanceof Node) {
556+ // // Argument is a single child node
557+ // element.appendChild(arg);
558+ // } else if (typeof arg === 'object' && arg.constructor === Object) {
559+ // // Argument is a plain object, treat as attributes
560+ // for (const key in arg) {
561+ // const value = arg[key];
562+ // if (value === null || value === undefined) continue;
563+
564+ // // Handle special cases for attributes
565+ // if (key.startsWith('on') && typeof value === 'function') {
566+ // // Event listeners: onclick -> click
567+ // const eventName = key.substring(2).toLowerCase();
568+ // element.addEventListener(eventName, value);
569+ // } else if (key === 'style' && typeof value === 'object') {
570+ // // Style object: { color: 'red', fontSize: '16px' }
571+ // Object.assign(element.style, value);
572+ // } else if (key === 'class' || key === 'className') {
573+ // // Class attribute
574+ // element.className = String(value);
575+ // } else if (typeof value === 'boolean') {
576+ // // Boolean attributes: disabled, checked, etc.
577+ // // The `toggleAttribute` API correctly handles true/false.
578+ // element.toggleAttribute(key, value);
579+ // } else {
580+ // // All other attributes
581+ // element.setAttribute(key, String(value));
582+ // }
583+ // }
584+ // } else {
585+ // // Argument is a primitive (string, number), treat as a child text node
586+ // element.appendChild(document.createTextNode(String(arg)));
587+ // }
588+ // }
589+
590+ // return element;
591+ // }
0 commit comments