All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.1.0 - 2026-08-08
- Retargeted the port to Solid 2.0 exclusively.
peerDependenciesis nowsolid-js@^2.0.0-beta.32and@solidjs/web@^2.0.0-beta.32— in Solid 2 the DOM runtime is its own package. The^1.9peer leg and the non-gatingsolid-nextCI job are both gone; CI is a single gating job on the pinned beta, preceded by acheck:versionsstep that asserts the resolved prerelease toolchain has not drifted.jsxImportSourceis now@solidjs/web, and the SSR smoke test renders through Solid 2's synchronousrenderToString. Theexportsmap is unchanged. A v1-target port, should demand warrant one, will be a separate repo publishing as@react-querybuilder/solid1; this package will not carrysolid-js@1compatibility shims. 0.1.0still publishes to thelatestdist-tag. The prerelease peer is documented here and inREADME.mdrather than encoded in the version.
- Repo bootstrap: Bun workspaces, root tooling config (
oxfmt,oxlint,.editorconfig,.npmrc), rootvitest.config.tswithv8coverage (80% lines), and CI. packages/solid-querybuilderscaffold: the Solid tripleexportsmap (solid→types→import), build pipeline (vite builddom bundle,tsc --jsx preservesource bundle, types, css),check:exportsspecifier guard, andscripts/ssr-smoke.tsas a real gate from day one — it asserts thesolidcondition is first in the exports map and confirms that with Node's real resolver run with and without--conditions=solid, then renders through Vite's SSR pipeline inside a single Solid instance and asserts the exact markup.examples/demo— a Vite + Solid 2 playground aliased to the library's source (HMR without a build). Eight fields covering all seven value editors, two separately bound queries (RuleGroupTypeandRuleGroupTypeIC) behind an independent-combinators toggle that swaps query shapes, every display flag, undo/redo, and liveformatQueryinsql/json/mongodb/cel.examples/ssr— a hand-rolled Vite SSR consumer that depends onsolid-querybuilderby workspace specifier, so it exercises the publishabledistthrough the realexportsmap. It server-renders a nested independent-combinators query withrenderToString, passes one control throughcontrolElements, prints a server-sideformatQueryresult into the markup, and hydrates on the client.examples/ssr/ssr-smoke-test.ts, wired into roottest:ssrafter (not instead of)scripts/ssr-smoke.ts. It builds both bundles, serves them programmatically on an ephemeral port, asserts the status code and 20 markup claims, then loads the served page into jsdom, runs the client entry, and asserts hydration produced no errors and left the conformance surface unchanged.- Root
checknow fans out to@solid-querybuilder/example-*, so an example type error breaks CI. README.mdgains a prominent "Requires Solid 2.0" note, documentation links, and an examples section; newdocs/differences-from-react-querybuilder.md,docs/styling.md, anddocs/customization.md.- Accessibility suite (
src/components/a11y.test.tsx):vitest-axeover all eight conformance scenarios plus an all-controls independent-combinator case (nine cases), each asserted twice — WCAG 2.0/2.1 A+AA must be empty, and best-practice must equal exactly['label-title-only'], so any other best-practice regression still fails. Plus keyboard tests: tab order through a rule row, Enter/Space activation, and the not-toggle label association. It importstest/conformance/{scenarios,queries}rather than duplicating them, so a11y is asserted against exactly the prop combinations DOM parity is, and it still runs in a fresh clone (both modules are fixture-independent).
label-title-only(axe best-practice) fires on every selector and text editor. React Query Builder labels these controls withtitlealone, and full DOM parity is a locked decision for this port, so addingaria-labelwould break the conformance harness. It is not a WCAG failure:titleproduces an accessible name, and the level-Alabel/aria-*rules pass across all nine a11y cases. Consumers who need a visible label can supply one throughcontrolElements.
src/index.tsxre-exports@react-querybuilder/coreat runtime, not just at the type level.examples/ssrfound the gap by failing to build onimport { formatQuery } from 'solid-querybuilder'. Consumers can now use core's formatters, defaults, andQueryManagerwithout depending on core directly, as React Query Builder's own barrel allows.
Authoritative list: docs/differences-from-react-querybuilder.md.
- No SolidStart SSR gate.
@solidjs/start@2.0.0is a Solid 1 release (it depends onsolid-js@^1.9.14) and there is no Solid-2 line on any dist-tag, so the planned SolidStart example is replaced byexamples/ssr. Known gap: no router, no server functions, no meta-framework build pipeline, and the server-sideformatQuerycall is a plain call in the SSR entry rather than a server function or API route.examples/ssris replaced by SolidStart when a Solid-2 line ships; tracked post-0.1.0, and0.1.0is not held for it. - No Redux store, no
qbId, nodispatchQuery, nopreserveQueryStateOnUnmount. External control is themanagerprop plus the veto callbacks. - No slot or snippet customization tier —
controlElementsis the only one, because a component is the Solid idiom. - Not ported: drag and drop, UI compatibility packages,
expr/datetimevalue editor UI, async option lists, deprecated props,ruleGroupHeaderElements/ruleGroupBodyElements,DragHandle. - Type substitutions:
ReactNode→LabelNode,ComponentType→ Solid'sComponent,JSXfrom@solidjs/web, React syntheticMouseEvent→ the DOMMouseEvent,Controls.undoRedoActionsnon-nullable,RuleProps.fieldabsent.