import { For, Show, createSignal, onMount, onCleanup } from 'solid-js'; import { defineWebComponent } from './define'; import { ChainOfThought, ChainOfThoughtStep, ChainOfThoughtTrigger, ChainOfThoughtContent, ChainOfThoughtItem, } from '../components/chain-of-thought'; interface Step { /** The step's heading (the always-visible trigger). */ label: string; /** Optional expandable detail. */ content?: string; } interface Props extends Record { /** The reasoning steps. Set as a JS property. Compound sub-parts collapse to * this one data model (Route 1). */ steps: Step[]; } /** Parse a single light-DOM `` element into a `Step` descriptor. * Attribute mapping: * - `label` → Step.label (the always-visible heading) * - textContent → Step.content (optional expandable detail) */ export function parseKcStepElement(n: Element): Step { return { label: n.getAttribute('label') ?? '', content: n.textContent?.trim() || undefined, }; } /** * `` — step-by-step reasoning with connectors and * per-step collapsible detail. * * **Route 1 — JS property:** set the `steps` property to an array of * `{ label, content? }` objects. * * **Route 2 — declarative children:** compose `` child elements in * light DOM (hidden by the Shadow DOM — pure data carriers). The `label` * attribute becomes the step heading; `textContent` becomes the expandable * detail. Children are merged after any prop steps. * * ```html * * The user wants composable web components. * Route 1: variant + flags; rich data via properties. * * * ``` */ defineWebComponent('kc-chain-of-thought', { steps: [], }, (props, { element }) => { // Read declarative children from light DOM. // Shadow DOM with no suppresses them visually — they're invisible data carriers. const [slottedSteps, setSlottedSteps] = createSignal([]); onMount(() => { const read = () => { const nodes = [...element.querySelectorAll('kc-step')]; setSlottedSteps(nodes.map(parseKcStepElement)); }; read(); const observer = new MutationObserver(read); observer.observe(element, { childList: true, attributes: true, subtree: true }); onCleanup(() => observer.disconnect()); }); // Prop steps first; declarative children appended after. const allSteps = () => [...props.steps, ...slottedSteps()]; return ( {(step, i) => ( {step.label} {step.content} )} ); });