@charcuterie/ui 2.12.1 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/QueryBuilder/QueryBuilder.d.ts +95 -0
  2. package/dist/QueryBuilder/QueryBuilder.d.ts.map +1 -0
  3. package/dist/QueryBuilder/QueryBuilder.js +38 -0
  4. package/dist/QueryBuilder/QueryBuilder.js.map +1 -0
  5. package/dist/QueryBuilder/QueryBuilderCombinator.d.ts +53 -0
  6. package/dist/QueryBuilder/QueryBuilderCombinator.d.ts.map +1 -0
  7. package/dist/QueryBuilder/QueryBuilderCombinator.js +59 -0
  8. package/dist/QueryBuilder/QueryBuilderCombinator.js.map +1 -0
  9. package/dist/QueryBuilder/QueryBuilderGroup.d.ts +42 -0
  10. package/dist/QueryBuilder/QueryBuilderGroup.d.ts.map +1 -0
  11. package/dist/QueryBuilder/QueryBuilderGroup.js +51 -0
  12. package/dist/QueryBuilder/QueryBuilderGroup.js.map +1 -0
  13. package/dist/QueryBuilder/QueryBuilderRow.d.ts +28 -0
  14. package/dist/QueryBuilder/QueryBuilderRow.d.ts.map +1 -0
  15. package/dist/QueryBuilder/QueryBuilderRow.js +16 -0
  16. package/dist/QueryBuilder/QueryBuilderRow.js.map +1 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +1 -0
  20. package/dist/index.js.map +1 -1
  21. package/package.json +2 -2
  22. package/src/QueryBuilder/QueryBuilder.mdx +70 -0
  23. package/src/QueryBuilder/QueryBuilder.stories.tsx +429 -0
  24. package/src/QueryBuilder/QueryBuilder.test.tsx +204 -0
  25. package/src/QueryBuilder/QueryBuilder.tsx +136 -0
  26. package/src/QueryBuilder/QueryBuilderCombinator.tsx +108 -0
  27. package/src/QueryBuilder/QueryBuilderGroup.tsx +189 -0
  28. package/src/QueryBuilder/QueryBuilderRow.tsx +54 -0
  29. package/src/index.ts +5 -0
  30. package/src/sourceRules.test.ts +10 -1
@@ -0,0 +1,95 @@
1
+ import type { Tree } from "@charcuterie/logic";
2
+ import type { ReactNode } from "react";
3
+ export type QueryBuilderLabels = {
4
+ addGroup?: string;
5
+ addLeaf?: string;
6
+ /** The caption over each group's combinator picker. */
7
+ match?: string;
8
+ removeGroup?: string;
9
+ removeLeaf?: string;
10
+ };
11
+ export type QueryBuilderProps<Combinator, Leaf> = {
12
+ /**
13
+ * The combinator choices offered in every group's "Match" select.
14
+ * The `value` is opaque — `and`/`or` for a mail rule, `any`/`all`/
15
+ * `none` for a DSL — and the `label` is what a user reads.
16
+ */
17
+ combinatorOptions: readonly {
18
+ label: string;
19
+ value: Combinator;
20
+ }[];
21
+ /** The value a fresh leaf is born with when "+ Condition" is pressed. */
22
+ createLeafValue: () => Leaf;
23
+ labels?: QueryBuilderLabels;
24
+ /**
25
+ * The group's combinator control, when one `Listbox` over a flat
26
+ * option list is the wrong shape for it.
27
+ *
28
+ * Optional, and the default is the right answer for most consumers:
29
+ * a combinator that is a plain enum reads as one picker. But a
30
+ * combinator can be a *composite* — mux-magic's is a quantifier
31
+ * (ANY/ALL/NO) crossed with a target (a nested group, a style row,
32
+ * a script-info block), and the legal pairs are asymmetric
33
+ * (`notAllScriptInfo` exists, `notAllStyle` does not). Flattened
34
+ * into one list that is nine options where the user is making two
35
+ * choices, and the illegal pairs are invisible until they are
36
+ * missing.
37
+ *
38
+ * So the combinator is app-ownable for the same reason `renderLeaf`
39
+ * is: `Combinator` is opaque here, and only the app knows whether
40
+ * its shape is an enum or a product. `options` and the current
41
+ * `value` are handed over unchanged; the app calls `onChange` with a
42
+ * real `Combinator`.
43
+ */
44
+ renderCombinator?: (args: {
45
+ nodeId: string;
46
+ onChange: (combinator: Combinator) => void;
47
+ options: readonly {
48
+ label: string;
49
+ value: Combinator;
50
+ }[];
51
+ value: Combinator;
52
+ }) => ReactNode;
53
+ /**
54
+ * The leaf UI, owned by the app. `QueryBuilder` knows nothing about
55
+ * what a condition *is* — a field/operator/value triple, a
56
+ * non-uniform per-kind shape — only that it can be rendered and
57
+ * patched. The delete control around each leaf is the builder's.
58
+ */
59
+ renderLeaf: (args: {
60
+ nodeId: string;
61
+ onChange: (value: Leaf) => void;
62
+ value: Leaf;
63
+ }) => ReactNode;
64
+ /**
65
+ * The `Tree` core from `useTree`, owned by the consumer — the same
66
+ * arrangement as a `Listbox`'s parent owning `useVisibility`.
67
+ * `QueryBuilder` subscribes to it and drives it; it never creates
68
+ * one, so a consumer keeps `serialize()` and the initial tree.
69
+ */
70
+ tree: Tree<Combinator, Leaf>;
71
+ };
72
+ /**
73
+ * The generic, nestable AND/OR — and any-combinator — group editor.
74
+ *
75
+ * Two apps in the fleet grow the same widget: Mail Sifter's nested
76
+ * mail rules (leaf = field/operator/value, combinators AND/OR) and
77
+ * mux-magic's job DSL (non-uniform leaves, combinators any/all/none).
78
+ * Both are a recursive group of conditions with a combinator, so the
79
+ * value **and** the combinator are opaque here — `Combinator` and
80
+ * `Leaf` never appear except passed through to the consumer's
81
+ * `renderLeaf` and its `combinatorOptions`.
82
+ *
83
+ * State lives entirely in the `Tree` core from `@charcuterie/logic`;
84
+ * this component holds none of its own. It subscribes with
85
+ * `useStoreValue`, so a `patchLeaf` deep in the tree re-renders only
86
+ * the rows whose node identity changed — the same identity discipline
87
+ * the state layer is built on.
88
+ *
89
+ * The recursion and the per-leaf row each live in their own file
90
+ * (`QueryBuilderGroup`, `QueryBuilderRow`), not exported: a group
91
+ * renders groups, and both are rendered inside a `.map`, which is
92
+ * exactly the shape the member-file rule is for.
93
+ */
94
+ export declare const QueryBuilder: <Combinator, Leaf>({ combinatorOptions, createLeafValue, labels, renderCombinator, renderLeaf, tree, }: QueryBuilderProps<Combinator, Leaf>) => ReactNode;
95
+ //# sourceMappingURL=QueryBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBuilder.d.ts","sourceRoot":"","sources":["../../src/QueryBuilder/QueryBuilder.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAK9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,UAAU,EAAE,IAAI,IAAI;IAChD;;;;OAIG;IACH,iBAAiB,EAAE,SAAS;QAC1B,KAAK,EAAE,MAAM,CAAA;QACb,KAAK,EAAE,UAAU,CAAA;KAClB,EAAE,CAAA;IACH,yEAAyE;IACzE,eAAe,EAAE,MAAM,IAAI,CAAA;IAC3B,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAC3B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE;QACxB,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAA;QAC1C,OAAO,EAAE,SAAS;YAChB,KAAK,EAAE,MAAM,CAAA;YACb,KAAK,EAAE,UAAU,CAAA;SAClB,EAAE,CAAA;QACH,KAAK,EAAE,UAAU,CAAA;KAClB,KAAK,SAAS,CAAA;IACf;;;;;OAKG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE;QACjB,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAA;QAC/B,KAAK,EAAE,IAAI,CAAA;KACZ,KAAK,SAAS,CAAA;IACf;;;;;OAKG;IACH,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;CAC7B,CAAA;AAUD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,YAAY,GAAI,UAAU,EAAE,IAAI,EAAE,qFAO5C,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,KAAG,SAkBxC,CAAA"}
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { selectRootGroup, useStoreValue, } from "@charcuterie/logic";
3
+ import { QueryBuilderGroup } from "./QueryBuilderGroup.js";
4
+ const DEFAULT_LABELS = {
5
+ addGroup: "Add group",
6
+ addLeaf: "Add condition",
7
+ match: "Match",
8
+ removeGroup: "Remove group",
9
+ removeLeaf: "Remove condition",
10
+ };
11
+ /**
12
+ * The generic, nestable AND/OR — and any-combinator — group editor.
13
+ *
14
+ * Two apps in the fleet grow the same widget: Mail Sifter's nested
15
+ * mail rules (leaf = field/operator/value, combinators AND/OR) and
16
+ * mux-magic's job DSL (non-uniform leaves, combinators any/all/none).
17
+ * Both are a recursive group of conditions with a combinator, so the
18
+ * value **and** the combinator are opaque here — `Combinator` and
19
+ * `Leaf` never appear except passed through to the consumer's
20
+ * `renderLeaf` and its `combinatorOptions`.
21
+ *
22
+ * State lives entirely in the `Tree` core from `@charcuterie/logic`;
23
+ * this component holds none of its own. It subscribes with
24
+ * `useStoreValue`, so a `patchLeaf` deep in the tree re-renders only
25
+ * the rows whose node identity changed — the same identity discipline
26
+ * the state layer is built on.
27
+ *
28
+ * The recursion and the per-leaf row each live in their own file
29
+ * (`QueryBuilderGroup`, `QueryBuilderRow`), not exported: a group
30
+ * renders groups, and both are rendered inside a `.map`, which is
31
+ * exactly the shape the member-file rule is for.
32
+ */
33
+ export const QueryBuilder = ({ combinatorOptions, createLeafValue, labels, renderCombinator, renderLeaf, tree, }) => {
34
+ const state = useStoreValue(tree);
35
+ const resolvedLabels = { ...DEFAULT_LABELS, ...labels };
36
+ return (_jsx(QueryBuilderGroup, { combinatorOptions: combinatorOptions, createLeafValue: createLeafValue, depth: 0, labels: resolvedLabels, node: selectRootGroup(state), renderCombinator: renderCombinator, renderLeaf: renderLeaf, state: state, tree: tree }));
37
+ };
38
+ //# sourceMappingURL=QueryBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBuilder.js","sourceRoot":"","sources":["../../src/QueryBuilder/QueryBuilder.tsx"],"names":[],"mappings":";AACA,OAAO,EACL,eAAe,EACf,aAAa,GACd,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAyB,CAAA;AAyE3D,MAAM,cAAc,GAAG;IACrB,QAAQ,EAAE,WAAW;IACrB,OAAO,EAAE,eAAe;IACxB,KAAK,EAAE,OAAO;IACd,WAAW,EAAE,cAAc;IAC3B,UAAU,EAAE,kBAAkB;CACQ,CAAA;AAExC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAmB,EAC7C,iBAAiB,EACjB,eAAe,EACf,MAAM,EACN,gBAAgB,EAChB,UAAU,EACV,IAAI,GACgC,EAAa,EAAE;IACnD,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;IAEjC,MAAM,cAAc,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAA;IAEvD,OAAO,CACL,KAAC,iBAAiB,IAChB,iBAAiB,EAAE,iBAAiB,EACpC,eAAe,EAAE,eAAe,EAChC,KAAK,EAAE,CAAC,EACR,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,eAAe,CAAC,KAAK,CAAC,EAC5B,gBAAgB,EAAE,gBAAgB,EAClC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,IAAI,GACV,CACH,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,53 @@
1
+ import type { ReactNode } from "react";
2
+ export type QueryBuilderCombinatorProps<Combinator> = {
3
+ /** The visible caption above the control, e.g. "Match". */
4
+ label: string;
5
+ onChange: (combinator: Combinator) => void;
6
+ options: readonly {
7
+ label: string;
8
+ value: Combinator;
9
+ }[];
10
+ value: Combinator;
11
+ };
12
+ /**
13
+ * One group's combinator picker.
14
+ *
15
+ * A `Listbox`, not a native `Select`, per
16
+ * [the 2026-08-10 demotion](../../../../docs/decisions/2026-08-10-listbox-and-combobox-are-the-default-and-select-is-demoted.md).
17
+ * `QueryBuilder` shipped in #84 with a `Select` the day after that
18
+ * record landed; `charcuterie/prefer-listbox-over-select` did not
19
+ * catch it because the component-choice block is scoped to app
20
+ * packages and exempts this one — right for a primitive, wrong for a
21
+ * composite an app consumes whole.
22
+ *
23
+ * ### Why this is its own file
24
+ *
25
+ * `Listbox` needs a visibility state, and a group renders one picker
26
+ * per group inside a recursive `.map`. A hook cannot be called there,
27
+ * so the picker becomes a component — the same member-file case as
28
+ * `QueryBuilderRow`.
29
+ *
30
+ * ### The name, and why it is not a `Field`
31
+ *
32
+ * `Field` wires `<label htmlFor>` by cloning its `id` onto the
33
+ * control. `Listbox`'s trigger cannot take one: `useAnchoredOverlay`
34
+ * overwrites the cloned trigger's `id` with the one the panel points
35
+ * `aria-labelledby` at, so the label would address an element that no
36
+ * longer carries that id — the exact defect `Field` exists to
37
+ * prevent. So the caption is plain text and the trigger is named with
38
+ * `aria-label`.
39
+ *
40
+ * That name is `"<label>: <current value>"` rather than bare
41
+ * `"<label>"` on purpose: the button's visible text is the current
42
+ * combinator, and WCAG 2.5.3 wants the visible text contained in the
43
+ * accessible name. "Match" alone would fail it; "Match: ALL — every
44
+ * condition" reads correctly and keeps each group's control findable
45
+ * by name.
46
+ *
47
+ * The combinator stays opaque here exactly as it is in the rest of
48
+ * the component: `String(value)` bridges it to the string-valued
49
+ * `Listbox`, and a selection is mapped back to the real `Combinator`
50
+ * before it leaves.
51
+ */
52
+ export declare const QueryBuilderCombinator: <Combinator>({ label, onChange, options, value, }: QueryBuilderCombinatorProps<Combinator>) => ReactNode;
53
+ //# sourceMappingURL=QueryBuilderCombinator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBuilderCombinator.d.ts","sourceRoot":"","sources":["../../src/QueryBuilder/QueryBuilderCombinator.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtC,MAAM,MAAM,2BAA2B,CAAC,UAAU,IAAI;IACpD,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAA;IAC1C,OAAO,EAAE,SAAS;QAChB,KAAK,EAAE,MAAM,CAAA;QACb,KAAK,EAAE,UAAU,CAAA;KAClB,EAAE,CAAA;IACH,KAAK,EAAE,UAAU,CAAA;CAClB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,sBAAsB,GAAI,UAAU,EAAG,sCAKjD,2BAA2B,CAAC,UAAU,CAAC,KAAG,SA6C5C,CAAA"}
@@ -0,0 +1,59 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useVisibility } from "@charcuterie/logic";
3
+ import { Button } from "../Button/Button.js";
4
+ import { Listbox } from "../Listbox/Listbox.js";
5
+ /**
6
+ * One group's combinator picker.
7
+ *
8
+ * A `Listbox`, not a native `Select`, per
9
+ * [the 2026-08-10 demotion](../../../../docs/decisions/2026-08-10-listbox-and-combobox-are-the-default-and-select-is-demoted.md).
10
+ * `QueryBuilder` shipped in #84 with a `Select` the day after that
11
+ * record landed; `charcuterie/prefer-listbox-over-select` did not
12
+ * catch it because the component-choice block is scoped to app
13
+ * packages and exempts this one — right for a primitive, wrong for a
14
+ * composite an app consumes whole.
15
+ *
16
+ * ### Why this is its own file
17
+ *
18
+ * `Listbox` needs a visibility state, and a group renders one picker
19
+ * per group inside a recursive `.map`. A hook cannot be called there,
20
+ * so the picker becomes a component — the same member-file case as
21
+ * `QueryBuilderRow`.
22
+ *
23
+ * ### The name, and why it is not a `Field`
24
+ *
25
+ * `Field` wires `<label htmlFor>` by cloning its `id` onto the
26
+ * control. `Listbox`'s trigger cannot take one: `useAnchoredOverlay`
27
+ * overwrites the cloned trigger's `id` with the one the panel points
28
+ * `aria-labelledby` at, so the label would address an element that no
29
+ * longer carries that id — the exact defect `Field` exists to
30
+ * prevent. So the caption is plain text and the trigger is named with
31
+ * `aria-label`.
32
+ *
33
+ * That name is `"<label>: <current value>"` rather than bare
34
+ * `"<label>"` on purpose: the button's visible text is the current
35
+ * combinator, and WCAG 2.5.3 wants the visible text contained in the
36
+ * accessible name. "Match" alone would fail it; "Match: ALL — every
37
+ * condition" reads correctly and keeps each group's control findable
38
+ * by name.
39
+ *
40
+ * The combinator stays opaque here exactly as it is in the rest of
41
+ * the component: `String(value)` bridges it to the string-valued
42
+ * `Listbox`, and a selection is mapped back to the real `Combinator`
43
+ * before it leaves.
44
+ */
45
+ export const QueryBuilderCombinator = ({ label, onChange, options, value, }) => {
46
+ const { hide, isVisible, toggle } = useVisibility();
47
+ const currentOption = options.find((option) => String(option.value) === String(value));
48
+ const currentLabel = currentOption?.label ?? "";
49
+ return (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("span", { className: "font-medium text-content-primary text-sm", children: label }), _jsx(Listbox, { isVisible: isVisible, onDismiss: hide, onSelect: (nextValue) => {
50
+ const match = options.find((option) => String(option.value) === nextValue);
51
+ if (match) {
52
+ onChange(match.value);
53
+ }
54
+ }, options: options.map((option) => ({
55
+ label: option.label,
56
+ value: String(option.value),
57
+ })), selectedValue: String(value), trigger: _jsx(Button, { appearance: "outline", "aria-label": `${label}: ${currentLabel}`, intent: "neutral", onClick: toggle, children: currentLabel }) })] }));
58
+ };
59
+ //# sourceMappingURL=QueryBuilderCombinator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBuilderCombinator.js","sourceRoot":"","sources":["../../src/QueryBuilder/QueryBuilderCombinator.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAGlD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAsB,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAwB,CAAA;AAahD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAc,EAClD,KAAK,EACL,QAAQ,EACR,OAAO,EACP,KAAK,GACmC,EAAa,EAAE;IACvD,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAAA;IAEnD,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAChC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,CACnD,CAAA;IAED,MAAM,YAAY,GAAG,aAAa,EAAE,KAAK,IAAI,EAAE,CAAA;IAE/C,OAAO,CACL,eAAK,SAAS,EAAC,uBAAuB,aACpC,eAAM,SAAS,EAAC,0CAA0C,YACvD,KAAK,GACD,EAEP,KAAC,OAAO,IACN,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,IAAI,EACf,QAAQ,EAAE,CAAC,SAAS,EAAE,EAAE;oBACtB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CACxB,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS,CAC/C,CAAA;oBAED,IAAI,KAAK,EAAE,CAAC;wBACV,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;oBACvB,CAAC;gBACH,CAAC,EACD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;oBAChC,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC5B,CAAC,CAAC,EACH,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,EAC5B,OAAO,EACL,KAAC,MAAM,IACL,UAAU,EAAC,SAAS,gBACR,GAAG,KAAK,KAAK,YAAY,EAAE,EACvC,MAAM,EAAC,SAAS,EAChB,OAAO,EAAE,MAAM,YAEd,YAAY,GACN,GAEX,IACE,CACP,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,42 @@
1
+ import type { Tree, TreeGroupNode, TreeState } from "@charcuterie/logic";
2
+ import type { ReactNode } from "react";
3
+ import type { QueryBuilderLabels } from "./QueryBuilder.tsx";
4
+ export type QueryBuilderGroupProps<Combinator, Leaf> = {
5
+ combinatorOptions: readonly {
6
+ label: string;
7
+ value: Combinator;
8
+ }[];
9
+ createLeafValue: () => Leaf;
10
+ /** Root is `0`; nested groups deepen and gain the accent rail. */
11
+ depth: number;
12
+ labels: Required<QueryBuilderLabels>;
13
+ node: TreeGroupNode<Combinator>;
14
+ renderCombinator?: (args: {
15
+ nodeId: string;
16
+ onChange: (combinator: Combinator) => void;
17
+ options: readonly {
18
+ label: string;
19
+ value: Combinator;
20
+ }[];
21
+ value: Combinator;
22
+ }) => ReactNode;
23
+ renderLeaf: (args: {
24
+ nodeId: string;
25
+ onChange: (value: Leaf) => void;
26
+ value: Leaf;
27
+ }) => ReactNode;
28
+ state: TreeState<Combinator, Leaf>;
29
+ tree: Tree<Combinator, Leaf>;
30
+ };
31
+ /**
32
+ * One match group: a "Match" combinator picker, its children (leaf
33
+ * rows and nested groups), and a toolbar to add either. Its own file
34
+ * because it renders itself recursively for nested groups and is
35
+ * itself rendered inside the parent's `.map` — the member-file case.
36
+ *
37
+ * The picker is `QueryBuilderCombinator`, a `Listbox` rather than the
38
+ * native `Select` this shipped with — see that file for why it is a
39
+ * component and how it stays generic over an opaque `Combinator`.
40
+ */
41
+ export declare const QueryBuilderGroup: <Combinator, Leaf>({ combinatorOptions, createLeafValue, depth, labels, node, renderCombinator, renderLeaf, state, tree, }: QueryBuilderGroupProps<Combinator, Leaf>) => ReactNode;
42
+ //# sourceMappingURL=QueryBuilderGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBuilderGroup.d.ts","sourceRoot":"","sources":["../../src/QueryBuilder/QueryBuilderGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EACb,SAAS,EACV,MAAM,oBAAoB,CAAA;AAE3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAI5D,MAAM,MAAM,sBAAsB,CAAC,UAAU,EAAE,IAAI,IAAI;IACrD,iBAAiB,EAAE,SAAS;QAC1B,KAAK,EAAE,MAAM,CAAA;QACb,KAAK,EAAE,UAAU,CAAA;KAClB,EAAE,CAAA;IACH,eAAe,EAAE,MAAM,IAAI,CAAA;IAC3B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAA;IACpC,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,CAAA;IAC/B,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE;QACxB,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAA;QAC1C,OAAO,EAAE,SAAS;YAChB,KAAK,EAAE,MAAM,CAAA;YACb,KAAK,EAAE,UAAU,CAAA;SAClB,EAAE,CAAA;QACH,KAAK,EAAE,UAAU,CAAA;KAClB,KAAK,SAAS,CAAA;IACf,UAAU,EAAE,CAAC,IAAI,EAAE;QACjB,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAA;QAC/B,KAAK,EAAE,IAAI,CAAA;KACZ,KAAK,SAAS,CAAA;IACf,KAAK,EAAE,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;IAClC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;CAC7B,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,EAAE,IAAI,EAAE,yGAUjD,sBAAsB,CAAC,UAAU,EAAE,IAAI,CAAC,KAAG,SA4H7C,CAAA"}
@@ -0,0 +1,51 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { selectChildNodes } from "@charcuterie/logic";
3
+ import { Button } from "../Button/Button.js";
4
+ import { Card } from "../Card/Card.js";
5
+ import { IconButton } from "../IconButton/IconButton.js";
6
+ import { toClassName } from "../toClassName.js";
7
+ import { QueryBuilderCombinator } from "./QueryBuilderCombinator.js";
8
+ import { QueryBuilderRow } from "./QueryBuilderRow.js";
9
+ /**
10
+ * One match group: a "Match" combinator picker, its children (leaf
11
+ * rows and nested groups), and a toolbar to add either. Its own file
12
+ * because it renders itself recursively for nested groups and is
13
+ * itself rendered inside the parent's `.map` — the member-file case.
14
+ *
15
+ * The picker is `QueryBuilderCombinator`, a `Listbox` rather than the
16
+ * native `Select` this shipped with — see that file for why it is a
17
+ * component and how it stays generic over an opaque `Combinator`.
18
+ */
19
+ export const QueryBuilderGroup = ({ combinatorOptions, createLeafValue, depth, labels, node, renderCombinator, renderLeaf, state, tree, }) => {
20
+ const children = selectChildNodes(state, node.id);
21
+ const setCombinator = (nextCombinator) => {
22
+ tree.setCombinator(node.id, nextCombinator);
23
+ };
24
+ const card = (_jsx(Card
25
+ // Nested groups sit on the sunken surface so the depth reads as
26
+ // recession, not another raised card floating at the same level.
27
+ , {
28
+ // Nested groups sit on the sunken surface so the depth reads as
29
+ // recession, not another raised card floating at the same level.
30
+ surface: depth === 0 ? "raised" : "sunken", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsx("div", { className: "min-w-52", children: renderCombinator ? (renderCombinator({
31
+ nodeId: node.id,
32
+ onChange: setCombinator,
33
+ options: combinatorOptions,
34
+ value: node.combinator,
35
+ })) : (_jsx(QueryBuilderCombinator, { label: labels.match, onChange: setCombinator, options: combinatorOptions, value: node.combinator })) }), depth === 0 ? null : (_jsx(IconButton, { appearance: "ghost", intent: "danger", label: labels.removeGroup, onClick: () => {
36
+ tree.removeNode(node.id);
37
+ }, size: "sm", children: "\u2715" }))] }), children.length === 0 ? null : (_jsx("div", { className: "flex flex-col gap-2", children: children.map((child) => child.kind === "group" ? (_jsx(QueryBuilderGroup, { combinatorOptions: combinatorOptions, createLeafValue: createLeafValue, depth: depth + 1, labels: labels, node: child, renderCombinator: renderCombinator, renderLeaf: renderLeaf, state: state, tree: tree }, child.id)) : (_jsx(QueryBuilderRow, { label: labels.removeLeaf, nodeId: child.id, onChange: (value) => {
38
+ tree.patchLeaf(child.id, value);
39
+ }, onRemove: () => {
40
+ tree.removeNode(child.id);
41
+ }, renderLeaf: renderLeaf, value: child.value }, child.id))) })), _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsx(Button, { appearance: "outline", intent: "neutral", onClick: () => {
42
+ tree.addLeaf(node.id, createLeafValue());
43
+ }, size: "sm", children: `+ ${labels.addLeaf}` }), _jsx(Button, { appearance: "outline", intent: "neutral", onClick: () => {
44
+ tree.addGroup(node.id);
45
+ }, size: "sm", children: `+ ${labels.addGroup}` })] })] }) }));
46
+ // Depth is shown with a semantic-token inline-start rail. The colour
47
+ // utility paints all four sides, but only the inline-start edge has
48
+ // a width, so only it renders — no raw palette colour anywhere.
49
+ return depth === 0 ? (card) : (_jsx("div", { className: toClassName("border-intent-accent-border border-s-2 ps-3"), children: card }));
50
+ };
51
+ //# sourceMappingURL=QueryBuilderGroup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBuilderGroup.js","sourceRoot":"","sources":["../../src/QueryBuilder/QueryBuilderGroup.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { ReactNode } from "react";
2
+ export type QueryBuilderRowProps<Leaf> = {
3
+ /** The accessible name of the row's delete control. */
4
+ label: string;
5
+ nodeId: string;
6
+ onChange: (value: Leaf) => void;
7
+ onRemove: () => void;
8
+ renderLeaf: (args: {
9
+ nodeId: string;
10
+ onChange: (value: Leaf) => void;
11
+ value: Leaf;
12
+ }) => ReactNode;
13
+ value: Leaf;
14
+ };
15
+ /**
16
+ * A single leaf row: the app's own leaf UI, plus the builder's delete
17
+ * control. Its own file for the same reason `ListboxOption` is —
18
+ * rendered inside the group's `.map`, so it cannot be an inline
19
+ * component — and it is a member file (`QueryBuilder*.tsx`, not
20
+ * `QueryBuilder/QueryBuilder.tsx`), so it stays out of the barrel and
21
+ * the component count by rule.
22
+ *
23
+ * The delete control is an `IconButton` because a bare glyph is not an
24
+ * accessible name; its required `label` is what makes each row's
25
+ * remove button findable and unique per condition.
26
+ */
27
+ export declare const QueryBuilderRow: <Leaf>({ label, nodeId, onChange, onRemove, renderLeaf, value, }: QueryBuilderRowProps<Leaf>) => ReactNode;
28
+ //# sourceMappingURL=QueryBuilderRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBuilderRow.d.ts","sourceRoot":"","sources":["../../src/QueryBuilder/QueryBuilderRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC,MAAM,MAAM,oBAAoB,CAAC,IAAI,IAAI;IACvC,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAA;IAC/B,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,UAAU,EAAE,CAAC,IAAI,EAAE;QACjB,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAA;QAC/B,KAAK,EAAE,IAAI,CAAA;KACZ,KAAK,SAAS,CAAA;IACf,KAAK,EAAE,IAAI,CAAA;CACZ,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,GAAI,IAAI,EAAG,2DAOpC,oBAAoB,CAAC,IAAI,CAAC,KAAG,SAgB/B,CAAA"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { IconButton } from "../IconButton/IconButton.js";
3
+ /**
4
+ * A single leaf row: the app's own leaf UI, plus the builder's delete
5
+ * control. Its own file for the same reason `ListboxOption` is —
6
+ * rendered inside the group's `.map`, so it cannot be an inline
7
+ * component — and it is a member file (`QueryBuilder*.tsx`, not
8
+ * `QueryBuilder/QueryBuilder.tsx`), so it stays out of the barrel and
9
+ * the component count by rule.
10
+ *
11
+ * The delete control is an `IconButton` because a bare glyph is not an
12
+ * accessible name; its required `label` is what makes each row's
13
+ * remove button findable and unique per condition.
14
+ */
15
+ export const QueryBuilderRow = ({ label, nodeId, onChange, onRemove, renderLeaf, value, }) => (_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("div", { className: "grow", children: renderLeaf({ nodeId, onChange, value }) }), _jsx(IconButton, { appearance: "ghost", intent: "danger", label: label, onClick: onRemove, size: "sm", children: "\u2715" })] }));
16
+ //# sourceMappingURL=QueryBuilderRow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBuilderRow.js","sourceRoot":"","sources":["../../src/QueryBuilder/QueryBuilderRow.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA8B,CAAA;AAgBzD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAQ,EACrC,KAAK,EACL,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,KAAK,GACsB,EAAa,EAAE,CAAC,CAC3C,eAAK,SAAS,EAAC,wBAAwB,aACrC,cAAK,SAAS,EAAC,MAAM,YAClB,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,GACpC,EAEN,KAAC,UAAU,IACT,UAAU,EAAC,OAAO,EAClB,MAAM,EAAC,QAAQ,EACf,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAC,IAAI,uBAGE,IACT,CACP,CAAA"}
package/dist/index.d.ts CHANGED
@@ -98,6 +98,8 @@ export type { ProgressBarProps, ProgressBarSize, } from "./ProgressBar/ProgressB
98
98
  export { ProgressBar } from "./ProgressBar/ProgressBar.tsx";
99
99
  export type { ProgressThreshold } from "./ProgressBar/progressValue.ts";
100
100
  export { getProgressIntent, toProgressPercent, toProgressValue, } from "./ProgressBar/progressValue.ts";
101
+ export type { QueryBuilderLabels, QueryBuilderProps, } from "./QueryBuilder/QueryBuilder.tsx";
102
+ export { QueryBuilder } from "./QueryBuilder/QueryBuilder.tsx";
101
103
  export type { RadioGroupProps, RadioItem, } from "./RadioGroup/RadioGroup.tsx";
102
104
  export { RadioGroup } from "./RadioGroup/RadioGroup.tsx";
103
105
  export type { RailLandmark, RailProps, RailSide, } from "./Rail/Rail.tsx";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -64,6 +64,7 @@ export { Modal } from "./Modal/Modal.js";
64
64
  export { Popover } from "./Popover/Popover.js";
65
65
  export { ProgressBar } from "./ProgressBar/ProgressBar.js";
66
66
  export { getProgressIntent, toProgressPercent, toProgressValue, } from "./ProgressBar/progressValue.js";
67
+ export { QueryBuilder } from "./QueryBuilder/QueryBuilder.js";
67
68
  export { RadioGroup } from "./RadioGroup/RadioGroup.js";
68
69
  export { Rail } from "./Rail/Rail.js";
69
70
  export { AnchorLink } from "./RouterLink/AnchorLink.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@charcuterie/ui",
3
- "version": "2.12.1",
3
+ "version": "2.14.0",
4
4
  "description": "The Charcuterie components. Tokens for look, @charcuterie/logic for state, ARIA that agents can actually drive.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -48,7 +48,7 @@
48
48
  "typecheck": "tsc --noEmit"
49
49
  },
50
50
  "dependencies": {
51
- "@charcuterie/logic": "1.4.0",
51
+ "@charcuterie/logic": "1.5.0",
52
52
  "@charcuterie/tokens": "1.5.0",
53
53
  "@floating-ui/react": "^0.27.20",
54
54
  "@tanstack/react-virtual": "^3.13.12"
@@ -0,0 +1,70 @@
1
+ import { Canvas, Controls, Meta } from "@storybook/addon-docs/blocks";
2
+
3
+ import * as QueryBuilderStories from "./QueryBuilder.stories";
4
+
5
+ <Meta of={QueryBuilderStories} />
6
+
7
+ # QueryBuilder
8
+
9
+ The generic, nestable **AND/OR — and any-combinator — group editor**. A recursive group of
10
+ conditions, each group carrying a combinator the app owns and each leaf carrying a value the
11
+ app owns. Two apps in the fleet grow the same widget from opposite ends: Mail Sifter's nested
12
+ mail rules (leaf = field/operator/value, combinators AND/OR) and mux-magic's job DSL
13
+ (non-uniform leaves, combinators any/all/none). So both the **leaf value** and the **group
14
+ combinator** are fully opaque here — `Combinator` and `Leaf` only ever pass through to the
15
+ consumer's `renderLeaf` and `combinatorOptions`.
16
+
17
+ <Canvas of={QueryBuilderStories.Default} />
18
+
19
+ ## Props
20
+
21
+ <Controls />
22
+
23
+ ## The state is a `Tree`, and the consumer owns it
24
+
25
+ `QueryBuilder` holds no state of its own. It takes a `Tree` core from
26
+ [`useTree`](?path=/docs/state-usetree--docs) and subscribes to it, the same way a `Listbox`'s
27
+ parent owns `useVisibility` and hands it down. That is what leaves `serialize()` — the
28
+ YAML/DB round-trip — and the initial tree in the consumer's hands.
29
+
30
+ ```tsx
31
+ const tree = useTree<Combinator, Leaf>({
32
+ defaultCombinator: "and",
33
+ initialTree,
34
+ })
35
+
36
+ <QueryBuilder
37
+ combinatorOptions={COMBINATOR_OPTIONS}
38
+ createLeafValue={() => ({ field: "subject", operator: "contains", value: "" })}
39
+ renderLeaf={({ value, onChange }) => <ConditionFields value={value} onChange={onChange} />}
40
+ tree={tree}
41
+ />
42
+ ```
43
+
44
+ Because the tree is normalized and addressed by id, a `patchLeaf` deep in the tree re-renders
45
+ only the rows whose node identity changed — the same `useSyncExternalStore` identity
46
+ discipline the whole state layer rests on.
47
+
48
+ ## Nesting, and depth
49
+
50
+ A group renders leaf rows and nested groups, recursively. The nested group wears a
51
+ semantic-token inline-start rail so depth reads without a raw palette colour, and it moves to
52
+ the sunken surface so it recedes rather than floating at the same level as its parent.
53
+
54
+ <Canvas of={QueryBuilderStories.AllStates} />
55
+
56
+ ## Driving it
57
+
58
+ Every control is nameable, not a `data-testid`: the combinator picker is a `Listbox` whose
59
+ trigger is named `Match: <current combinator>`, the leaf controls by their own labels, and each
60
+ delete is an `IconButton` whose required `label` makes it findable. Add a condition, nest a
61
+ group, flip a combinator, delete a row — all reachable by role and name.
62
+
63
+ The picker is a `Listbox` rather than a native `Select`, per
64
+ [the 2026-08-10 demotion](../../../../docs/decisions/2026-08-10-listbox-and-combobox-are-the-default-and-select-is-demoted.md).
65
+ Its name carries the current value because the trigger's visible text *is* that value, and
66
+ WCAG 2.5.3 wants the visible text contained in the accessible name — so query it with
67
+ `getByRole("button", { name: /^Match: / })`, not by the bare caption. Rename the caption with
68
+ `labels.match`.
69
+
70
+ <Canvas of={QueryBuilderStories.Interactive} />