Skip to content

Commit

Permalink
Refactor useTagList and renderTagList to accept any list element attr…
Browse files Browse the repository at this point in the history
…ibutes
  • Loading branch information
i-like-robots committed Jun 16, 2024
1 parent a72e6be commit fb198ee
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 43 deletions.
10 changes: 5 additions & 5 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,14 +380,14 @@ function CustomRoot({ children, classNames, isActive, isDisabled, isInvalid, ...

#### renderTagList (optional)

A custom tag list component to render. Receives the list object, required tag list element attributes, and [`classNames`](#classNames-optional) as props. Defaults to `null`.
A custom selected tag list component to render. Receives the selected tags as children, required tag list element attributes, and [`classNames`](#classNames-optional) as props. Defaults to `null`.

```jsx
function CustomTagList({ children, label, classNames, listRef }) {
function CustomTagList({ children, classNames, ...tagListprops }) {
return (
<ul className={classNames.tagList} aria-label={label} ref={listRef} role="list">
{children.map((child) => (
<li className={classNames.tagListItem} key={child.key} role="listitem">
<ul className={classNames.tagList} {...tagListprops}>
{React.Children.map(children, (child) => (
<li className={classNames.tagListItem} key={child.key}>
{child}
</li>
))}
Expand Down
28 changes: 14 additions & 14 deletions src/components/TagList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,28 @@ import { GlobalContext } from '../contexts'
import type { TagProps } from './'
import type { ClassNames } from '../sharedTypes'

type TagListRendererProps = React.ComponentPropsWithoutRef<'ul'> & {
children: React.ReactElement<TagProps>[]
type TagListRendererProps = React.ComponentPropsWithRef<'ul'> & {
classNames: ClassNames
label: string
listRef: React.MutableRefObject<HTMLUListElement>
}

export type TagListRenderer = (props: TagListRendererProps) => JSX.Element

const DefaultTagList: TagListRenderer = ({
children,
label,
classNames,
listRef,
...tagListProps
}: TagListRendererProps) => {
return (
<ul className={classNames.tagList} aria-label={label} ref={listRef} role="list">
{children.map((child) => (
<li className={classNames.tagListItem} key={child.key} role="listitem">
{child}
</li>
))}
<ul className={classNames.tagList} {...tagListProps} role="list">
{React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
return (
<li className={classNames.tagListItem} key={child.key} role="listitem">
{child}
</li>
)
}
})}
</ul>
)
}
Expand All @@ -38,7 +38,7 @@ export type TagListProps = {

export function TagList({ children, label, render = DefaultTagList }: TagListProps): JSX.Element {
const { classNames } = useContext(GlobalContext)
const { listRef } = useTagList()
const tagListProps = useTagList({ label })

return render({ classNames, children, label, listRef })
return render({ classNames, children, ...tagListProps })
}
12 changes: 6 additions & 6 deletions src/hooks/useTagList.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { useContext, useLayoutEffect, useRef } from 'react'
import { GlobalContext } from '../contexts'

// export type UseTagListArgs = {}

export type UseTagListState = {
listRef: React.MutableRefObject<HTMLUListElement>
export type UseTagListArgs = {
label: string
}

export function useTagList(): UseTagListState {
export type UseTagListState = React.ComponentPropsWithRef<'ul'>

export function useTagList({ label }: UseTagListArgs): UseTagListState {
const { rootRef, managerRef } = useContext(GlobalContext)

const listRef = useRef<HTMLUListElement>()
Expand All @@ -25,5 +25,5 @@ export function useTagList(): UseTagListState {
}
}, [isFocusInList, listRef, rootRef, tagDeleted])

return { listRef }
return { ref: listRef, 'aria-label': label }
}
29 changes: 11 additions & 18 deletions src/test/ReactTags.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -925,24 +925,17 @@ describe('React Tags Autocomplete', () => {
})

it('renders a custom tag list component when provided', () => {
const renderer: Harness['props']['renderTagList'] = ({
children,
label,
classNames,
listRef,
}) => (
<ul
id={'custom-tag-list'}
className={classNames.tagList}
aria-label={label}
ref={listRef}
role="list"
>
{children.map((child) => (
<li className={classNames.tagListItem} key={child.key} role="listitem">
{child}
</li>
))}
const renderer: Harness['props']['renderTagList'] = ({ children, classNames, ...props }) => (
<ul id="custom-tag-list" className={classNames.tagList} {...props}>
{React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
return (
<li className={classNames.tagListItem} key={child.key}>
{child}
</li>
)
}
})}
</ul>
)

Expand Down

0 comments on commit fb198ee

Please sign in to comment.