Skip to content

Commit

Permalink
feat(TagList): support icons (#2796)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Lienard authored Aug 8, 2023
1 parent d7d3936 commit 32e9211
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-cobras-train.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ultraviolet/ui': patch
---

Support icons in TagList
13 changes: 13 additions & 0 deletions packages/ui/src/components/TagList/__stories__/Icons.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Template } from './Template.stories'

export const Icons = Template.bind({})

Icons.args = {
tags: [
{ label: 'smooth', icon: 'id' },
'code',
{ label: 'hello', icon: 'lock' },
{ label: 'world', icon: 'plus' },
],
threshold: 3,
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ export { Playground } from './Playground.stories'
export { Threshold } from './Threshold.stories'
export { Multiline } from './Multiline.stories'
export { Copiable } from './Copiable.stories'
export { Icons } from './Icons.stories'
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,124 @@ exports[`TagList renders correctly with custom threshold and extra tags and maxL
</DocumentFragment>
`;

exports[`TagList renders correctly with icons 1`] = `
<DocumentFragment>
.cache-a1981g-StyledContainer {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.cache-1alpvce-StyledTagContainer {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
color: #3f4250;
gap: 8px;
}
.cache-yb56yg-StyledChildrenContainer {
display: inherit;
}
.cache-1ykqsf4-Container-StyledContainer {
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
white-space: nowrap;
border-radius: 4px;
padding: 0 8px;
gap: 8px;
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content;
height: 24px;
color: #3f4250;
background: #ffffff;
border: solid 1px #d9dadd;
}
.cache-1ykqsf4-Container-StyledContainer:hover,
.cache-1ykqsf4-Container-StyledContainer:active {
cursor: pointer;
background: #e9eaeb;
border-color: #92959d;
}
.cache-1ykqsf4-Container-StyledContainer:active {
box-shadow: 0px 0px 0px 3px #151A2D5C;
}
.cache-t6vuyb-StyledTag {
font-size: 12px;
font-weight: 500;
color: inherit;
max-width: 232px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
<div>
<div
class="cache-a1981g-StyledContainer eb6op482"
>
<div
class="cache-1alpvce-StyledTagContainer eb6op480"
>
<div
aria-describedby=":r6:"
class="cache-yb56yg-StyledChildrenContainer efkq4700"
tabindex="0"
>
<button
class="cache-1ykqsf4-Container-StyledContainer el6733p3"
>
<span
aria-disabled="false"
class="cache-t6vuyb-StyledTag el6733p1"
>
scaleway
</span>
</button>
</div>
<div
aria-describedby=":r7:"
class="cache-yb56yg-StyledChildrenContainer efkq4700"
tabindex="0"
>
<button
class="cache-1ykqsf4-Container-StyledContainer el6733p3"
>
<span
aria-disabled="false"
class="cache-t6vuyb-StyledTag el6733p1"
>
cloud
</span>
</button>
</div>
</div>
</div>
</div>
</DocumentFragment>
`;

exports[`TagList renders correctly with multiline 1`] = `
<DocumentFragment>
.cache-a1981g-StyledContainer {
Expand Down
19 changes: 18 additions & 1 deletion packages/ui/src/components/TagList/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,29 @@ describe('TagList', () => {
</div>,
))

test('renders correctly with icons', () =>
shouldMatchEmotionSnapshot(
<div>
<TagList
popoverTitle="Additional"
copiable
threshold={4}
tags={['scaleway', 'cloud']}
/>
</div>,
))

test('renders correctly when clicking on popover', async () => {
renderWithTheme(
<TagList
popoverTitle="Additional"
threshold={1}
tags={['scaleway', 'cloud']}
tags={[
{ label: 'smooth', icon: 'id' },
'code',
{ label: 'hello', icon: 'lock' },
{ label: 'world', icon: 'plus' },
]}
/>,
)

Expand Down
27 changes: 19 additions & 8 deletions packages/ui/src/components/TagList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ type TagListProps = {
* This property define maximum characters length of all tags until it hide tags into tooltip.
*/
maxLength?: number
tags?: string[]
tags?: (
| string
| { label: string; icon: NonNullable<ComponentProps<typeof Tag>['icon']> }
)[]
/**
* This property define maximum characters length of all tags until it hide tags into tooltip.
*/
Expand All @@ -55,6 +58,9 @@ type TagListProps = {

const DEFAULT_TAGS: TagListProps['tags'] = []

const getTagLabel = (tag: NonNullable<TagListProps['tags']>[number]) =>
typeof tag === 'object' ? tag.label : tag

export const TagList = ({
maxLength = 600,
tags = DEFAULT_TAGS,
Expand All @@ -70,7 +76,10 @@ export const TagList = ({
let tmpThreshold = threshold
if (
tags.length > 0 &&
tags.slice(0, tmpThreshold).reduce((_, tag) => _ + tag).length > maxLength
tags
.slice(0, tmpThreshold)
.reduce<string>((acc, tag) => acc + getTagLabel(tag), '').length >
maxLength
) {
// If total tags length in characters is above maxLength,
// threshold is decremented in order to prevent too many long tags displayed.
Expand All @@ -92,16 +101,17 @@ export const TagList = ({
<Tag
// useful when two tags are identical `${tag}-${index}`
// eslint-disable-next-line react/no-array-index-key
key={`${tag}-${index}`}
key={`${getTagLabel(tag)}-${index}`}
copiable={copiable}
copyText={copyText}
copiedText={copiedText}
icon={typeof tag === 'object' ? tag.icon : undefined}
>
{tag}
{getTagLabel(tag)}
</Tag>
))}
</StyledTagContainer>
{hasManyTags && (
{hasManyTags ? (
<Popover
title={popoverTitle}
visible={isVisible}
Expand All @@ -113,12 +123,13 @@ export const TagList = ({
<Tag
// useful when two tags are identical `${tag}-${index}`
// eslint-disable-next-line react/no-array-index-key
key={`${tag}-${index}`}
key={`${getTagLabel(tag)}-${index}`}
copiable={copiable}
copyText={copyText}
copiedText={copiedText}
icon={typeof tag === 'object' ? tag.icon : undefined}
>
{tag}
{getTagLabel(tag)}
</Tag>
))}
</StyledTagContainer>
Expand All @@ -131,7 +142,7 @@ export const TagList = ({
+{tags.length - tmpThreshold}
</TagsWrapper>
</Popover>
)}
) : null}
</StyledContainer>
)
}

0 comments on commit 32e9211

Please sign in to comment.