-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add contained-list component (#11969)
* feat(contained-list): scaffold new component * feat(contained-list-item): scaffold new component * feat(contained-list-item): add support for clickable items * feat(contained-list): add support for disabled list items * feat(contained-list): add support for actions in header and item * docs(contained-list): build stories * feat(contained-list-item): add support for icons * test(contained-list): add tests * refactor(contained-list): rename variants * docs(contained-list): change "Heading" to "List title" * fix(contained-list-item): add extra padding when action is pased * docs(contained-list): change "Heading" to "List title" Co-authored-by: Lauren Rice <43969356+laurenmrice@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
- Loading branch information
1 parent
2cb3054
commit e346d01
Showing
12 changed files
with
900 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
packages/react/src/components/ContainedList/ContainedList.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/** | ||
* Copyright IBM Corp. 2022 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import classNames from 'classnames'; | ||
import { useId } from '../../internal/useId'; | ||
import { usePrefix } from '../../internal/usePrefix'; | ||
|
||
const variants = ['on-page', 'disclosed']; | ||
|
||
function ContainedList({ | ||
action, | ||
children, | ||
className, | ||
kind = variants[0], | ||
label, | ||
}) { | ||
const labelId = `${useId('contained-list')}-header`; | ||
const prefix = usePrefix(); | ||
|
||
const classes = classNames( | ||
`${prefix}--contained-list`, | ||
`${prefix}--contained-list--${kind}`, | ||
className | ||
); | ||
|
||
return ( | ||
<div className={classes}> | ||
<div className={`${prefix}--contained-list__header`}> | ||
<div id={labelId} className={`${prefix}--contained-list__label`}> | ||
{label} | ||
</div> | ||
{action && ( | ||
<div className={`${prefix}--contained-list__action`}>{action}</div> | ||
)} | ||
</div> | ||
<ul aria-labelledby={labelId}>{children}</ul> | ||
</div> | ||
); | ||
} | ||
|
||
ContainedList.propTypes = { | ||
/** | ||
* A slot for a possible interactive element to render. | ||
*/ | ||
action: PropTypes.node, | ||
|
||
/** | ||
* A collection of ContainedListItems to be rendered in the ContainedList | ||
*/ | ||
children: PropTypes.node, | ||
|
||
/** | ||
* Additional CSS class names. | ||
*/ | ||
className: PropTypes.string, | ||
|
||
/** | ||
* The kind of ContainedList you want to display | ||
*/ | ||
kind: PropTypes.oneOf(variants), | ||
|
||
/** | ||
* A label describing the contained list. | ||
*/ | ||
label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired, | ||
}; | ||
|
||
export default ContainedList; |
96 changes: 96 additions & 0 deletions
96
packages/react/src/components/ContainedList/ContainedListItem/ContainedListItem.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/** | ||
* Copyright IBM Corp. 2022 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import classNames from 'classnames'; | ||
import { usePrefix } from '../../../internal/usePrefix'; | ||
|
||
function ContainedListItem({ | ||
action, | ||
children, | ||
className, | ||
disabled = false, | ||
onClick, | ||
renderIcon: IconElement, | ||
}) { | ||
const prefix = usePrefix(); | ||
|
||
const isClickable = onClick !== undefined; | ||
|
||
const classes = classNames(`${prefix}--contained-list-item`, className, { | ||
[`${prefix}--contained-list-item--clickable`]: isClickable, | ||
[`${prefix}--contained-list-item--with-icon`]: IconElement, | ||
[`${prefix}--contained-list-item--with-action`]: action, | ||
}); | ||
|
||
const content = ( | ||
<> | ||
{IconElement && ( | ||
<div className={`${prefix}--contained-list-item__icon`}> | ||
<IconElement /> | ||
</div> | ||
)} | ||
<div>{children}</div> | ||
</> | ||
); | ||
|
||
return ( | ||
<li className={classes}> | ||
{isClickable ? ( | ||
<button | ||
className={`${prefix}--contained-list-item__content`} | ||
type="button" | ||
disabled={disabled} | ||
onClick={onClick}> | ||
{content} | ||
</button> | ||
) : ( | ||
<div className={`${prefix}--contained-list-item__content`}> | ||
{content} | ||
</div> | ||
)} | ||
{action && ( | ||
<div className={`${prefix}--contained-list-item__action`}>{action}</div> | ||
)} | ||
</li> | ||
); | ||
} | ||
|
||
ContainedListItem.propTypes = { | ||
/** | ||
* A slot for a possible interactive element to render within the item. | ||
*/ | ||
action: PropTypes.node, | ||
|
||
/** | ||
* The content of this item. Must not contain any interactive elements. Use props.action to include those. | ||
*/ | ||
children: PropTypes.node, | ||
|
||
/** | ||
* Additional CSS class names. | ||
*/ | ||
className: PropTypes.string, | ||
|
||
/** | ||
* Whether this item is disabled. | ||
*/ | ||
disabled: PropTypes.bool, | ||
|
||
/** | ||
* Provide an optional function to be called when the item is clicked. | ||
*/ | ||
onClick: PropTypes.func, | ||
|
||
/** | ||
* Provide an optional icon to render in front of the item's content. | ||
*/ | ||
renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), | ||
}; | ||
|
||
export default ContainedListItem; |
8 changes: 8 additions & 0 deletions
8
packages/react/src/components/ContainedList/ContainedListItem/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** | ||
* Copyright IBM Corp. 2022 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
export default from './ContainedListItem'; |
Oops, something went wrong.