Skip to content

Latest commit

 

History

History
142 lines (122 loc) · 9.79 KB

File metadata and controls

142 lines (122 loc) · 9.79 KB

Changelog

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.

Removed

  • Breaking: createRuleContext and createRuleGroupContext are no longer exported. Each was a single-line createMemo around QueryManager#getRuleContext / #getRuleGroupContext keyed on query identity, with no consumer inside the package. Callers should read the manager directly — createMemo(() => (query(), manager.getRuleContext(path()))) is the whole implementation.

Changed

  • @react-querybuilder/core is bumped to 8.23.0, and the conformance fixtures with it (CONFORMANCE_TAG v8.22.4 → v8.23.0, schemaVersion 2 → 3). Schema 3 adds a per-element text channel — the element's own direct text-node children, verbatim — so extract.ts now emits it. Both walkers here go through a real DOM, so entity decoding is free. All 237 conformance assertions stay green; the new channel was proved live (a leading space added to every ActionElement label turns 100 cases red, a change the class-only schema-2 surface could not see).
  • controlKeys is now re-exported explicitly from the barrel. Core 8.23.0 exports a controlKeys of its own, and two star exports cannot disambiguate themselves (TS2308). This package's list is the deliberate delta — it omits dragHandle, ruleGroupHeaderElements, and ruleGroupBodyElements, matching this package's Controls — so it wins.
  • Breaking: createQueryBuilderState is renamed createQueryBuilder and is now documented as the package's headless entry point (see "Headless usage" in the README). It already was one — it returns query, tree, manager, schema, actions and context and renders nothing — so this is a naming change only. CreateQueryBuilderStateOptions is renamed CreateQueryBuilderOptions; the returned QueryBuilderState interface keeps its name. No alias is kept.
  • Breaking (source path only): createRuleActions moved from src/reactive/ to src/actions.ts. It is the one module in the reactive layer with no reactive primitives — a pure QueryManagerQueryActions adapter. The public barrel export is unchanged.
  • Internal: createQueryBuilder.ts (767 lines) is split along its existing #region seams into manager-options.ts (the option builders and valuesEqual), manager-bridge.ts (manager construction, query seeding, the version signals, the store projection, the subscription and the three effects), schema.ts (the option lists, the resolvers and the Schema getter object) and context-value.ts. Pure moves; the assembly file is ~200 lines and the new modules are internal.
  • Internal: ~20 createMemo calls that wrapped a single property read or a primitive-returning boolean expression are now plain closures. Solid props are already lazy getters, so those memos allocated a computation node to cache a property access. Memos that allocate an object, run a user callback (validator, accessibleDescriptionGenerator), or exist for identity stability (disabledPaths, the configVersion-keyed option lists) are untouched. createRuleState's resolvers memo is inlined into the ctx memo it exclusively fed.
  • createRuleState and createRuleGroupState take a plain RuleProps / RuleGroupProps instead of Props | Accessor<Props>. A getter-object literal is equally reactive, which is what the one internal accessor caller (RuleSubQuery) was already passing.

0.1.0 - 2026-08-08

Changed

  • Retargeted the port to Solid 2.0 exclusively. peerDependencies is now solid-js@^2.0.0-rc.0 and @solidjs/web@^2.0.0-rc.0 — in Solid 2 the DOM runtime is its own package. The ^1.9 peer leg and the non-gating solid-next CI job are both gone; CI is a single gating job on the pinned beta, preceded by a check:versions step that asserts the resolved prerelease toolchain has not drifted. jsxImportSource is now @solidjs/web, and the SSR smoke test renders through Solid 2's synchronous renderToString. The exports map is unchanged. A v1-target port, should demand warrant one, will be a separate repo publishing as @react-querybuilder/solid1; this package will not carry solid-js@1 compatibility shims.
  • 0.1.0 still publishes to the latest dist-tag. The prerelease peer is documented here and in README.md rather than encoded in the version.

Added

  • Repo bootstrap: Bun workspaces, root tooling config (oxfmt, oxlint, .editorconfig, .npmrc), root vitest.config.ts with v8 coverage (80% lines), and CI.
  • packages/solid-querybuilder scaffold: the Solid triple exports map (solidtypesimport), build pipeline (vite build dom bundle, tsc --jsx preserve source bundle, types, css), check:exports specifier guard, and scripts/ssr-smoke.ts as a real gate from day one — it asserts the solid condition 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 (RuleGroupType and RuleGroupTypeIC) behind an independent-combinators toggle that swaps query shapes, every display flag, undo/redo, and live formatQuery in sql/json/mongodb/cel.
  • examples/ssr — a hand-rolled Vite SSR consumer that depends on solid-querybuilder by workspace specifier, so it exercises the publishable dist through the real exports map. It server-renders a nested independent-combinators query with renderToString, passes one control through controlElements, prints a server-side formatQuery result into the markup, and hydrates on the client.
  • examples/ssr/ssr-smoke-test.ts, wired into root test:ssr after (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 check now fans out to @solid-querybuilder/example-*, so an example type error breaks CI.
  • README.md gains a prominent "Requires Solid 2.0" note, documentation links, and an examples section; new docs/differences-from-react-querybuilder.md, docs/styling.md, and docs/customization.md.
  • Accessibility suite (src/components/a11y.test.tsx): vitest-axe over 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 imports test/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).

Known limitations

  • label-title-only (axe best-practice) fires on every selector and text editor. React Query Builder labels these controls with title alone, and full DOM parity is a locked decision for this port, so adding aria-label would break the conformance harness. It is not a WCAG failure: title produces an accessible name, and the level-A label/aria-* rules pass across all nine a11y cases. Consumers who need a visible label can supply one through controlElements.

Fixed

  • src/index.tsx re-exports @react-querybuilder/core at runtime, not just at the type level. examples/ssr found the gap by failing to build on import { formatQuery } from 'solid-querybuilder'. Consumers can now use core's formatters, defaults, and QueryManager without depending on core directly, as React Query Builder's own barrel allows.

Changed (divergences from React Query Builder)

Authoritative list: docs/differences-from-react-querybuilder.md.

  • No SolidStart SSR gate. @solidjs/start@2.0.0 is a Solid 1 release (it depends on solid-js@^1.9.14) and there is no Solid-2 line on any dist-tag, so the planned SolidStart example is replaced by examples/ssr. Known gap: no router, no server functions, no meta-framework build pipeline, and the server-side formatQuery call is a plain call in the SSR entry rather than a server function or API route. examples/ssr is replaced by SolidStart when a Solid-2 line ships; tracked post-0.1.0, and 0.1.0 is not held for it.
  • No Redux store, no qbId, no dispatchQuery, no preserveQueryStateOnUnmount. External control is the manager prop plus the veto callbacks.
  • No slot or snippet customization tier — controlElements is the only one, because a component is the Solid idiom.
  • Not ported: drag and drop, UI compatibility packages, expr/datetime value editor UI, async option lists, deprecated props, ruleGroupHeaderElements/ruleGroupBodyElements, DragHandle.
  • Type substitutions: ReactNodeLabelNode, ComponentType → Solid's Component, JSX from @solidjs/web, React synthetic MouseEvent → the DOM MouseEvent, Controls.undoRedoActions non-nullable, RuleProps.field absent.