Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add x variant to unordered lists, and leadingVisual, variant and color props to list items #534

Merged
merged 1 commit into from
Feb 20, 2024
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
20 changes: 20 additions & 0 deletions .changeset/small-apricots-judge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
'@primer/react-brand': patch
---

Added `x` variant to `UnorderedList`, and `leadingVisual`, `variant`, `leadingVisualAriaLabel` and `leadingVisualFill` props to list items.

Example:

```jsx
<UnorderedList variant="x">
<UnorderedList.Item leadingVisual={CheckIcon} leadingVisualFill="green">
Check icon override in green
</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="orange">X icon in orange</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="red">X icon in red</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="blue">X icon in blue</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="purple">X icon in purple</UnorderedList.Item>{' '}
<UnorderedList.Item variant="muted">Muted text color</UnorderedList.Item>
</UnorderedList>
```
53 changes: 48 additions & 5 deletions apps/docs/content/components/UnorderedList/react.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,62 @@ import {UnorderedList} from '@primer/react-brand'
</UnorderedList>
```

### `x` variant

```jsx live
<UnorderedList variant="x">
<UnorderedList.Item>
Automatic security and version updates
</UnorderedList.Item>
<UnorderedList.Item>GitHub Security Advisories</UnorderedList.Item>
<UnorderedList.Item>Code and secret scanning</UnorderedList.Item>
<UnorderedList.Item>Dependency review</UnorderedList.Item>
<UnorderedList.Item>
Automated authentication and identity management
</UnorderedList.Item>
</UnorderedList>
```

### Custom colors

```jsx live
<UnorderedList variant="checked">
<UnorderedList.Item leadingVisualFill="var(--brand-color-success-fg)">
Automatic security and version updates
</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="var(--brand-color-success-fg)">
GitHub Security Advisories
</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="var(--brand-color-success-fg)">
Code and secret scanning
</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="var(--brand-color-success-fg)">
Dependency review
</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="var(--brand-color-success-fg)">
Automated authentication and identity management
</UnorderedList.Item>
</UnorderedList>
```

## Component props

### UnorderedList

| Name | Type | Default | Description |
| :---------- | :------------------------------------- | :-------: | :--------------------------------------------------------- |
| `className` | `string` | | Sets a custom class on the root element |
| `variant` | `default`, `checked` | `default` | Specify alternative leading visual for list items |
| `variant` | `default`, `checked` , `x` | `default` | Specify alternative leading visual for list items |
| `children` | `React.ReactNode`, `React.ReactNode[]` | | Content to be displayed within the UnorderedList component |

### UnorderedList.Item

| Name | Type | Default | Description |
| :---------- | :------------------------------------- | :-------: | :------------------------------------------------------- |
| `className` | `string` | | Sets a custom class on the root element |
| `children` | `React.ReactNode`, `React.ReactNode[]` | `default` | Content to be displayed within the OrderedList component |
| Name | Type | Default | Description |
| :----------------------- | :------------------------------------- | :---------: | :-------------------------------------------------------------------------------------------------- |
| `className` | `string` | | Sets a custom class on the root element |
| `children` | `React.ReactNode`, `React.ReactNode[]` | `default` | Content to be displayed within the OrderedList component |
| `leadingVisual` | `Icon` | `undefined` | Sets a custom leading visual ([Octicon](https://primer.style/foundations/icons/)) for the list item |
| `leadingVisualFill` | `string` | `undefined` | Sets a custom color value for the leading visual |
| `leadingVisualAriaLabel` | `string` | `undefined` | Sets `aria-label` on the leading visual icon |

Also forwards the `variant` prop from the [Text component](/components/Text).
4 changes: 2 additions & 2 deletions apps/docs/scripts/components-with-animation.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
/* This file is generated by a script. Do not modify. */

export const supportedComponents = [
'Button',
'Box',
'Button',
'ComparisonTable',
'FAQ',
'Heading',
'Image',
'Label',
'Pillar',
'SectionIntro',
'Stack',
'Testimonial',
'Text',
'Timeline',
'SectionIntro',
'Animate',
'River',
'RiverBreakout',
Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 12 additions & 1 deletion packages/react/src/list/ListItem/ListItem.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,22 @@
gap: var(--base-size-12);
}

.ListItem--default {
color: var(--brand-color-text-default);
}

.ListItem--muted {
color: var(--brand-color-text-muted);
}

.ListItem__leading-visual {
fill: var(--brand-color-text-muted);
margin: var(--base-size-4) 0;
}

.ListItem__leading-visual--muted {
fill: var(--brand-color-text-muted);
}

.OrderedList__item::before {
content: counter(li) '.';
counter-increment: li;
Expand Down
3 changes: 3 additions & 0 deletions packages/react/src/list/ListItem/ListItem.module.css.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
declare const styles: {
readonly "ListItem": string;
readonly "ListItem--default": string;
readonly "ListItem--muted": string;
readonly "ListItem__leading-visual": string;
readonly "ListItem__leading-visual--muted": string;
readonly "OrderedList__item": string;
};
export = styles;
Expand Down
84 changes: 75 additions & 9 deletions packages/react/src/list/ListItem/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, {type Ref, useContext} from 'react'
import clsx from 'clsx'
import {CheckIcon, DashIcon} from '@primer/octicons-react'
import {Text} from '../../Text'
import {CheckIcon, DashIcon, Icon, IconProps, XIcon} from '@primer/octicons-react'
import {Text, TextProps} from '../../Text'
import type {BaseProps} from '../../component-helpers'
import {ListContext} from '../listContext'

Expand All @@ -16,26 +16,92 @@ export type ListItemProps = BaseProps<HTMLElement> & {
* The ref object to be attached to the list item.
*/
ref?: Ref<HTMLLIElement>
}
/*
* Custom icon to be used as leading visual
*/
leadingVisual?: Icon
/*
* Color of leading icon
*/
leadingVisualFill?: IconProps['fill']
/*
* Aria label for the leading visual
*/
leadingVisualAriaLabel?: string
} & Pick<TextProps, 'variant'>

function Root({className, children, ...props}: ListItemProps) {
function Root({
className,
children,
leadingVisualFill,
leadingVisual: LeadingVisual,
leadingVisualAriaLabel,
variant: textVariant = 'default',
...props
}: ListItemProps) {
const {variant} = useContext(ListContext)

const leadingVisual = () => {
const _leadingVisual = () => {
const iconProps = {fill: leadingVisualFill, 'aria-label': leadingVisualAriaLabel}

if (LeadingVisual) {
return (
<LeadingVisual
className={clsx(
styles['ListItem__leading-visual'],
!leadingVisualFill && styles['ListItem__leading-visual--muted'],
)}
{...iconProps}
/>
)
}

switch (variant) {
case 'checked':
return <CheckIcon className={clsx(styles['ListItem__leading-visual'], styles['ListItem__checked'])} />
return (
<CheckIcon
className={clsx(
styles['ListItem__leading-visual'],
styles['ListItem__checked'],
!leadingVisualFill && styles['ListItem__leading-visual--muted'],
)}
{...iconProps}
/>
)
case 'x':
return (
<XIcon
className={clsx(
styles['ListItem__leading-visual'],
styles['ListItem__x'],
!leadingVisualFill && styles['ListItem__leading-visual--muted'],
)}
{...iconProps}
/>
)
case 'default':
return <DashIcon className={clsx(styles['ListItem__leading-visual'], styles['ListItem__default'])} />
return (
<DashIcon
className={clsx(
styles['ListItem__leading-visual'],
styles['ListItem__default'],
!leadingVisualFill && styles['ListItem__leading-visual--muted'],
)}
{...iconProps}
/>
)

default:
return null
}
}

return (
<li className={clsx(styles.ListItem, !variant && styles.OrderedList__item, className)} {...props}>
{leadingVisual()}
<Text as="span">{children}</Text>
{_leadingVisual()}
<Text as="span" variant={textVariant} className={clsx(styles[`ListItem--${textVariant}`])}>
{children}
</Text>
</li>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react'
import {Meta} from '@storybook/react'

import {UnorderedList} from '.'
import {XIcon} from '@primer/octicons-react'

export default {
title: 'Components/UnorderedList/Features',
Expand All @@ -17,3 +18,56 @@ export const CheckList = () => (
<UnorderedList.Item>Automated authentication and identity management</UnorderedList.Item>
</UnorderedList>
)

export const XList = () => (
<UnorderedList variant="x">
<UnorderedList.Item>Automatic security and version updates</UnorderedList.Item>
<UnorderedList.Item>GitHub Security Advisories</UnorderedList.Item>
<UnorderedList.Item>Code and secret scanning</UnorderedList.Item>
<UnorderedList.Item>Dependency review</UnorderedList.Item>
<UnorderedList.Item>Automated authentication and identity management</UnorderedList.Item>
</UnorderedList>
)

export const customColor = () => (
<UnorderedList variant="checked">
<UnorderedList.Item leadingVisualFill="green">Automatic security and version updates</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="orange">GitHub Security Advisories</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="red">Code and secret scanning</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="blue">Dependency review</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="purple">Automated authentication and identity management</UnorderedList.Item>
</UnorderedList>
)

export const customIcon = () => (
<UnorderedList variant="checked">
<UnorderedList.Item leadingVisualFill="var(--brand-color-success-fg)">
Automatic security and version updates
</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="var(--brand-color-success-fg)">
GitHub Security Advisories
</UnorderedList.Item>
<UnorderedList.Item leadingVisualFill="var(--brand-color-success-fg)">Code and secret scanning</UnorderedList.Item>
<UnorderedList.Item
leadingVisual={XIcon}
leadingVisualFill="var(--brand-color-text-muted)"
leadingVisualAriaLabel="Not included icon"
>
Dependency review
</UnorderedList.Item>
<UnorderedList.Item
leadingVisual={XIcon}
leadingVisualFill="var(--brand-color-text-muted)"
leadingVisualAriaLabel="Not included icon"
>
Automated authentication and identity management
</UnorderedList.Item>
</UnorderedList>
)

export const textVariant = () => (
<UnorderedList>
<UnorderedList.Item>Default</UnorderedList.Item>
<UnorderedList.Item variant="muted">Muted</UnorderedList.Item>
</UnorderedList>
)
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default {
description: 'Specify alternative leading visuals for list items',
control: {
type: 'radio',
options: ['default', 'checked'],
options: ['default', 'checked', 'x'],
},
},
data: {
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/list/UnorderedList/UnorderedList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export type UnorderedListProps = PropsWithChildren<BaseProps<HTMLUListElement>>
/**
* The semantic structure of list that is presented visually setting 'ol' vs 'ul' based on the style the style of the list.
*/
variant?: 'default' | 'checked'
variant?: 'default' | 'checked' | 'x'
}

function Root({variant = 'default', children, ...props}: UnorderedListProps) {
Expand Down
Loading
Loading