react-querybuilder
Version:
React Query Builder component for constructing queries and filters, with utilities for executing them in various database and evaluation contexts
1 lines • 234 kB
Source Map (JSON)
{"version":3,"file":"defaults-mONjSyj5.mjs","names":["DragHandle: React.ForwardRefExoticComponent<\n DragHandleProps & React.RefAttributes<HTMLSpanElement>\n>","dummyFieldData: FullField","dummyPath: Path","initialState: QueriesSliceState","queriesSlice: Slice<\n QueriesSliceState,\n {\n setQueryState: (\n state: QueriesSliceState,\n {\n payload: { qbId, query },\n }: PayloadAction<SetQueryStateParams>\n ) => void;\n },\n 'queries',\n 'queries',\n { getQuerySelectorById: (state: QueriesSliceState, qbId: string) => RuleGroupTypeAny }\n>","QueryBuilderStateContext: React.Context<ReactReduxContextValue<RqbState> | null>","initialState: WarningsSliceState","warningsSlice: Slice<\n WarningsSliceState,\n {\n // oxlint-disable-next-line typescript/no-explicit-any\n rqbWarn: (state: any, { payload }: PayloadAction<Messages>) => void;\n },\n 'warnings'\n>","rootReducer: CombinedSliceReducer<{\n queries: QueriesSliceState;\n warnings: WarningsSliceState;\n}>","useRQB_INTERNAL_QueryBuilderDispatch: UseQueryBuilderDispatch","useRQB_INTERNAL_QueryBuilderStore: UseStore<Store<RqbState>>","useRQB_INTERNAL_QueryBuilderSelector: TypedUseSelectorHook<RqbState>","storeCommon: ConfigureStoreOptions","_store: RqbStore | null","useQueryBuilderSelector: TypedUseSelectorHook<RqbState>","defaultValidationResult: ReturnType<QueryValidator>","defaultValidationMap: ValidationMap","defaultDisabledPaths: Path[]","validationResult","combinatorPropObject: Pick<RuleGroupProps, 'combinator'>","value: string | (string | null)[] | boolean | null","QueryBuilderContext: Context<QueryBuilderContextType>","RuleGroup: React.MemoExoticComponent<(props: RuleGroupProps) => React.JSX.Element>","RuleGroup","RuleGroupHeaderComponents: React.MemoExoticComponent<\n (rg: UseRuleGroup) => React.JSX.Element\n>","RuleGroupHeaderComponents","RuleGroupBodyComponents: React.MemoExoticComponent<\n (rg: UseRuleGroup) => React.JSX.Element\n>","RuleGroupBodyComponents","onCombinatorChange: ValueChangeEventHandler","addRule: ActionElementEventHandler","addGroup: ActionElementEventHandler","cloneGroup: ActionElementEventHandler","toggleLockGroup: ActionElementEventHandler","toggleMuteGroup: ActionElementEventHandler","removeGroup: ActionElementEventHandler","bi: bigint","QueryBuilderContext","_QBC","nullFwdComp: ForwardRefExoticComponent<DragHandleProps & RefAttributes<HTMLElement>>","rqbContext: QueryBuilderContextProps<F, O>","contextCE: ControlElementsProp<F, O>","propsCE: ControlElementsProp<F, O>","propsT: Partial<Translations>","contextT: Partial<Translations>","paths: PathInfo[]","defaultSubproperties: FullOption[]","Rule: React.MemoExoticComponent<(r: RuleProps) => React.JSX.Element>","Rule","RuleComponents: React.MemoExoticComponent<\n (r: RuleComponentsProps) => React.JSX.Element\n>","RuleComponents","RuleComponentsWithSubQuery: React.MemoExoticComponent<\n (r: RuleComponentsProps) => React.JSX.Element\n>","RuleComponentsWithSubQuery","cloneRule: ActionElementEventHandler","toggleLockRule: ActionElementEventHandler","toggleMuteRule: ActionElementEventHandler","removeRule: ActionElementEventHandler","shiftRuleUp: ActionElementEventHandler","shiftRuleDown: ActionElementEventHandler","fieldData: FullField","defaultControlElements: {\n actionElement: typeof ActionElement;\n addGroupAction: typeof ActionElement;\n addRuleAction: typeof ActionElement;\n cloneGroupAction: typeof ActionElement;\n cloneRuleAction: typeof ActionElement;\n combinatorSelector: typeof ValueSelector;\n dragHandle: typeof DragHandle;\n fieldSelector: typeof ValueSelector;\n inlineCombinator: typeof InlineCombinator;\n lockGroupAction: typeof ActionElement;\n lockRuleAction: typeof ActionElement;\n matchModeEditor: typeof MatchModeEditor;\n muteGroupAction: typeof ActionElement;\n muteRuleAction: typeof ActionElement;\n notToggle: typeof NotToggle;\n operatorSelector: typeof ValueSelector;\n removeGroupAction: typeof ActionElement;\n removeRuleAction: typeof ActionElement;\n rule: typeof Rule;\n ruleGroup: typeof RuleGroup;\n ruleGroupBodyElements: typeof RuleGroupBodyComponents;\n ruleGroupHeaderElements: typeof RuleGroupHeaderComponents;\n shiftActions: typeof ShiftActions;\n valueEditor: typeof ValueEditor;\n valueSelector: typeof ValueSelector;\n valueSourceSelector: typeof ValueSelector;\n}"],"sources":["../src/components/ActionElement.tsx","../src/components/DragHandle.tsx","../src/components/InlineCombinator.tsx","../src/components/MatchModeEditor.tsx","../src/components/NotToggle.tsx","../src/messages.ts","../src/redux/queriesSlice.ts","../src/redux/QueryBuilderStateContext.ts","../src/redux/warningsSlice.ts","../src/redux/rootReducer.ts","../src/redux/_internal/hooks.ts","../src/redux/_internal/index.ts","../src/hooks/usePrevious.ts","../src/hooks/useControlledOrUncontrolled.ts","../src/hooks/useDeprecatedProps.ts","../src/hooks/useFields.ts","../src/redux/configureRqbStore.ts","../src/redux/getRqbStore.ts","../src/redux/selectors.ts","../src/redux/hooks.ts","../src/components/QueryBuilder.useQueryBuilderSchema.ts","../src/components/QueryBuilder.useQueryBuilderSetup.ts","../src/components/QueryBuilder.useQueryBuilder.ts","../src/components/QueryBuilderContext.ts","../src/components/RuleGroup.tsx","../src/components/ShiftActions.tsx","../src/components/ValueEditor.tsx","../src/hooks/useSelectElementChangeHandler.ts","../src/utils/getCompatContextProvider.tsx","../src/utils/mergeTranslations.ts","../src/utils/toOptions.tsx","../src/components/ValueSelector.tsx","../src/components/QueryBuilderInternal.tsx","../src/hooks/useMergedContext.ts","../src/hooks/useOptionListProp.ts","../src/hooks/usePathsMemo.ts","../src/hooks/usePreferProp.ts","../src/hooks/useReactDndWarning.ts","../src/hooks/useStopEventPropagation.ts","../src/components/Rule.tsx","../src/defaults.ts"],"sourcesContent":["import * as React from 'react';\nimport type { ActionProps } from '../types';\n\n/**\n * Default `<button>` component used by {@link QueryBuilder}.\n *\n * @group Components\n */\nexport const ActionElement = (props: ActionProps): React.JSX.Element => (\n <button\n type=\"button\"\n data-testid={props.testID}\n disabled={props.disabled && !props.disabledTranslation}\n className={props.className}\n title={\n props.disabledTranslation && props.disabled ? props.disabledTranslation.title : props.title\n }\n onClick={e => props.handleOnClick(e)}>\n {props.disabledTranslation && props.disabled ? props.disabledTranslation.label : props.label}\n </button>\n);\n","import * as React from 'react';\nimport { forwardRef } from 'react';\nimport type { DragHandleProps } from '../types';\n\n/**\n * Default drag handle component used by {@link QueryBuilder} when `enableDragAndDrop` is `true`.\n *\n * @group Components\n */\nexport const DragHandle: React.ForwardRefExoticComponent<\n DragHandleProps & React.RefAttributes<HTMLSpanElement>\n> = forwardRef<HTMLSpanElement, DragHandleProps>((props, dragRef) => (\n <span data-testid={props.testID} ref={dragRef} className={props.className} title={props.title}>\n {props.label}\n </span>\n));\n","import { clsx, standardClassnames, TestID } from '@react-querybuilder/core';\nimport * as React from 'react';\nimport type { InlineCombinatorProps } from '../types';\n\n/**\n * Default `inlineCombinator` component used by {@link QueryBuilder}. A small `<div>`\n * wrapper around the `combinatorSelector` component, used when either\n * `showCombinatorsBetweenRules` or `independentCombinators` are `true`.\n *\n * @group Components\n */\nexport const InlineCombinator = (allProps: InlineCombinatorProps): React.JSX.Element => {\n const { component: CombinatorSelectorComponent, ...props } = allProps;\n\n const className = clsx(\n props.schema.suppressStandardClassnames || standardClassnames.betweenRules,\n props.schema.classNames.betweenRules\n );\n\n return (\n <div className={className} data-testid={TestID.inlineCombinator}>\n <CombinatorSelectorComponent {...props} testID={TestID.combinators} />\n </div>\n );\n};\n","import type { FullField, MatchMode, Path, RuleType } from '@react-querybuilder/core';\nimport { lc, parseNumber } from '@react-querybuilder/core';\nimport * as React from 'react';\nimport { useCallback } from 'react';\nimport type { MatchModeEditorProps, Schema } from '../types';\n\nconst dummyFieldData: FullField = { name: '', value: '', label: '' };\nconst requiresThreshold = (mm?: string | null) =>\n ['atleast', 'atmost', 'exactly'].includes(lc(mm) ?? /* istanbul ignore next */ '');\nconst dummyPath: Path = [];\n\n/**\n * Default `matchModeEditor` component used by {@link QueryBuilder}.\n *\n * @group Components\n */\nexport const MatchModeEditor = (props: MatchModeEditorProps): React.JSX.Element | null => {\n const {\n match,\n options,\n title,\n className,\n disabled,\n testID,\n schema,\n selectorComponent: SelectorComponent = props.schema.controls.valueSelector,\n numericEditorComponent: NumericEditorComponent = props.schema.controls.valueEditor,\n } = props;\n\n const { thresholdNum, thresholdRule, thresholdSchema, handleChangeMode, handleChangeThreshold } =\n useMatchModeEditor(props);\n\n return (\n <React.Fragment>\n <SelectorComponent\n schema={schema}\n testID={testID}\n className={className}\n title={title}\n handleOnChange={handleChangeMode}\n disabled={disabled}\n value={match.mode}\n options={options}\n multiple={false}\n listsAsArrays={false}\n path={dummyPath}\n level={0}\n />\n {requiresThreshold(match.mode) && (\n <NumericEditorComponent\n skipHook\n testID={testID}\n inputType=\"number\"\n // TODO: Implement `matchThresholdPlaceholderText`?\n // placeholder={placeHolderText}\n title={title}\n className={className}\n disabled={disabled}\n handleOnChange={handleChangeThreshold}\n field={''}\n operator={''}\n value={thresholdNum}\n valueSource={'value'}\n fieldData={dummyFieldData}\n schema={thresholdSchema}\n path={dummyPath}\n level={0}\n rule={thresholdRule}\n />\n )}\n </React.Fragment>\n );\n};\n\nexport interface UseMatchModeEditor {\n thresholdNum: number;\n thresholdRule: RuleType;\n thresholdSchema: Schema<FullField, string>;\n handleChangeMode: (mode: MatchMode) => void;\n handleChangeThreshold: (threshold: number) => void;\n}\nexport const useMatchModeEditor = (props: MatchModeEditorProps): UseMatchModeEditor => {\n const { match, handleOnChange } = props;\n\n const thresholdNum = React.useMemo(\n () => (typeof match.threshold === 'number' ? Math.max(0, match.threshold) : 1),\n [match.threshold]\n );\n const thresholdRule = React.useMemo(\n () => ({ field: '', operator: '=', value: thresholdNum }),\n [thresholdNum]\n );\n const thresholdSchema = React.useMemo(\n () => ({ ...props.schema, parseNumbers: true }),\n [props.schema]\n );\n\n const handleChangeMode = useCallback(\n (mode: MatchMode) => {\n if (requiresThreshold(mode) && typeof match.threshold !== 'number') {\n handleOnChange({ ...match, mode, threshold: 1 });\n } else {\n handleOnChange({ ...match, mode });\n }\n },\n [handleOnChange, match]\n );\n\n const handleChangeThreshold = useCallback(\n (threshold: number) => {\n handleOnChange({ ...match, threshold: parseNumber(threshold, { parseNumbers: true }) });\n },\n [handleOnChange, match]\n );\n\n return {\n thresholdNum,\n thresholdRule,\n thresholdSchema,\n handleChangeMode,\n handleChangeThreshold,\n };\n};\n","import * as React from 'react';\nimport type { NotToggleProps } from '../types';\n\n/**\n * Default `notToggle` (aka inversion) component used by {@link QueryBuilder}.\n *\n * @group Components\n */\nexport const NotToggle = (props: NotToggleProps): React.JSX.Element => {\n const id = React.useId();\n return (\n <label data-testid={props.testID} className={props.className} title={props.title} htmlFor={id}>\n <input\n id={id}\n type=\"checkbox\"\n onChange={e => props.handleOnChange(e.target.checked)}\n checked={!!props.checked}\n disabled={props.disabled}\n />\n {props.label}\n </label>\n );\n};\n","export const messages = {\n errorInvalidIndependentCombinatorsProp:\n 'QueryBuilder was rendered with a truthy independentCombinators prop. This prop is deprecated and unnecessary. Furthermore, the initial query/defaultQuery prop was of type RuleGroupType instead of type RuleGroupIC. More info: https://react-querybuilder.js.org/docs/components/querybuilder#independent-combinators',\n\n errorUnnecessaryIndependentCombinatorsProp:\n 'QueryBuilder was rendered with the deprecated and unnecessary independentCombinators prop. To use independent combinators, make sure the query/defaultQuery prop is of type RuleGroupIC when the component mounts. More info: https://react-querybuilder.js.org/docs/components/querybuilder#independent-combinators',\n\n errorDeprecatedRuleGroupProps:\n 'A custom RuleGroup component has rendered a standard RuleGroup component with deprecated props. The combinator, not, and rules props should not be used. Instead, the full group object should be passed as the ruleGroup prop.',\n\n errorDeprecatedRuleProps:\n 'A custom RuleGroup component has rendered a standard Rule component with deprecated props. The field, operator, value, and valueSource props should not be used. Instead, the full rule object should be passed as the rule prop.',\n\n errorBothQueryDefaultQuery:\n 'QueryBuilder was rendered with both query and defaultQuery props. QueryBuilder must be either controlled or uncontrolled (specify either the query prop, or the defaultQuery prop, but not both). Decide between using a controlled or uncontrolled query builder and remove one of these props. More info: https://reactjs.org/link/controlled-components',\n\n errorUncontrolledToControlled:\n 'QueryBuilder is changing from an uncontrolled component to be controlled. This is likely caused by the query changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled query builder for the lifetime of the component. More info: https://reactjs.org/link/controlled-components',\n\n errorControlledToUncontrolled:\n 'QueryBuilder is changing from a controlled component to be uncontrolled. This is likely caused by the query changing from defined to undefined, which should not happen. Decide between using a controlled or uncontrolled query builder for the lifetime of the component. More info: https://reactjs.org/link/controlled-components',\n\n errorEnabledDndWithoutReactDnD:\n 'QueryBuilder was rendered with the enableDragAndDrop prop set to true, but either react-dnd was not detected or one of react-dnd-html5-backend or react-dnd-touch-backend was not detected. To enable drag-and-drop functionality, install react-dnd and one of the backend packages and wrap QueryBuilder in QueryBuilderDnD from @react-querybuilder/dnd.',\n\n errorDeprecatedDebugImport: `Importing from react-querybuilder/debug is deprecated. To enable Redux DevTools for React Query Builder's internal store, set globalThis.__RQB_DEVTOOLS__ = true.`,\n} as const;\n","import type { RuleGroupTypeAny } from '@react-querybuilder/core';\nimport type { PayloadAction, Slice } from '@reduxjs/toolkit';\nimport { createSlice } from '@reduxjs/toolkit';\n\nexport type QueriesSliceState = Record<string, RuleGroupTypeAny>;\n\nexport interface SetQueryStateParams {\n qbId: string;\n query: RuleGroupTypeAny;\n}\n\nconst initialState: QueriesSliceState = {};\n\nexport const queriesSlice: Slice<\n QueriesSliceState,\n {\n setQueryState: (\n state: QueriesSliceState,\n {\n payload: { qbId, query },\n }: PayloadAction<SetQueryStateParams>\n ) => void;\n },\n 'queries',\n 'queries',\n { getQuerySelectorById: (state: QueriesSliceState, qbId: string) => RuleGroupTypeAny }\n> = createSlice({\n name: 'queries',\n initialState,\n reducers: {\n setQueryState: (state, { payload: { qbId, query } }) => {\n state[qbId] = query;\n },\n },\n selectors: {\n getQuerySelectorById: (state, qbId) => state[qbId],\n },\n});\n","import * as React from 'react';\nimport type { ReactReduxContextValue } from 'react-redux';\nimport type { RqbState } from './types';\n\nexport const QueryBuilderStateContext: React.Context<ReactReduxContextValue<RqbState> | null> =\n React.createContext<ReactReduxContextValue<RqbState> | null>(null);\n","import type { PayloadAction, Slice } from '@reduxjs/toolkit';\nimport { createSlice } from '@reduxjs/toolkit';\nimport { messages } from '../messages';\n\ntype ValuesAsKeys<T> =\n T extends Record<infer _K, infer V>\n ? [V] extends [string]\n ? { [Key in V]: boolean }\n : never\n : never;\ntype ValuesType<T> =\n T extends Record<infer _K, infer V> ? ([V] extends [string] ? V : never) : never;\nexport type WarningsSliceState = ValuesAsKeys<typeof messages>;\nexport type Messages = ValuesType<typeof messages>;\nconst initialState: WarningsSliceState = {\n [messages.errorInvalidIndependentCombinatorsProp]: false,\n [messages.errorUnnecessaryIndependentCombinatorsProp]: false,\n [messages.errorDeprecatedRuleGroupProps]: false,\n [messages.errorDeprecatedRuleProps]: false,\n [messages.errorBothQueryDefaultQuery]: false,\n [messages.errorUncontrolledToControlled]: false,\n [messages.errorControlledToUncontrolled]: false,\n [messages.errorEnabledDndWithoutReactDnD]: false,\n [messages.errorDeprecatedDebugImport]: false,\n};\n\nexport const warningsSlice: Slice<\n WarningsSliceState,\n {\n // oxlint-disable-next-line typescript/no-explicit-any\n rqbWarn: (state: any, { payload }: PayloadAction<Messages>) => void;\n },\n 'warnings'\n> = createSlice({\n name: 'warnings',\n initialState,\n reducers: {\n rqbWarn: (state, { payload }) => {\n if (!state[payload]) {\n console.error(payload);\n state[payload] = true;\n }\n },\n },\n});\n","import type { CombinedSliceReducer } from '@reduxjs/toolkit';\nimport { combineSlices } from '@reduxjs/toolkit';\nimport type { QueriesSliceState } from './queriesSlice';\nimport { queriesSlice } from './queriesSlice';\nimport type { WarningsSliceState } from './warningsSlice';\nimport { warningsSlice } from './warningsSlice';\n\nexport interface LazyLoadedSlices {}\n\nexport const rootReducer: CombinedSliceReducer<{\n queries: QueriesSliceState;\n warnings: WarningsSliceState;\n}> = combineSlices(queriesSlice, warningsSlice).withLazyLoadedSlices<LazyLoadedSlices>();\n","import type { Dispatch, Store, ThunkDispatch, UnknownAction } from '@reduxjs/toolkit';\nimport React from 'react';\nimport type { ReactReduxContextValue, TypedUseSelectorHook, UseStore } from 'react-redux';\nimport { createDispatchHook, createSelectorHook, createStoreHook } from 'react-redux';\nimport type { RqbState } from '../types';\n\nconst genUseQueryBuilderDispatch = (\n ctx: React.Context<ReactReduxContextValue<RqbState> | null>\n): UseQueryBuilderDispatch => createDispatchHook(ctx);\nexport type UseQueryBuilderDispatch = () => ThunkDispatch<RqbState, undefined, UnknownAction> &\n Dispatch;\n\nconst genUseQueryBuilderStore = (\n ctx: React.Context<ReactReduxContextValue<RqbState> | null>\n): UseStore<Store<RqbState>> => createStoreHook(ctx);\n\nconst genUseQueryBuilderSelector = (\n ctx: React.Context<ReactReduxContextValue<RqbState> | null>\n): TypedUseSelectorHook<RqbState> => createSelectorHook(ctx);\n\nexport const getInternalHooks = (\n ctx: React.Context<ReactReduxContextValue<RqbState> | null>\n): {\n useRQB_INTERNAL_QueryBuilderDispatch: UseQueryBuilderDispatch;\n useRQB_INTERNAL_QueryBuilderStore: UseStore<Store<RqbState>>;\n useRQB_INTERNAL_QueryBuilderSelector: TypedUseSelectorHook<RqbState>;\n} => ({\n useRQB_INTERNAL_QueryBuilderDispatch: genUseQueryBuilderDispatch(ctx),\n useRQB_INTERNAL_QueryBuilderStore: genUseQueryBuilderStore(ctx),\n useRQB_INTERNAL_QueryBuilderSelector: genUseQueryBuilderSelector(ctx),\n});\n","import type { RuleGroupType, RuleGroupTypeIC } from '@react-querybuilder/core';\nimport type { ConfigureStoreOptions, PayloadAction, Store, ThunkAction } from '@reduxjs/toolkit';\nimport type { TypedUseSelectorHook, UseStore } from 'react-redux';\nimport type { SetQueryStateParams } from '../queriesSlice';\nimport { queriesSlice } from '../queriesSlice';\nimport { QueryBuilderStateContext } from '../QueryBuilderStateContext';\nimport { rootReducer } from '../rootReducer';\nimport type { RqbState } from '../types';\nimport type { Messages } from '../warningsSlice';\nimport { warningsSlice } from '../warningsSlice';\nimport type { UseQueryBuilderDispatch } from './hooks';\nimport { getInternalHooks } from './hooks';\n\nexport const _RQB_INTERNAL_dispatchThunk =\n ({\n payload,\n onQueryChange,\n }: {\n payload: SetQueryStateParams;\n onQueryChange?: ((query: RuleGroupType) => void) | ((query: RuleGroupTypeIC) => void);\n }): ThunkAction<void, RqbState, unknown, PayloadAction<SetQueryStateParams>> =>\n dispatch => {\n dispatch(queriesSlice.actions.setQueryState(payload));\n if (typeof onQueryChange === 'function') {\n onQueryChange(payload.query as never /* ??? */);\n }\n };\n\nconst internalHooks = getInternalHooks(QueryBuilderStateContext);\n\n/**\n * Gets the `dispatch` function for the RQB Redux store.\n */\nexport const useRQB_INTERNAL_QueryBuilderDispatch: UseQueryBuilderDispatch =\n internalHooks.useRQB_INTERNAL_QueryBuilderDispatch;\n/**\n * Gets the full RQB Redux store.\n */\nexport const useRQB_INTERNAL_QueryBuilderStore: UseStore<Store<RqbState>> =\n internalHooks.useRQB_INTERNAL_QueryBuilderStore;\n/**\n * General purpose selector hook for the RQB Redux store.\n */\nexport const useRQB_INTERNAL_QueryBuilderSelector: TypedUseSelectorHook<RqbState> =\n internalHooks.useRQB_INTERNAL_QueryBuilderSelector;\n\nconst { rqbWarn: _SYNC_rqbWarn } = warningsSlice.actions;\n\nexport const rqbWarn =\n (msg: Messages): ThunkAction<void, RqbState, unknown, PayloadAction<Messages>> =>\n dispatch => {\n setTimeout(() => dispatch(_SYNC_rqbWarn(msg)));\n };\n\nconst preloadedState = {\n queries: queriesSlice.getInitialState(),\n warnings: warningsSlice.getInitialState(),\n // Avoid importing the async slice itself to ensure lazy loading\n // asyncOptionLists: { cache: {}, loading: {}, errors: {} },\n} as RqbState;\n\nexport const storeCommon: ConfigureStoreOptions = {\n reducer: rootReducer,\n preloadedState,\n middleware: getDefaultMiddleware =>\n getDefaultMiddleware({\n // Ignore non-serializable values in setQueryState actions and rule `value`s\n // https://redux-toolkit.js.org/usage/usage-guide#working-with-non-serializable-data\n serializableCheck: {\n ignoredActions: [queriesSlice.actions.setQueryState.type],\n ignoredPaths: [/^queries\\b.*\\.rules\\.\\d+\\.value$/],\n },\n }),\n};\n","import { useRef } from 'react';\n\n/**\n * Returns the prop value from the last render.\n *\n * Adapted from https://usehooks.com/usePrevious/.\n *\n * @group Hooks\n */\nexport const usePrevious = <T>(value: T): T | null => {\n const ref = useRef<{ value: T | null; prev: T | null }>({ value, prev: null });\n\n const current = ref.current.value;\n\n if (value !== current) {\n // ref.current = { value, prev: current };\n ref.current.prev = current;\n ref.current.value = value;\n }\n\n return ref.current.prev;\n};\n","import type { RuleGroupTypeAny } from '@react-querybuilder/core';\nimport { messages } from '../messages';\nimport { rqbWarn, useRQB_INTERNAL_QueryBuilderDispatch } from '../redux/_internal';\nimport { usePrevious } from './usePrevious';\n\nexport interface UseControlledOrUncontrolledParams {\n defaultQuery?: RuleGroupTypeAny;\n queryProp?: RuleGroupTypeAny;\n}\n\n/**\n * Logs a warning when the component changes from controlled to uncontrolled,\n * vice versa, or both `query` and `defaultQuery` are provided.\n *\n * @group Hooks\n */\nexport const useControlledOrUncontrolled = (params: UseControlledOrUncontrolledParams): void => {\n const dispatch = useRQB_INTERNAL_QueryBuilderDispatch();\n const { defaultQuery, queryProp } = params;\n const prevQueryPresent = usePrevious(!!queryProp);\n\n // istanbul ignore else\n if (process.env.NODE_ENV !== 'production') {\n if (!!queryProp && !!defaultQuery) {\n dispatch(rqbWarn(messages.errorBothQueryDefaultQuery));\n } else if (prevQueryPresent === true && !queryProp && !!defaultQuery) {\n dispatch(rqbWarn(messages.errorControlledToUncontrolled));\n } else if (prevQueryPresent === false && !!queryProp && !defaultQuery) {\n dispatch(rqbWarn(messages.errorUncontrolledToControlled));\n }\n }\n};\n","import { messages } from '../messages';\nimport { rqbWarn, useRQB_INTERNAL_QueryBuilderDispatch } from '../redux/_internal';\n\n/**\n * Logs an error to the console if any of the following are true:\n * - `QueryBuilder` is rendered with an `independentCombinators` prop\n * - `RuleGroup` is rendered with `combinator` or `rules` props (deprecated in favor of `ruleGroup`)\n * - `Rule` is rendered with `field`, `operator`, or `value` props (deprecated in favor of `rule`)\n *\n * @group Hooks\n */\nfunction useDeprecatedProps(\n type: 'independentCombinators',\n logWarning: boolean,\n otherParams: 'invalid' | 'unnecessary'\n): void;\nfunction useDeprecatedProps(type: 'rule' | 'ruleGroup', logWarning: boolean): void;\nfunction useDeprecatedProps(\n /** Type of error to be logged, if logWarning is true. */\n type: 'independentCombinators' | 'rule' | 'ruleGroup',\n /** If true, the error (well...warning, really) will be logged. */\n logWarning: boolean,\n otherParams?: 'invalid' | 'unnecessary'\n) {\n const dispatch = useRQB_INTERNAL_QueryBuilderDispatch();\n if (process.env.NODE_ENV !== 'production' && logWarning) {\n if (type === 'independentCombinators') {\n if (otherParams === 'invalid') {\n dispatch(rqbWarn(messages.errorInvalidIndependentCombinatorsProp));\n }\n\n if (otherParams === 'unnecessary') {\n dispatch(rqbWarn(messages.errorUnnecessaryIndependentCombinatorsProp));\n }\n }\n\n if (type === 'rule') {\n dispatch(rqbWarn(messages.errorDeprecatedRuleProps));\n }\n\n if (type === 'ruleGroup') {\n dispatch(rqbWarn(messages.errorDeprecatedRuleGroupProps));\n }\n }\n}\n\nexport { useDeprecatedProps };\n","import type {\n FullCombinator,\n FullField,\n FullOperator,\n FullOptionList,\n FullOptionRecord,\n RuleGroupTypeAny,\n} from '@react-querybuilder/core';\nimport { prepareOptionList } from '@react-querybuilder/core';\nimport { useMemo } from 'react';\nimport type { QueryBuilderProps, TranslationsFull } from '../types';\n\nexport interface UseFields<F extends FullField> {\n defaultField: FullField;\n fields: FullOptionList<F>;\n fieldMap: Partial<FullOptionRecord<FullField>>;\n}\n\nexport const useFields = <F extends FullField>(\n props: { translations: TranslationsFull } & Pick<\n QueryBuilderProps<RuleGroupTypeAny, F, FullOperator, FullCombinator>,\n 'fields' | 'baseField' | 'autoSelectField'\n >\n): UseFields<F> => {\n const {\n optionList: fields,\n optionsMap: fieldMap,\n defaultOption: defaultField,\n } = useMemo(\n () =>\n prepareOptionList({\n placeholder: props.translations.fields,\n optionList: props.fields,\n autoSelectOption: props.autoSelectField,\n baseOption: props.baseField,\n }),\n [props.autoSelectField, props.baseField, props.fields, props.translations.fields]\n );\n return { fields, fieldMap, defaultField };\n};\n","import type { Slice } from '@reduxjs/toolkit';\nimport { configureStore } from '@reduxjs/toolkit';\nimport { storeCommon } from './_internal';\nimport { rootReducer } from './rootReducer';\nimport type { RqbStore } from './types';\n\nexport const configureRqbStore = (devTools?: boolean): RqbStore => {\n const queryBuilderStore = configureStore({\n ...storeCommon,\n devTools: devTools ? /* istanbul ignore next */ { name: 'React Query Builder' } : false,\n }) as RqbStore;\n\n queryBuilderStore.addSlice = (slice: Slice) => {\n rootReducer.inject(slice);\n // Initialize state for the new slice. This action is a no-op because\n // the `type` is random and will never match any reducers.\n queryBuilderStore.dispatch({\n type: crypto.randomUUID().slice(0, 8),\n meta: `Initializing state for slice \"${slice.name}\"`,\n });\n };\n\n return queryBuilderStore;\n};\n","import type { Slice } from '@reduxjs/toolkit';\nimport { configureRqbStore } from './configureRqbStore';\nimport type { RqbStore } from './types';\n\nlet _store: RqbStore | null = null;\n\ndeclare global {\n var __RQB_DEVTOOLS__: boolean | undefined;\n}\n\n/**\n * Gets the singleton React Query Builder store instance.\n * DevTools are enabled if either:\n * - globalThis.__RQB_DEVTOOLS__ is truthy\n * - window.__RQB_DEVTOOLS__ is truthy\n */\nexport function getRqbStore(devTools?: boolean): RqbStore {\n if (!_store) {\n const devToolsEnabled = devTools || globalThis?.__RQB_DEVTOOLS__;\n\n _store = configureRqbStore(devToolsEnabled);\n }\n return _store;\n}\n\n/**\n * Injects a slice into the React Query Builder store. Useful for extensions\n * that need to integrate their own state management.\n */\nexport const injectSlice = (slice: Slice): void => getRqbStore().addSlice(slice);\n","import type { RuleGroupTypeAny } from '@react-querybuilder/core';\nimport { queriesSlice } from './queriesSlice';\nimport type { RqbState } from './types';\n\n/**\n * Given a `qbId` (passed to every component as part of the `schema` prop), returns\n * a Redux selector for use with {@link useQueryBuilderSelector}.\n *\n * Note that {@link useQueryBuilderQuery} is a more concise way of accessing the\n * query for the nearest ancestor {@link QueryBuilder} component.\n */\nexport const getQuerySelectorById =\n (qbId: string) =>\n (state: RqbState): RuleGroupTypeAny =>\n queriesSlice.selectors.getQuerySelectorById({ queries: state.queries }, qbId);\n","import type { RuleGroupTypeAny } from '@react-querybuilder/core';\nimport * as React from 'react';\nimport type { TypedUseSelectorHook } from 'react-redux';\nimport { QueryBuilderContext } from '../components';\nimport { useRQB_INTERNAL_QueryBuilderSelector } from './_internal';\nimport { getQuerySelectorById } from './selectors';\nimport type { RqbState } from './types';\n\n/**\n * A Redux `useSelector` hook for RQB's internal store. See also {@link getQuerySelectorById}.\n *\n * **TIP:** Prefer {@link useQueryBuilderQuery} if you only need to access the query object\n * for the nearest ancestor {@link QueryBuilder} component.\n *\n * @group Hooks\n */\nexport const useQueryBuilderSelector: TypedUseSelectorHook<RqbState> = (selector, other) => {\n const rqbContext = React.useContext(QueryBuilderContext);\n // TODO: Why is `as` necessary here?\n const result = useRQB_INTERNAL_QueryBuilderSelector(selector, other as undefined);\n return result ?? rqbContext?.initialQuery;\n};\n\n/**\n * Retrieves the full, latest query object for the nearest ancestor {@link QueryBuilder}\n * component.\n *\n * The optional parameter should only be used when retrieving a query object from a different\n * {@link QueryBuilder} than the nearest ancestor. It can be a full props object as passed\n * to a custom component or any object matching the interface `{ schema: { qbId: string } }`.\n *\n * Must follow React's [Rules of Hooks](https://react.dev/warnings/invalid-hook-call-warning).\n *\n * @group Hooks\n */\nexport const useQueryBuilderQuery = (props?: { schema: { qbId: string } }): RuleGroupTypeAny => {\n const rqbContext = React.useContext(QueryBuilderContext);\n return (\n useRQB_INTERNAL_QueryBuilderSelector(\n getQuerySelectorById(props?.schema.qbId ?? rqbContext.qbId ?? /* istanbul ignore next */ '')\n ) ?? rqbContext?.initialQuery\n );\n};\n","import type {\n FullCombinator,\n FullField,\n FullOperator,\n FullOptionMap,\n GetOptionIdentifierType,\n GetRuleTypeFromGroupWithFieldAndOperator,\n MatchModeOptions,\n Path,\n QueryActions,\n QueryValidator,\n RuleGroupTypeAny,\n RuleGroupTypeIC,\n UpdateableProperties,\n ValidationMap,\n ValueSourceFullOptions,\n} from '@react-querybuilder/core';\nimport {\n add,\n clsx,\n findPath,\n generateAccessibleDescription,\n group,\n isRuleGroup,\n isRuleGroupTypeIC,\n LogType,\n move,\n pathIsDisabled,\n prepareRuleGroup,\n remove,\n standardClassnames,\n update,\n} from '@react-querybuilder/core';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useControlledOrUncontrolled, useDeprecatedProps } from '../hooks/';\nimport { getQuerySelectorById, useQueryBuilderSelector } from '../redux';\nimport {\n _RQB_INTERNAL_dispatchThunk,\n useRQB_INTERNAL_QueryBuilderDispatch,\n useRQB_INTERNAL_QueryBuilderStore,\n} from '../redux/_internal';\nimport type { QueryBuilderProps, RuleGroupProps, Schema, TranslationsFull } from '../types';\nimport type { UseQueryBuilderSetup } from './QueryBuilder.useQueryBuilderSetup';\n\nconst defaultValidationResult: ReturnType<QueryValidator> = {};\nconst defaultValidationMap: ValidationMap = {};\nconst defaultDisabledPaths: Path[] = [];\nconst icCombinatorPropObject = {} as const;\nconst defaultGetValueEditorSeparator = () => null;\nconst defaultGetRuleOrGroupClassname = () => '';\nconst defaultOnAddMoveRemove = () => true;\n// istanbul ignore next\nconst defaultOnLog = (...params: unknown[]) => {\n console.log(...params);\n};\n\nexport type UseQueryBuilderSchema<\n RG extends RuleGroupTypeAny,\n F extends FullField,\n O extends FullOperator,\n C extends FullCombinator,\n> = Pick<UseQueryBuilderSetup<RG, F, O, C>, 'rqbContext'> & {\n actions: QueryActions;\n rootGroup: RuleGroupTypeAny<GetRuleTypeFromGroupWithFieldAndOperator<RG, F, O>>;\n rootGroupDisabled: boolean;\n queryDisabled: boolean;\n schema: Schema<F, GetOptionIdentifierType<O>>;\n translations: TranslationsFull;\n wrapperClassName: string;\n dndEnabledAttr: string;\n inlineCombinatorsAttr: string;\n combinatorPropObject: Pick<RuleGroupProps, 'combinator'>;\n};\n\n/**\n * For given {@link QueryBuilderProps} and setup values from {@link useQueryBuilderSetup},\n * prepares and returns all values required to render a query builder.\n *\n * @group Hooks\n */\nexport function useQueryBuilderSchema<\n RG extends RuleGroupTypeAny,\n F extends FullField,\n O extends FullOperator,\n C extends FullCombinator,\n>(\n props: QueryBuilderProps<RG, F, O, C>,\n setup: UseQueryBuilderSetup<RG, F, O, C>\n): UseQueryBuilderSchema<RG, F, O, C> {\n type R = GetRuleTypeFromGroupWithFieldAndOperator<RG, F, O>;\n\n const {\n query: queryProp,\n defaultQuery: defaultQueryProp,\n getValueEditorSeparator = defaultGetValueEditorSeparator,\n getRuleClassname = defaultGetRuleOrGroupClassname,\n getRuleGroupClassname = defaultGetRuleOrGroupClassname,\n onAddRule = defaultOnAddMoveRemove,\n onAddGroup = defaultOnAddMoveRemove,\n onMoveRule = defaultOnAddMoveRemove,\n onMoveGroup = defaultOnAddMoveRemove,\n onGroupRule = defaultOnAddMoveRemove,\n onGroupGroup = defaultOnAddMoveRemove,\n onRemove = defaultOnAddMoveRemove,\n onQueryChange,\n showCombinatorsBetweenRules: showCombinatorsBetweenRulesProp = false,\n showNotToggle: showNotToggleProp = false,\n showShiftActions: showShiftActionsProp = false,\n showCloneButtons: showCloneButtonsProp = false,\n showLockButtons: showLockButtonsProp = false,\n showMuteButtons: showMuteButtonsProp = false,\n suppressStandardClassnames: suppressStandardClassnamesProp = false,\n resetOnFieldChange: resetOnFieldChangeProp = true,\n resetOnOperatorChange: resetOnOperatorChangeProp = false,\n autoSelectField: autoSelectFieldProp = true,\n autoSelectOperator: autoSelectOperatorProp = true,\n autoSelectValue: autoSelectValueProp = true,\n addRuleToNewGroups: addRuleToNewGroupsProp = false,\n listsAsArrays: listsAsArraysProp = false,\n parseNumbers = false,\n disabled = false,\n validator,\n onLog = defaultOnLog,\n idGenerator,\n accessibleDescriptionGenerator = generateAccessibleDescription,\n } = props;\n\n const {\n qbId,\n rqbContext: incomingRqbContext,\n fields,\n fieldMap,\n combinators,\n getOperatorsMain,\n getMatchModesMain,\n getRuleDefaultOperator,\n getSubQueryBuilderPropsMain,\n getValueEditorTypeMain,\n getValueSourcesMain,\n getValuesMain,\n getRuleDefaultValue,\n getInputTypeMain,\n createRule,\n createRuleGroup,\n } = setup;\n\n const {\n controlClassnames,\n controlElements: controls,\n debugMode,\n enableDragAndDrop,\n enableMountQueryChange,\n translations,\n } = incomingRqbContext;\n\n // #region Type coercions\n const showCombinatorsBetweenRules = !!showCombinatorsBetweenRulesProp;\n const showNotToggle = !!showNotToggleProp;\n const showShiftActions = !!showShiftActionsProp;\n const showCloneButtons = !!showCloneButtonsProp;\n const showLockButtons = !!showLockButtonsProp;\n const showMuteButtons = !!showMuteButtonsProp;\n const resetOnFieldChange = !!resetOnFieldChangeProp;\n const resetOnOperatorChange = !!resetOnOperatorChangeProp;\n const autoSelectField = !!autoSelectFieldProp;\n const autoSelectOperator = !!autoSelectOperatorProp;\n const autoSelectValue = !!autoSelectValueProp;\n const addRuleToNewGroups = !!addRuleToNewGroupsProp;\n const listsAsArrays = !!listsAsArraysProp;\n const suppressStandardClassnames = !!suppressStandardClassnamesProp;\n const maxLevels = (props.maxLevels ?? 0) > 0 ? Number(props.maxLevels) : Infinity;\n // #endregion\n\n const log = useCallback(\n (...params: unknown[]) => {\n if (debugMode) {\n onLog(...params);\n }\n },\n [debugMode, onLog]\n );\n\n // #region Controlled vs uncontrolled mode\n useControlledOrUncontrolled({\n defaultQuery: defaultQueryProp,\n queryProp,\n });\n\n const queryBuilderStore = useRQB_INTERNAL_QueryBuilderStore();\n const queryBuilderDispatch = useRQB_INTERNAL_QueryBuilderDispatch();\n\n const querySelector = useMemo(() => getQuerySelectorById(qbId), [qbId]);\n const storeQuery = useQueryBuilderSelector(querySelector);\n const getQuery = useCallback(\n () => querySelector(queryBuilderStore.getState()),\n [queryBuilderStore, querySelector]\n );\n\n const fallbackQuery = useMemo(() => createRuleGroup(), [createRuleGroup]);\n\n // We assume here that if the query has an `id` property, the query has already\n // been prepared. If `candidateQuery === query`, the user is probably just\n // passing back the parameter from the `onQueryChange` callback.\n const candidateQuery = queryProp ?? storeQuery ?? defaultQueryProp ?? fallbackQuery;\n const rootGroup = (\n candidateQuery.id ? candidateQuery : prepareRuleGroup(candidateQuery, { idGenerator })\n ) as RuleGroupTypeAny<R>;\n\n const [initialQuery] = useState(rootGroup);\n const rqbContext = useMemo(\n () => ({ ...incomingRqbContext, initialQuery }),\n [incomingRqbContext, initialQuery]\n );\n\n // If a new `query` prop is passed in that doesn't match the query in the store,\n // update the store to match the prop _without_ calling `onQueryChange`.\n useEffect(() => {\n if (!!queryProp && !Object.is(queryProp, storeQuery)) {\n queryBuilderDispatch(\n _RQB_INTERNAL_dispatchThunk({\n payload: { qbId, query: queryProp },\n onQueryChange: undefined,\n })\n );\n }\n }, [queryProp, qbId, storeQuery, queryBuilderDispatch]);\n\n const independentCombinators = useMemo(() => isRuleGroupTypeIC(rootGroup), [rootGroup]);\n const invalidIC = !!props.independentCombinators && !independentCombinators;\n useDeprecatedProps(\n 'independentCombinators',\n invalidIC || (!invalidIC && (props.independentCombinators ?? 'not present') !== 'not present'),\n invalidIC ? 'invalid' : 'unnecessary'\n );\n\n const hasRunMountQueryChange = useRef(false);\n useEffect(() => {\n if (hasRunMountQueryChange.current) return;\n hasRunMountQueryChange.current = true;\n queryBuilderDispatch(\n _RQB_INTERNAL_dispatchThunk({\n payload: { qbId, query: rootGroup },\n onQueryChange:\n // Leave `onQueryChange` undefined if `enableMountQueryChange` is disabled\n enableMountQueryChange && typeof onQueryChange === 'function' ? onQueryChange : undefined,\n })\n );\n }, [enableMountQueryChange, onQueryChange, qbId, queryBuilderDispatch, rootGroup]);\n\n /**\n * Updates the redux-based query, then calls `onQueryChange` with the updated\n * query object. NOTE: `useCallback` is only effective here when the user's\n * `onQueryChange` handler is undefined or has a stable reference, which usually\n * means that it's wrapped in its own `useCallback`.\n */\n const dispatchQuery = useCallback(\n (newQuery: RuleGroupTypeAny) => {\n queryBuilderDispatch(\n _RQB_INTERNAL_dispatchThunk({ payload: { qbId, query: newQuery }, onQueryChange })\n );\n },\n [onQueryChange, qbId, queryBuilderDispatch]\n );\n // #endregion\n\n // #region Query update methods\n const disabledPaths = (Array.isArray(disabled) && disabled) || defaultDisabledPaths;\n const queryDisabled = disabled === true;\n const rootGroupDisabled = rootGroup.disabled || disabledPaths.some(p => p.length === 0);\n\n const onRuleAdd = useCallback(\n // oxlint-disable-next-line typescript/no-explicit-any\n (rule: R, parentPath: Path, context?: any) => {\n const queryLocal = getQuerySelectorById(qbId)(queryBuilderStore.getState()) as RG;\n // istanbul ignore if\n if (!queryLocal) return;\n if (pathIsDisabled(parentPath, queryLocal) || queryDisabled) {\n log({ qbId, type: LogType.parentPathDisabled, rule, parentPath, query: queryLocal });\n return;\n }\n // @ts-expect-error `queryLocal` is type `RuleGroupTypeAny`, but it doesn't matter here\n const nextRule = onAddRule(rule, parentPath, queryLocal, context);\n if (!nextRule) {\n log({ qbId, type: LogType.onAddRuleFalse, rule, parentPath, query: queryLocal });\n return;\n }\n const newRule = nextRule === true ? rule : nextRule;\n const newQuery = add(queryLocal, newRule, parentPath, {\n combinators,\n combinatorPreceding: newRule.combinatorPreceding ?? undefined,\n idGenerator,\n });\n log({ qbId, type: LogType.add, query: queryLocal, newQuery, newRule, parentPath });\n dispatchQuery(newQuery);\n },\n [\n combinators,\n dispatchQuery,\n idGenerator,\n log,\n onAddRule,\n qbId,\n queryBuilderStore,\n queryDisabled,\n ]\n );\n\n const onGroupAdd = useCallback(\n // oxlint-disable-next-line typescript/no-explicit-any\n (ruleGroup: RG, parentPath: Path, context?: any) => {\n if (parentPath.length >= maxLevels) return;\n const queryLocal = getQuerySelectorById(qbId)(queryBuilderStore.getState()) as RG;\n // istanbul ignore if\n if (!queryLocal) return;\n if (pathIsDisabled(parentPath, queryLocal) || queryDisabled) {\n log({\n qbId,\n type: LogType.parentPathDisabled,\n ruleGroup,\n parentPath,\n query: queryLocal,\n });\n return;\n }\n // @ts-expect-error `queryLocal` is type `RuleGroupTypeAny`, but it doesn't matter here\n const nextGroup = onAddGroup(ruleGroup, parentPath, queryLocal, context);\n if (!nextGroup) {\n log({ qbId, type: LogType.onAddGroupFalse, ruleGroup, parentPath, query: queryLocal });\n return;\n }\n const newGroup = nextGroup === true ? ruleGroup : nextGroup;\n const newQuery = add(queryLocal, newGroup, parentPath, {\n combinators,\n combinatorPreceding: (newGroup as RuleGroupTypeIC).combinatorPreceding ?? undefined,\n idGenerator,\n });\n log({ qbId, type: LogType.add, query: queryLocal, newQuery, newGroup, parentPath });\n dispatchQuery(newQuery);\n },\n [\n combinators,\n dispatchQuery,\n idGenerator,\n log,\n maxLevels,\n onAddGroup,\n qbId,\n queryBuilderStore,\n queryDisabled,\n ]\n );\n\n const onPropChange = useCallback(\n // oxlint-disable-next-line typescript/no-explicit-any\n (prop: UpdateableProperties, value: any, path: Path) => {\n const queryLocal = getQuerySelectorById(qbId)(queryBuilderStore.getState());\n // istanbul ignore if\n if (!queryLocal) return;\n if ((pathIsDisabled(path, queryLocal) && prop !== 'disabled') || queryDisabled) {\n log({ qbId, type: LogType.pathDisabled, path, prop, value, query: queryLocal });\n return;\n }\n\n const newQuery = update(queryLocal, prop, value, path, {\n resetOnFieldChange,\n resetOnOperatorChange,\n getRuleDefaultOperator: getRuleDefaultOperator as (field: string) => string,\n getValueSources: getValueSourcesMain as (\n field: string,\n operator: string\n ) => ValueSourceFullOptions,\n getRuleDefaultValue,\n getMatchModes: getMatchModesMain as (field: string) => MatchModeOptions,\n });\n log({ qbId, type: LogType.update, query: queryLocal, newQuery, prop, value, path });\n dispatchQuery(newQuery);\n },\n [\n dispatchQuery,\n getMatchModesMain,\n getRuleDefaultOperator,\n getRuleDefaultValue,\n getValueSourcesMain,\n log,\n qbId,\n queryBuilderStore,\n queryDisabled,\n resetOnFieldChange,\n resetOnOperatorChange,\n ]\n );\n\n const onRuleOrGroupRemove = useCallback(\n // oxlint-disable-next-line typescript/no-explicit-any\n (path: Path, context?: any) => {\n const queryLocal = getQuerySelectorById(qbId)(queryBuilderStore.getState()) as RG;\n // istanbul ignore if\n if (!queryLocal) return;\n if (pathIsDisabled(path, queryLocal) || queryDisabled) {\n log({ qbId, type: LogType.pathDisabled, path, query: queryLocal });\n return;\n }\n const ruleOrGroup = findPath(path, queryLocal) as RG | R;\n // istanbul ignore else\n if (ruleOrGroup) {\n // @ts-expect-error `ruleOrGroup` and `queryLocal` are type `RuleGroupTypeAny`,\n // but it doesn't matter here\n if (onRemove(ruleOrGroup, path, queryLocal, context)) {\n const newQuery = remove(queryLocal, path);\n log({ qbId, type: LogType.remove, query: queryLocal, newQuery, path, ruleOrGroup });\n dispatchQuery(newQuery);\n } else {\n log({ qbId, type: LogType.onRemoveFalse, ruleOrGroup, path, query: queryLocal });\n }\n }\n },\n [dispatchQuery, log, onRemove, qbId, queryBuilderStore, queryDisabled]\n );\n\n const moveRule = useCallback(\n // oxlint-disable-next-line typescript/no-explicit-any\n (oldPath: Path, newPath: Path | 'up' | 'down', clone?: boolean, context?: any) => {\n const queryLocal = getQuerySelectorById(qbId)(queryBuilderStore.getState()) as RG;\n // istanbul ignore if\n if (!queryLocal) return;\n if (pathIsDisabled(oldPath, queryLocal) || queryDisabled) {\n log({ qbId, type: LogType.pathDisabled, oldPath, newPath, query: queryLocal });\n return;\n }\n const nextQuery = move(queryLocal, oldPath, newPath, { clone, combinators, idGenerator });\n const ruleOrGroup = findPath(oldPath, queryLocal)!;\n const isGroup = isRuleGroup(ruleOrGroup);\n const callbackResult = (\n (isGroup ? onMoveGroup : onMoveRule) as (...args: unknown[]) => RG | boolean\n )(ruleOrGroup, oldPath, newPath, queryLocal, nextQuery, { clone, combinators }, context);\n if (!callbackResult) {\n log({\n qbId,\n type: isGroup ? LogType.onMoveGroupFalse : LogType.onMoveRuleFalse,\n ruleOrGroup,\n oldPath,\n newPath,\n clone,\n query: queryLocal,\n nextQuery,\n });\n return;\n }\n const newQuery = isRuleGroup(callbackResult) ? callbackResult : nextQuery;\n log({ qbId, type: LogType.move, query: queryLocal, newQuery, oldPath, newPath, clone });\n dispatchQuery(newQuery);\n },\n [\n combinators,\n dispatchQuery,\n idGenerator,\n log,\n onMoveGroup,\n onMoveRule,\n qbId,\n queryBuilderStore,\n queryDisabled,\n ]\n );\n\n const groupRule = useCallback(\n // oxlint-disable-next-line typescript/no-explicit-any\n (sourcePath: Path, targetPath: Path, clone?: boolean, context?: any) => {\n const queryLocal = getQuerySelectorById(qbId)(queryBuilderStore.getState()) as RG;\n // istanbul ignore if\n if (!queryLocal) return;\n if (pathIsDisabled(sourcePath, queryLocal) || queryDisabled) {\n log({ qbId, type: LogType.pathDisabled, sourcePath, targetPath, query: queryLocal });\n return;\n }\n const nextQuery = group(queryLocal, sourcePath, targetPath, {\n clone,\n combinators,\n idGenerator,\n });\n const ruleOrGroup = findPath(sourcePath, queryLocal)!;\n const isGroup = isRuleGroup(ruleOrGroup);\n