Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 17 additions & 21 deletions packages/react-core/src/components/Toolbar/ToolbarFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ interface ToolbarFilterState {
isMounted: boolean;
}

const getCategoryKey = (categoryName: string | ToolbarLabelGroup): string => {
if (typeof categoryName === 'string') {
return categoryName;
}
return categoryName.key;
};

class ToolbarFilter extends Component<ToolbarFilterProps, ToolbarFilterState> {
static displayName = 'ToolbarFilter';
static contextType = ToolbarContext;
Expand All @@ -63,24 +70,16 @@ class ToolbarFilter extends Component<ToolbarFilterProps, ToolbarFilterState> {
}

componentDidMount() {
const { categoryName, labels } = this.props;
this.context.updateNumberFilters(
typeof categoryName !== 'string' && categoryName.hasOwnProperty('key')
? categoryName.key
: categoryName.toString(),
labels.length
);
this.context.updateNumberFilters(getCategoryKey(this.props.categoryName), this.props.labels.length);
this.setState({ isMounted: true });
}

componentDidUpdate() {
const { categoryName, labels } = this.props;
this.context.updateNumberFilters(
typeof categoryName !== 'string' && categoryName.hasOwnProperty('key')
? categoryName.key
: categoryName.toString(),
labels.length
);
this.context.updateNumberFilters(getCategoryKey(this.props.categoryName), this.props.labels.length);
}
Comment on lines 77 to +79
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Clear previous category count when categoryName changes

If categoryName changes without unmounting, the old key can stay populated in filterInfo, leaving stale state. Handle prevProps.categoryName and clear the previous key before updating the new one.

Suggested fix
-  componentDidUpdate() {
-    this.context.updateNumberFilters(getCategoryKey(this.props.categoryName), this.props.labels.length);
-  }
+  componentDidUpdate(prevProps: ToolbarFilterProps) {
+    const prevCategoryKey = getCategoryKey(prevProps.categoryName);
+    const nextCategoryKey = getCategoryKey(this.props.categoryName);
+
+    if (prevCategoryKey !== nextCategoryKey) {
+      this.context.updateNumberFilters(prevCategoryKey, 0);
+    }
+
+    this.context.updateNumberFilters(nextCategoryKey, this.props.labels.length);
+  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-core/src/components/Toolbar/ToolbarFilter.tsx` around lines 77
- 79, When categoryName changes we need to clear the old key before setting the
new count: update componentDidUpdate to accept prevProps, compare
prevProps.categoryName to this.props.categoryName, and if different call
this.context.updateNumberFilters(getCategoryKey(prevProps.categoryName), 0) to
clear the previous entry, then call
this.context.updateNumberFilters(getCategoryKey(this.props.categoryName),
this.props.labels.length) to set the new count; reference componentDidUpdate,
this.context.updateNumberFilters, getCategoryKey, this.props.categoryName,
prevProps.categoryName and this.props.labels.length.


componentWillUnmount() {
this.context.updateNumberFilters(getCategoryKey(this.props.categoryName), 0);
}

render() {
Expand All @@ -99,10 +98,7 @@ class ToolbarFilter extends Component<ToolbarFilterProps, ToolbarFilterState> {
} = this.props;
const { isExpanded: managedIsExpanded, labelGroupContentRef } = this.context;
const _isExpanded = isExpanded !== undefined ? isExpanded : managedIsExpanded;
const categoryKey =
typeof categoryName !== 'string' && categoryName.hasOwnProperty('key')
? categoryName.key
: categoryName.toString();
const categoryKey = getCategoryKey(categoryName);

const labelGroup = labels.length ? (
<ToolbarItem variant="label-group">
Expand All @@ -116,11 +112,11 @@ class ToolbarFilter extends Component<ToolbarFilterProps, ToolbarFilterState> {
>
{labels.map((label) =>
typeof label === 'string' ? (
<Label variant="outline" key={label} onClose={() => deleteLabel(categoryKey, label)}>
<Label variant="outline" key={label} onClose={() => deleteLabel?.(categoryKey, label)}>
{label}
</Label>
) : (
<Label key={label.key} onClose={() => deleteLabel(categoryKey, label)}>
<Label key={label.key} onClose={() => deleteLabel?.(categoryKey, label)}>
{label.node}
</Label>
Comment on lines 113 to 121
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Avoid no-op close affordance when deleteLabel is undefined

onClose is always passed, so labels can appear removable even when no delete handler exists; clicks then do nothing. Pass onClose only when deleteLabel is provided.

Suggested fix
-              <Label variant="outline" key={label} onClose={() => deleteLabel?.(categoryKey, label)}>
+              <Label
+                variant="outline"
+                key={label}
+                onClose={deleteLabel ? () => deleteLabel(categoryKey, label) : undefined}
+              >
                 {label}
               </Label>
             ) : (
-              <Label key={label.key} onClose={() => deleteLabel?.(categoryKey, label)}>
+              <Label
+                key={label.key}
+                onClose={deleteLabel ? () => deleteLabel(categoryKey, label) : undefined}
+              >
                 {label.node}
               </Label>
             )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-core/src/components/Toolbar/ToolbarFilter.tsx` around lines
113 - 121, The Label components are always receiving an onClose prop, causing a
clickable close affordance even when deleteLabel is undefined; update the
labels.map rendering in ToolbarFilter.tsx to only pass the onClose prop when
deleteLabel is truthy (e.g., conditionally include onClose={() =>
deleteLabel(categoryKey, label)} for the string branch and onClose={() =>
deleteLabel(categoryKey, label)} for the object branch), leaving Label without
onClose when deleteLabel is not provided so the close affordance is not shown.

)
Expand All @@ -133,7 +129,7 @@ class ToolbarFilter extends Component<ToolbarFilterProps, ToolbarFilterState> {
return (
<Fragment>
{showToolbarItem && <ToolbarItem {...props}>{children}</ToolbarItem>}
{labelGroupContentRef?.current?.firstElementChild !== null &&
{labelGroupContentRef?.current?.firstElementChild &&
ReactDOM.createPortal(labelGroup, labelGroupContentRef.current.firstElementChild)}
</Fragment>
);
Expand Down
Loading