Skip to content

Commit

Permalink
[TreeView] Support itemId with escaping characters when using `Simp…
Browse files Browse the repository at this point in the history
…leTreeView` (#13487)

Signed-off-by: Flavien DELANGLE <flaviendelangle@gmail.com>
Co-authored-by: Flavien DELANGLE <flaviendelangle@gmail.com>
  • Loading branch information
oukunan and flaviendelangle authored Jun 19, 2024
1 parent ac94b4a commit 3c6ce8e
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
12 changes: 12 additions & 0 deletions packages/x-tree-view/src/TreeItem/TreeItem.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ describeTreeView<[]>('TreeItem component', ({ render, treeItemComponentName }) =

expect(response.getItemContent('1').textContent).to.equal('ABCDEF');
});

it('should render TreeItem when itemId prop is escaping characters without throwing an error', function test() {
if (treeItemComponentName === 'TreeItem2') {
this.skip();
}

const response = render({
items: [{ id: 'C:\\\\', label: 'ABCDEF' }],
});

expect(response.getItemContent('C:\\\\').textContent).to.equal('ABCDEF');
});
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { useTreeViewContext } from './useTreeViewContext';
import { escapeOperandAttributeSelector } from '../utils/utils';
import type { UseTreeViewJSXItemsSignature } from '../plugins/useTreeViewJSXItems';
import type { UseTreeViewItemsSignature } from '../plugins/useTreeViewItems';
import type { UseTreeViewIdSignature } from '../plugins/useTreeViewId';
Expand Down Expand Up @@ -47,8 +48,9 @@ export function TreeViewChildrenItemProvider(props: TreeViewChildrenItemProvider
}

const previousChildrenIds = instance.getItemOrderedChildrenIds(itemId ?? null) ?? [];
const escapedIdAttr = escapeOperandAttributeSelector(idAttr);
const childrenElements = rootRef.current.querySelectorAll(
`${itemId == null ? '' : `*[id="${idAttr}"] `}[role="treeitem"]:not(*[id="${idAttr}"] [role="treeitem"] [role="treeitem"])`,
`${itemId == null ? '' : `*[id="${escapedIdAttr}"] `}[role="treeitem"]:not(*[id="${escapedIdAttr}"] [role="treeitem"] [role="treeitem"])`,
);
const childrenIds = Array.from(childrenElements).map(
(child) => childrenIdAttrToIdRef.current.get(child.id)!,
Expand Down
6 changes: 6 additions & 0 deletions packages/x-tree-view/src/internals/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ export const getActiveElement = (root: Document | ShadowRoot = document): Elemen

return activeEl;
};

// TODO, eventually replaces this function with CSS.escape, once available in jsdom, either added manually or built in
// https://github.com/jsdom/jsdom/issues/1550#issuecomment-236734471
export function escapeOperandAttributeSelector(operand: string): string {
return operand.replace(/["\\]/g, '\\$&');
}

0 comments on commit 3c6ce8e

Please sign in to comment.