npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

conditional-selection

v1.1.8

Published

conditional-selection

Readme

conditional-selection

A lightweight React component library for building conditional rule trees. Supports recursive nesting, AND/OR grouping, dynamic add/remove, and fully customizable condition rows via render props.

Installation

npm install conditional-selection

Peer dependencies: react >= 16.8.0, react-dom >= 16.8.0

Quick Start

import { ConditionalSelection } from 'conditional-selection';
import type { TConditionalSelection } from 'conditional-selection';

export default function App() {
  const [rules, setRules] = useState<TConditionalSelection | undefined>();

  return (
    <ConditionalSelection
      conditionalRules={rules}
      maxDeep={3}
      onChange={setRules}
      renderConditionRules={(item, change) => (
        <MyConditionRow item={item} onChange={change} />
      )}
    />
  );
}

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | conditionalRules | TConditionalSelection \| null | undefined | The condition tree data. Automatically initialized if null or undefined. | | maxDeep | number | 1 | Maximum recursion depth. Must be greater than 0. | | disabled | boolean \| TConditionalSelectionDisabledProps | false | Disable all or specific operations. | | onChange | (value: TConditionalSelection \| undefined) => void | — | Callback fired when the tree data changes. | | renderConditionRules | (item, change) => ReactNode | — | Render prop for each condition row. Receives the current INDIVIDUAL node and an update handler. | | renderCreateCondition | (params) => ReactNode | — | Render prop to customize the "Add condition" button. |

disabled object shape

type TConditionalSelectionDisabledProps = {
  addItem?: boolean;    // disable adding new conditions
  delItem?: boolean;    // disable deleting conditions
  linkChange?: boolean; // disable AND/OR toggle
};

Data Structure

type TConditionalSelection<T = any> = {
  _id: string;
  framework: 'group' | 'individual';
  link?: 'and' | 'or';
  group?: TConditionalSelection<T>[];
  individual?: Record<string, any>;
  level: number;
};
  • group node — contains child nodes and an AND/OR relationship toggle.
  • individual node — a single condition row; its data lives in the individual field.

Example Output

Flat structure — two individual conditions joined by AND:

{
  "_id": "2dfd8d9d-4bbf-4bc3-aae6-6c747ccbdd10",
  "framework": "group",
  "level": 0,
  "link": "and",
  "group": [
    {
      "_id": "02399b6c-10a3-41d4-9722-cce2db9ae056",
      "framework": "individual",
      "individual": { "field": 1, "function": 1, "value": 1 },
      "level": 1
    },
    {
      "_id": "6c627903-b970-43a8-a3f5-f5aba89f2200",
      "framework": "individual",
      "individual": { "field": 1, "function": 1, "value": 1 },
      "level": 1
    }
  ]
}

Nested structure — an individual AND a nested group (OR) at level 1:

{
  "_id": "2dfd8d9d-4bbf-4bc3-aae6-6c747ccbdd10",
  "framework": "group",
  "level": 0,
  "link": "and",
  "group": [
    {
      "_id": "02399b6c-10a3-41d4-9722-cce2db9ae056",
      "framework": "individual",
      "individual": { "field": 1, "function": 1, "value": 1 },
      "level": 1
    },
    {
      "_id": "2f808fe6-4dd8-488d-9b79-d2888915fddc",
      "framework": "group",
      "level": 1,
      "link": "or",
      "group": [
        {
          "_id": "17336bf2-2885-4350-8055-233b0058ec39",
          "framework": "individual",
          "individual": { "field": 1, "function": 1, "value": 1 },
          "level": 2
        },
        {
          "_id": "6e21bd9a-f994-474a-bba5-d77ac9013a65",
          "framework": "individual",
          "individual": { "field": 1, "function": 1, "value": 1 },
          "level": 2
        }
      ]
    }
  ]
}

Accessing Data via Ref

const ref = useRef<any>(null);

<ConditionalSelection ref={ref} ... />

// Returns a deep clone of the current tree
const data = await ref.current.getConditionalSelectionData();

Custom Condition Row Example

const MyConditionRow = ({ item, onChange }) => {
  const data = item.individual ?? {};
  return (
    <div style={{ display: 'flex', gap: 8 }}>
      <select value={data.field ?? ''} onChange={e => onChange({ field: e.target.value })}>
        <option value="">Select field</option>
        <option value="name">Name</option>
      </select>
      <select value={data.operator ?? ''} onChange={e => onChange({ ...data, operator: e.target.value })}>
        <option value="">Select operator</option>
        <option value="eq">Equals</option>
        <option value="ne">Not equals</option>
      </select>
      <input
        value={data.value ?? ''}
        onChange={e => onChange({ ...data, value: e.target.value })}
        placeholder="Value"
      />
    </div>
  );
};

Performance Tips

  • Wrap handlers and render props with useCallback to avoid unnecessary re-renders.
  • Use React Profiler for deeper performance analysis.

Contributing

git clone https://github.com/1512-Yolo/conditional-selection.git
cd conditional-selection
npm install
npm run dev

Components are exported from packages/index.ts. Styles are written in Less (packages/ConditionalSelection/index.less).

License

MIT