ScopeMatrix
scope-matrixEdits allow and deny scope lists with suggestions, an effective-scope summary, and read-only or controlled modes.
Usage
Task scope configuration
Two semantically opposed buckets. The summary at the bottom will write down the "final effective range" in human terms - the most common mistakes in this type of configuration are the blank list and priority.
Leave empty to disable the allowlist; only deny rules will apply.
src/**
Matches are denied and take priority over allow rules.
**/node_modules/**
Deny rules are evaluated first (1 under “Deny”); unmatched patterns must then match one of 1 under “Allow”.
<ScopeMatrix
allow={scope.allow}
deny={scope.deny}
onChange={setScope}
suggestions={derivedFromProject}
/>With syntax check
The component does not have built-in pattern syntax checking - glob / Regular / ant The style is very different, and guessing wrong is worse than not guessing at all. If needed, please send validate.
Leave empty to disable the allowlist; only deny rules will apply.
- Not set (allowlist disabled)
Matches are denied and take priority over allow rules.
- Not set
No scope restrictions are currently set.
<ScopeMatrix
allow={allow}
deny={deny}
onChange={onChange}
validate={(p) => (p.startsWith("/") ? "Please use relative mode, not absolute path" : null)}
/>Read-only review
If onChange is not given, it is read-only and is used for audit view or historical configuration review.
Leave empty to disable the allowlist; only deny rules will apply.
packages/ui/**docs/**
Matches are denied and take priority over allow rules.
**/dist/****/node_modules/**
Deny rules are evaluated first (2 under “Deny”); unmatched patterns must then match one of 2 under “Allow”.
<ScopeMatrix allow={record.allow} deny={record.deny} />When to use
Use ScopeMatrix when users must define an effective scope from opposing allow and deny patterns, such as:
- Permission or allowlist configuration.
- Paths a task or operation may change.
- Route guards, file-sync scopes, or CI trigger paths.
When not to use
| Scenario | Use instead | Why |
|---|---|---|
| Moving items from a fixed candidate pool | Transfer | Candidates form a closed set; users select but cannot create them. |
| Free entry of one-dimensional labels | TagInput | The values do not have opposing allow/deny semantics. |
Example
import { ScopeMatrix } from "@hulianui/ui";
const [scope, setScope] = useState({ allow: ["src/**"], deny: ["**/dist/**"] });
<ScopeMatrix
allow={scope.allow}
deny={scope.deny}
onChange={setScope}
suggestions={derivedFromProject}
/>Props
| Name | Type | Default | Description |
|---|---|---|---|
allow | string[] | — | Allow patterns; an empty array disables allowlisting. |
deny | string[] | — | Deny patterns. |
onChange | (next: { allow, deny }) => void | — | Called with both buckets; omitting it makes the component read-only. |
suggestions | string[] | [] | Suggested patterns that populate the input when clicked. |
readOnly | boolean | false | Forces read-only mode. |
validate | (pattern) => string | null | — | Returns an error message for an invalid pattern, or null. |
allowLabel / denyLabel | ReactNode | "\u5141\u8bb8" / "\u7981\u6b62" | Bucket headings; the built-in Chinese copy means “Allow” and “Deny.” |
allowHint / denyHint | ReactNode | See defaults | Guidance shown below each bucket. |
placeholder | string | "\u8f93\u5165\u6a21\u5f0f\u540e\u56de\u8f66" | Input placeholder; the built-in Chinese copy means “Enter a pattern, then press Enter.” |
Usage guidelines
The summary is the component's central feature. Two allow/deny lists are easy to build, but their combined behavior is easy to misunderstand:
- Deny takes precedence over allow. A pattern matching both buckets is denied.
- An empty allow list does not deny everything. It disables allowlisting, leaving only the deny list in effect.
Misrepresenting the second rule can make a valid configuration appear to block everything. The component therefore states the current effective behavior in plain language instead of relying on external documentation.
Pattern syntax is not built in. Glob, regular-expression, Ant-style, and custom DSL rules differ too much for the component to guess. Pass validate when syntax validation is required.
Clicking a suggestion only fills the input; it does not submit it. Suggested patterns often need adjustment before addition, such as changing depth or adding a suffix.
Playground
Leave empty to disable the allowlist; only deny rules will apply.
src/**
Matches are denied and take priority over allow rules.
**/node_modules/**
Deny rules are evaluated first (1 under “Deny”); unmatched patterns must then match one of 1 under “Allow”.
<ScopeMatrix
allow={scope.allow}
deny={scope.deny}
onChange={setScope}
suggestions={derivedFromProject}
/>