Custom menu item instead of icon buttons #955
Answered
by
jakeboone02
KaralyosBela
asked this question in
Q&A
-
Beta Was this translation helpful? Give feedback.
Answered by
jakeboone02
Oct 15, 2025
Replies: 1 comment 1 reply
-
|
There's no built-in way to do this today, but I love the idea! I'll think about how to facilitate this kind of behavior in a more "native" way. In the meantime what I'd recommend is overriding Here's a sandbox where I replaced the rule remove button with a poor man's "menu" using some cheeky CSS on a
The styles aren't really important, but the component logic should give you some ideas. RuleActionMenu.tsximport {
ActionElement,
defaultTranslations,
findPath,
getParentPath,
move,
standardClassnames,
update,
useQueryBuilderQuery,
type ActionProps,
} from 'react-querybuilder';
export const RuleActionMenu = (props: ActionProps) => {
const clone = () => {
const newPath = [...getParentPath(props.path), props.path.at(-1)! + 1];
props.schema.dispatchQuery(
move(props.schema.getQuery(), props.path, newPath, {
clone: true,
combinators: props.schema.combinators,
})
);
};
const lock = () => {
props.schema.dispatchQuery(
update(props.schema.getQuery(), 'disabled', !props.disabled, props.path)
);
};
return (
<details>
{/* See ./styles.css for styling */}
<summary></summary>
<div>
{/* Clone button */}
<ActionElement
{...props}
label={defaultTranslations.cloneRule.label}
title={defaultTranslations.cloneRule.title}
className={standardClassnames.cloneRule}
ruleOrGroup={props.ruleOrGroup}
handleOnClick={clone}
/>
{/* Delete button (default, so just spread `props` as is) */}
<ActionElement {...props} />
{/* Lock button */}
<ActionElement
{...props}
label={defaultTranslations.lockRule.label}
title={defaultTranslations.lockRule.title}
className={standardClassnames.lockRule}
ruleOrGroup={props.ruleOrGroup}
handleOnClick={lock}
disabledTranslation={
findPath(getParentPath(props.path), useQueryBuilderQuery(props))
?.disabled
? undefined
: defaultTranslations.lockRuleDisabled
}
/>
</div>
</details>
);
};styles.css@import 'react-querybuilder/dist/query-builder.css';
body {
margin: 0.5rem !important;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
}
details,
details > div {
display: flex;
}
details > div {
gap: var(--rqb-spacing);
}
details summary {
list-style: none; /* Hide the default marker */
cursor: pointer;
}
details summary::before {
content: '☰';
display: inline-block;
margin-right: 0.5em;
transition: transform 0.2s;
}
details[open] summary::before {
transform: rotate(-90deg);
} |
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
KaralyosBela
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment


There's no built-in way to do this today, but I love the idea! I'll think about how to facilitate this kind of behavior in a more "native" way.
In the meantime what I'd recommend is overriding
removeRuleActionand rendering the menu with all three buttons instead of just the "remove" button.Here's a sandbox where I replaced the rule remove button with a poor man's "menu" using some cheeky CSS on a
<details>element:The styles aren't really important, but the component logic should give you some ideas.
RuleActionMenu…