Skip to content
Merged
Show file tree
Hide file tree
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
5 changes: 5 additions & 0 deletions .changeset/sour-lamps-kick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/components": patch
---

Correct font size and truncate for description within ActionList Items
70 changes: 45 additions & 25 deletions src/ActionList/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {CheckIcon, IconProps} from '@primer/octicons-react'
import React, {useCallback} from 'react'
import {get} from '../constants'
import sx, {SxProp} from '../sx'
import Flex from '../Flex'
import Truncate from '../Truncate'
import {ItemInput} from './List'
import styled from 'styled-components'
import {StyledHeader} from './Header'
Expand Down Expand Up @@ -152,7 +152,10 @@ const getItemVariant = (variant = 'default', disabled?: boolean) => {
}

const StyledItemContent = styled.div`
width: 100%;
display: flex;
min-width: 0;
flex-grow: 1;
position: relative;
`

const StyledItem = styled.div<
Expand Down Expand Up @@ -188,7 +191,8 @@ const StyledItem = styled.div<
${StyledItemContent}::before {
content: ' ';
display: block;
position: relative;
position: absolute;
width: 100%;
top: -7px;
// NB: This 'get' won’t execute if it’s moved into the arrow function below.
border: 0 solid ${get('colors.selectMenu.borderSecondary')};
Expand All @@ -215,7 +219,10 @@ const StyledItem = styled.div<

const StyledTextContainer = styled.div<{descriptionVariant: ItemProps['descriptionVariant']}>`
display: flex;
min-width: 0;
flex-grow: 1;
flex-direction: ${({descriptionVariant}) => (descriptionVariant === 'inline' ? 'row' : 'column')};
align-items: baseline;
`

const BaseVisualContainer = styled.div<{variant?: ItemProps['variant']; disabled?: boolean}>`
Expand All @@ -242,7 +249,7 @@ const LeadingVisualContainer = styled(ColoredVisualContainer)``

const TrailingVisualContainer = styled(ColoredVisualContainer)`
color: ${({variant, disabled}) => getItemVariant(variant, disabled).annotationColor}};
margin-left: auto;
margin-left: ${get('space.2')};
margin-right: 0;
div:nth-child(2) {
margin-left: ${get('space.2')};
Expand All @@ -254,7 +261,14 @@ const TrailingVisualContainer = styled(ColoredVisualContainer)`

const DescriptionContainer = styled.span<{descriptionVariant: ItemProps['descriptionVariant']}>`
color: ${get('colors.text.secondary')};
font-size: ${get('fontSizes.0')};
Comment thread
smockle marked this conversation as resolved.
// TODO: When rem-based spacing on a 4px scale lands, replace
// hardcoded '16px' with '${get('lh-12')}'.
line-height: 16px;
margin-left: ${({descriptionVariant}) => (descriptionVariant === 'inline' ? get('space.2') : 0)};
min-width: 0;
flex-grow: 1;
flex-basis: ${({descriptionVariant}) => (descriptionVariant === 'inline' ? 0 : 'auto')};
`

const MultiSelectInput = styled.input`
Expand Down Expand Up @@ -365,27 +379,33 @@ export function Item(itemProps: Partial<ItemProps> & {item?: ItemInput}): JSX.El
</LeadingVisualContainer>
)}
<StyledItemContent>
<Flex>
{children}
{(text || description) && (
<StyledTextContainer descriptionVariant={descriptionVariant}>
{text && <div>{text}</div>}
{description && (
<DescriptionContainer descriptionVariant={descriptionVariant}>{description}</DescriptionContainer>
)}
</StyledTextContainer>
)}
{(TrailingIcon || trailingText) && (
<TrailingVisualContainer variant={variant} disabled={disabled}>
{trailingText && <div>{trailingText}</div>}
{TrailingIcon && (
<div>
<TrailingIcon />
</div>
)}
</TrailingVisualContainer>
)}
</Flex>
{children}
{(text || description) && (
<StyledTextContainer descriptionVariant={descriptionVariant}>
{text && <div>{text}</div>}
{description && (
<DescriptionContainer descriptionVariant={descriptionVariant}>
{descriptionVariant === 'block' ? (
description
) : (
<Truncate title={description} inline={true} maxWidth="100%">
{description}
</Truncate>
)}
</DescriptionContainer>
)}
</StyledTextContainer>
)}
{(TrailingIcon || trailingText) && (
<TrailingVisualContainer variant={variant} disabled={disabled}>
{trailingText && <div>{trailingText}</div>}
{TrailingIcon && (
<div>
<TrailingIcon />
</div>
)}
</TrailingVisualContainer>
)}
</StyledItemContent>
</StyledItem>
)
Expand Down
40 changes: 39 additions & 1 deletion src/stories/ActionList.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ const meta: Meta = {
}
export default meta

const ErsatzOverlay = styled.div`
const ErsatzOverlay = styled.div<{maxWidth?: string}>`
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 8px 24px rgba(149, 157, 165, 0.2);
overflow: hidden;
max-width: ${({maxWidth}) => maxWidth || 'none'};
`

export function ActionsStory(): JSX.Element {
Expand Down Expand Up @@ -324,3 +325,40 @@ export function CustomItemChildren(): JSX.Element {
)
}
CustomItemChildren.storyName = 'Custom Item Children'

export function SizeStressTestingStory(): JSX.Element {
return (
<>
<h1>Size Stress Testing</h1>
<ErsatzOverlay maxWidth="300px">
<ActionList
items={[
{
leadingVisual: ArrowRightIcon,
text: 'Block Description. Long text should wrap',
description: 'This description is long, but it is block so it wraps',
descriptionVariant: 'block',
trailingIcon: ArrowLeftIcon,

showDivider: true
},
{
leadingVisual: ArrowRightIcon,
text: 'Inline Description',
description: 'This description gets truncated because it is inline',
trailingIcon: ArrowLeftIcon,
showDivider: true
},
{
leadingVisual: ArrowRightIcon,
text: 'Really long text without a description should wrap',
trailingIcon: ArrowLeftIcon,
showDivider: true
}
]}
/>
</ErsatzOverlay>
</>
)
}
SizeStressTestingStory.storyName = 'Size Stress Testing'