diff --git a/.changeset/small-apricots-judge.md b/.changeset/small-apricots-judge.md
new file mode 100644
index 000000000..610784fdb
--- /dev/null
+++ b/.changeset/small-apricots-judge.md
@@ -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
+
+
+ Check icon override in green
+
+ X icon in orange
+ X icon in red
+ X icon in blue
+ X icon in purple{' '}
+ Muted text color
+
+```
diff --git a/apps/docs/content/components/UnorderedList/react.mdx b/apps/docs/content/components/UnorderedList/react.mdx
index eba5649ba..e90b2fc99 100644
--- a/apps/docs/content/components/UnorderedList/react.mdx
+++ b/apps/docs/content/components/UnorderedList/react.mdx
@@ -48,6 +48,44 @@ import {UnorderedList} from '@primer/react-brand'
```
+### `x` variant
+
+```jsx live
+
+
+ Automatic security and version updates
+
+ GitHub Security Advisories
+ Code and secret scanning
+ Dependency review
+
+ Automated authentication and identity management
+
+
+```
+
+### Custom colors
+
+```jsx live
+
+
+ Automatic security and version updates
+
+
+ GitHub Security Advisories
+
+
+ Code and secret scanning
+
+
+ Dependency review
+
+
+ Automated authentication and identity management
+
+
+```
+
## Component props
### UnorderedList
@@ -55,12 +93,17 @@ import {UnorderedList} from '@primer/react-brand'
| 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).
diff --git a/apps/docs/scripts/components-with-animation.js b/apps/docs/scripts/components-with-animation.js
index c5b3eb9f5..76dc2947c 100644
--- a/apps/docs/scripts/components-with-animation.js
+++ b/apps/docs/scripts/components-with-animation.js
@@ -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',
diff --git a/package-lock.json b/package-lock.json
index 3d59c488f..46ae4cca5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -46,7 +46,7 @@
},
"apps/storybook": {
"name": "@primer/brand-storybook",
- "version": "0.30.0",
+ "version": "0.30.1",
"license": "MIT",
"devDependencies": {
"@babel/preset-env": "^7.22.0",
@@ -27353,7 +27353,7 @@
},
"packages/design-tokens": {
"name": "@primer/brand-primitives",
- "version": "0.30.0",
+ "version": "0.30.1",
"license": "MIT",
"devDependencies": {
"@primer/primitives": "^7.15.0",
@@ -27504,7 +27504,7 @@
},
"packages/e2e": {
"name": "@primer/brand-e2e",
- "version": "0.30.0",
+ "version": "0.30.1",
"license": "MIT",
"devDependencies": {
"@github/axe-github": "^0.5.0",
@@ -27518,7 +27518,7 @@
},
"packages/fonts": {
"name": "@primer/brand-fonts",
- "version": "0.30.0",
+ "version": "0.30.1",
"license": "MIT",
"engines": {
"node": ">=16.0.0",
@@ -27527,7 +27527,7 @@
},
"packages/react": {
"name": "@primer/react-brand",
- "version": "0.30.0",
+ "version": "0.30.1",
"license": "MIT",
"dependencies": {
"@primer/behaviors": "^1.3.4",
@@ -27575,7 +27575,7 @@
},
"packages/repo-configs": {
"name": "@primer/brand-config",
- "version": "0.30.0",
+ "version": "0.30.1",
"license": "MIT"
}
},
diff --git a/packages/react/src/Avatar/Avatar.visual.spec.ts-snapshots/Visual-Comparison-Avatar-Avatar-Default-1-linux.png b/packages/react/src/Avatar/Avatar.visual.spec.ts-snapshots/Visual-Comparison-Avatar-Avatar-Default-1-linux.png
new file mode 100644
index 000000000..f4825909a
Binary files /dev/null and b/packages/react/src/Avatar/Avatar.visual.spec.ts-snapshots/Visual-Comparison-Avatar-Avatar-Default-1-linux.png differ
diff --git a/packages/react/src/list/ListItem/ListItem.module.css b/packages/react/src/list/ListItem/ListItem.module.css
index 44ce7d900..3d8fa6b6c 100644
--- a/packages/react/src/list/ListItem/ListItem.module.css
+++ b/packages/react/src/list/ListItem/ListItem.module.css
@@ -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;
diff --git a/packages/react/src/list/ListItem/ListItem.module.css.d.ts b/packages/react/src/list/ListItem/ListItem.module.css.d.ts
index cbf529ecc..2df20fa94 100644
--- a/packages/react/src/list/ListItem/ListItem.module.css.d.ts
+++ b/packages/react/src/list/ListItem/ListItem.module.css.d.ts
@@ -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;
diff --git a/packages/react/src/list/ListItem/ListItem.tsx b/packages/react/src/list/ListItem/ListItem.tsx
index 572340f69..191a8d988 100644
--- a/packages/react/src/list/ListItem/ListItem.tsx
+++ b/packages/react/src/list/ListItem/ListItem.tsx
@@ -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'
@@ -16,26 +16,92 @@ export type ListItemProps = BaseProps & {
* The ref object to be attached to the list item.
*/
ref?: Ref
-}
+ /*
+ * 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
-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 (
+
+ )
+ }
+
switch (variant) {
case 'checked':
- return
+ return (
+
+ )
+ case 'x':
+ return (
+
+ )
case 'default':
- return
+ return (
+
+ )
default:
return null
}
}
+
return (
- {leadingVisual()}
- {children}
+ {_leadingVisual()}
+
+ {children}
+
)
}
diff --git a/packages/react/src/list/UnorderedList/UnorderedList.features.stories.tsx b/packages/react/src/list/UnorderedList/UnorderedList.features.stories.tsx
index 05140d07a..487fd20a6 100644
--- a/packages/react/src/list/UnorderedList/UnorderedList.features.stories.tsx
+++ b/packages/react/src/list/UnorderedList/UnorderedList.features.stories.tsx
@@ -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',
@@ -17,3 +18,56 @@ export const CheckList = () => (
Automated authentication and identity management
)
+
+export const XList = () => (
+
+ Automatic security and version updates
+ GitHub Security Advisories
+ Code and secret scanning
+ Dependency review
+ Automated authentication and identity management
+
+)
+
+export const customColor = () => (
+
+ Automatic security and version updates
+ GitHub Security Advisories
+ Code and secret scanning
+ Dependency review
+ Automated authentication and identity management
+
+)
+
+export const customIcon = () => (
+
+
+ Automatic security and version updates
+
+
+ GitHub Security Advisories
+
+ Code and secret scanning
+
+ Dependency review
+
+
+ Automated authentication and identity management
+
+
+)
+
+export const textVariant = () => (
+
+ Default
+ Muted
+
+)
diff --git a/packages/react/src/list/UnorderedList/UnorderedList.stories.tsx b/packages/react/src/list/UnorderedList/UnorderedList.stories.tsx
index 2c5401cb5..e9bb4d7c0 100644
--- a/packages/react/src/list/UnorderedList/UnorderedList.stories.tsx
+++ b/packages/react/src/list/UnorderedList/UnorderedList.stories.tsx
@@ -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: {
diff --git a/packages/react/src/list/UnorderedList/UnorderedList.tsx b/packages/react/src/list/UnorderedList/UnorderedList.tsx
index 303820f9a..0a1d19a4c 100644
--- a/packages/react/src/list/UnorderedList/UnorderedList.tsx
+++ b/packages/react/src/list/UnorderedList/UnorderedList.tsx
@@ -10,7 +10,7 @@ export type UnorderedListProps = PropsWithChildren>
/**
* 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) {
diff --git a/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts b/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts
index 564004613..af29dc4c0 100644
--- a/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts
+++ b/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts
@@ -16,6 +16,42 @@ test.describe('Visual Comparison: UnorderedList', () => {
expect(await page.screenshot()).toMatchSnapshot()
})
+ test('UnorderedList / X List', async ({page}) => {
+ await page.goto(
+ 'http://localhost:6006/iframe.html?args=&id=components-unorderedlist-features--x-list&viewMode=story',
+ )
+
+ await page.waitForTimeout(500)
+ expect(await page.screenshot()).toMatchSnapshot()
+ })
+
+ test('UnorderedList / Custom Color', async ({page}) => {
+ await page.goto(
+ 'http://localhost:6006/iframe.html?args=&id=components-unorderedlist-features--custom-color&viewMode=story',
+ )
+
+ await page.waitForTimeout(500)
+ expect(await page.screenshot()).toMatchSnapshot()
+ })
+
+ test('UnorderedList / Custom Icon', async ({page}) => {
+ await page.goto(
+ 'http://localhost:6006/iframe.html?args=&id=components-unorderedlist-features--custom-icon&viewMode=story',
+ )
+
+ await page.waitForTimeout(500)
+ expect(await page.screenshot()).toMatchSnapshot()
+ })
+
+ test('UnorderedList / Text Variant', async ({page}) => {
+ await page.goto(
+ 'http://localhost:6006/iframe.html?args=&id=components-unorderedlist-features--text-variant&viewMode=story',
+ )
+
+ await page.waitForTimeout(500)
+ expect(await page.screenshot()).toMatchSnapshot()
+ })
+
test('UnorderedList / Default', async ({page}) => {
await page.goto('http://localhost:6006/iframe.html?args=&id=components-unorderedlist--default&viewMode=story')
diff --git a/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts-snapshots/Visual-Comparison-UnorderedList-UnorderedList-Custom-Color-1-linux.png b/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts-snapshots/Visual-Comparison-UnorderedList-UnorderedList-Custom-Color-1-linux.png
new file mode 100644
index 000000000..436b104a0
Binary files /dev/null and b/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts-snapshots/Visual-Comparison-UnorderedList-UnorderedList-Custom-Color-1-linux.png differ
diff --git a/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts-snapshots/Visual-Comparison-UnorderedList-UnorderedList-Custom-Icon-1-linux.png b/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts-snapshots/Visual-Comparison-UnorderedList-UnorderedList-Custom-Icon-1-linux.png
new file mode 100644
index 000000000..39dc2e3dc
Binary files /dev/null and b/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts-snapshots/Visual-Comparison-UnorderedList-UnorderedList-Custom-Icon-1-linux.png differ
diff --git a/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts-snapshots/Visual-Comparison-UnorderedList-UnorderedList-Text-Variant-1-linux.png b/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts-snapshots/Visual-Comparison-UnorderedList-UnorderedList-Text-Variant-1-linux.png
new file mode 100644
index 000000000..b05815327
Binary files /dev/null and b/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts-snapshots/Visual-Comparison-UnorderedList-UnorderedList-Text-Variant-1-linux.png differ
diff --git a/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts-snapshots/Visual-Comparison-UnorderedList-UnorderedList-X-List-1-linux.png b/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts-snapshots/Visual-Comparison-UnorderedList-UnorderedList-X-List-1-linux.png
new file mode 100644
index 000000000..635aad409
Binary files /dev/null and b/packages/react/src/list/UnorderedList/UnorderedList.visual.spec.ts-snapshots/Visual-Comparison-UnorderedList-UnorderedList-X-List-1-linux.png differ