From 6b2ff86d0c34b18fc340bd1c028f224e36e09579 Mon Sep 17 00:00:00 2001
From: Katie Langerman <18661030+langermank@users.noreply.github.com>
Date: Fri, 6 Dec 2024 08:06:48 -0800
Subject: [PATCH 1/4] copy
---
.../src/ActionList/ActionList.dev.stories.tsx | 15 ++++
.../src/ActionList/ActionList.module.css | 79 +++++++++++++++++++
.../react/src/ActionList/ActionList.test.tsx | 53 +++++++++++++
packages/react/src/ActionList/Divider.tsx | 30 ++++++-
packages/react/src/ActionList/List.tsx | 57 ++++++++++---
packages/react/src/ActionList/shared.ts | 1 +
.../__snapshots__/NavList.test.tsx.snap | 4 +-
7 files changed, 222 insertions(+), 17 deletions(-)
create mode 100644 packages/react/src/ActionList/ActionList.module.css
diff --git a/packages/react/src/ActionList/ActionList.dev.stories.tsx b/packages/react/src/ActionList/ActionList.dev.stories.tsx
index 6d0fc3d1da7..5d4214c6c13 100644
--- a/packages/react/src/ActionList/ActionList.dev.stories.tsx
+++ b/packages/react/src/ActionList/ActionList.dev.stories.tsx
@@ -116,3 +116,18 @@ export const GroupHeadingCustomClassname = () => (
)
+
+export const ListCustomClassname = () => (
+
+ Copy link
+ Quote reply
+
+)
+
+export const DividerCustomClassname = () => (
+
+ Edit comment
+
+ Quote reply
+
+)
diff --git a/packages/react/src/ActionList/ActionList.module.css b/packages/react/src/ActionList/ActionList.module.css
new file mode 100644
index 00000000000..0f3e563ffa0
--- /dev/null
+++ b/packages/react/src/ActionList/ActionList.module.css
@@ -0,0 +1,79 @@
+/* stylelint-disable selector-max-specificity, selector-max-compound-selectors */
+
+.ActionList {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+
+ ul {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+ }
+
+ &:where([data-variant='inset']) {
+ /* change to padding (all) when Item is converted */
+ padding-block: var(--base-size-8);
+ }
+
+ &:where([data-dividers='true']) {
+ /* place dividers on the wrapper that excludes leading visuals/actions */
+ & .ActionListSubContent::before {
+ position: absolute;
+ /* stylelint-disable-next-line primer/spacing */
+ top: calc(-1 * var(--control-medium-paddingBlock));
+ display: block;
+ width: 100%;
+ height: 1px;
+ content: '';
+ /* stylelint-disable-next-line primer/colors */
+ background: var(--borderColor-muted);
+ }
+
+ /* if inline description, move pseudo divider to description wrapper */
+ & [data-description-variant='inline'] {
+ &::before {
+ position: absolute;
+ /* stylelint-disable-next-line primer/spacing */
+ top: calc(-1 * var(--control-medium-paddingBlock));
+ display: block;
+ width: 100%;
+ height: var(--borderWidth-thin);
+ content: '';
+ /* stylelint-disable-next-line primer/colors */
+ background: var(--borderColor-muted);
+ }
+
+ /* remove the default divider */
+ & .ActionListSubContent::before {
+ content: unset;
+ }
+ }
+
+ /* hide if item is first of type with label::before, or is the first item after a sectionDivider */
+ .ActionListItem:first-of-type .ActionListSubContent::before,
+ .Divider + .ActionListItem .ActionListSubContent::before {
+ visibility: hidden;
+ }
+
+ /* hide if item is first of type with label::before, or is the first item after a sectionDivider */
+ .ActionListItem:first-of-type [data-description-variant='inline']::before,
+ .Divider + .ActionListItem [data-description-variant='inline']::before {
+ visibility: hidden;
+ }
+ }
+}
+
+.Divider {
+ display: block;
+ height: var(--borderWidth-thin);
+ padding: 0;
+ /* stylelint-disable-next-line primer/spacing */
+ margin-block-start: calc(var(--base-size-8) - var(--borderWidth-thin));
+ margin-block-end: var(--base-size-8);
+ margin-inline: calc(-1 * var(--base-size-8));
+ list-style: none;
+ /* stylelint-disable-next-line primer/colors */
+ background: var(--borderColor-muted);
+ border: 0;
+}
diff --git a/packages/react/src/ActionList/ActionList.test.tsx b/packages/react/src/ActionList/ActionList.test.tsx
index ae983870427..b69498990d8 100644
--- a/packages/react/src/ActionList/ActionList.test.tsx
+++ b/packages/react/src/ActionList/ActionList.test.tsx
@@ -696,4 +696,57 @@ describe('ActionList', () => {
expect(description.parentElement).toHaveAttribute('data-component', 'ActionList.Item--DividerContainer')
})
})
+
+ it('should support a custom `className` on the outermost element', () => {
+ const Element = () => {
+ return (
+
+ Item
+
+ )
+ }
+ const FeatureFlagElement = () => {
+ return (
+
+
+
+ )
+ }
+ expect(HTMLRender().container.querySelector('ul')).toHaveClass('test-class-name')
+ expect(HTMLRender().container.querySelector('ul')).toHaveClass('test-class-name')
+ })
+
+ it('divider should support a custom `className`', () => {
+ const Element = () => {
+ return (
+
+ Item
+
+
+ )
+ }
+ const FeatureFlagElement = () => {
+ return (
+
+
+
+ )
+ }
+ expect(HTMLRender().container.querySelector('li[aria-hidden="true"]')).toHaveClass(
+ 'test-class-name',
+ )
+ expect(HTMLRender().container.querySelector('li[aria-hidden="true"]')).toHaveClass('test-class-name')
+ })
})
diff --git a/packages/react/src/ActionList/Divider.tsx b/packages/react/src/ActionList/Divider.tsx
index dedf06f7689..04e0de3c690 100644
--- a/packages/react/src/ActionList/Divider.tsx
+++ b/packages/react/src/ActionList/Divider.tsx
@@ -4,13 +4,34 @@ import {get} from '../constants'
import type {Theme} from '../ThemeProvider'
import type {SxProp} from '../sx'
import {merge} from '../sx'
+import {clsx} from 'clsx'
+import {useFeatureFlag} from '../FeatureFlags'
+import classes from './ActionList.module.css'
+import {defaultSxProp} from '../utils/defaultSxProp'
-export type ActionListDividerProps = SxProp
+export type ActionListDividerProps = SxProp & {
+ className?: string
+}
/**
* Visually separates `Item`s or `Group`s in an `ActionList`.
*/
-export const Divider: React.FC> = ({sx = {}}) => {
+export const Divider: React.FC> = ({sx = defaultSxProp, className}) => {
+ const enabled = useFeatureFlag('primer_react_css_modules_team')
+ if (enabled) {
+ if (sx !== defaultSxProp) {
+ return (
+
+ )
+ }
+ return
+ }
return (
>
marginTop: (theme: Theme) => `calc(${get('space.2')(theme)} - 1px)`,
marginBottom: 2,
listStyle: 'none', // hide the ::marker inserted by browser's stylesheet
- marginRight: 'calc(-1 * var(--base-size-8, 8px))',
- marginLeft: 'calc(-1 * var(--base-size-8, 8px))',
+ marginRight: 'calc(-1 * var(--base-size-8))',
+ marginLeft: 'calc(-1 * var(--base-size-8))',
},
sx as SxProp,
)}
+ className={className}
data-component="ActionList.Divider"
/>
)
diff --git a/packages/react/src/ActionList/List.tsx b/packages/react/src/ActionList/List.tsx
index 874ce8195ef..c0b9d41ed87 100644
--- a/packages/react/src/ActionList/List.tsx
+++ b/packages/react/src/ActionList/List.tsx
@@ -11,12 +11,15 @@ import {useId} from '../hooks/useId'
import {ListContext, type ActionListProps} from './shared'
import {useProvidedRefOrCreate} from '../hooks'
import {FocusKeys, useFocusZone} from '../hooks/useFocusZone'
+import {clsx} from 'clsx'
+import {useFeatureFlag} from '../FeatureFlags'
+import classes from './ActionList.module.css'
const ListBox = styled.ul(sx)
export const List = React.forwardRef(
(
- {variant = 'inset', selectionVariant, showDividers = false, role, sx: sxProp = defaultSxProp, ...props},
+ {variant = 'inset', selectionVariant, showDividers = false, role, sx: sxProp = defaultSxProp, className, ...props},
forwardedRef,
): JSX.Element => {
const styles = {
@@ -39,7 +42,7 @@ export const List = React.forwardRef(
enableFocusZone: enableFocusZoneFromContainer,
} = React.useContext(ActionListContainerContext)
- const ariaLabelledBy = slots.heading ? (slots.heading.props.id ?? headingId) : listLabelledBy
+ const ariaLabelledBy = slots.heading ? slots.heading.props.id ?? headingId : listLabelledBy
const listRole = role || listRoleFromContainer
const listRef = useProvidedRefOrCreate(forwardedRef as React.RefObject)
@@ -54,6 +57,8 @@ export const List = React.forwardRef(
focusOutBehavior: listRole === 'menu' ? 'wrap' : undefined,
})
+ const enabled = useFeatureFlag('primer_react_css_modules_team')
+
return (
(
}}
>
{slots.heading}
-
- {childrenWithoutSlots}
-
+ {enabled ? (
+ sxProp !== defaultSxProp ? (
+
+ {childrenWithoutSlots}
+
+ ) : (
+
+ {childrenWithoutSlots}
+
+ )
+ ) : (
+
+ {childrenWithoutSlots}
+
+ )}
)
},
diff --git a/packages/react/src/ActionList/shared.ts b/packages/react/src/ActionList/shared.ts
index d0d582a804b..a8f62cfc86d 100644
--- a/packages/react/src/ActionList/shared.ts
+++ b/packages/react/src/ActionList/shared.ts
@@ -131,6 +131,7 @@ export type ActionListProps = React.PropsWithChildren<{
* The ARIA role describing the function of `List` component. `listbox` or `menu` are a common values.
*/
role?: AriaRole
+ className?: string
}> &
SxProp
diff --git a/packages/react/src/NavList/__snapshots__/NavList.test.tsx.snap b/packages/react/src/NavList/__snapshots__/NavList.test.tsx.snap
index 37c51447dd1..0310e28f437 100644
--- a/packages/react/src/NavList/__snapshots__/NavList.test.tsx.snap
+++ b/packages/react/src/NavList/__snapshots__/NavList.test.tsx.snap
@@ -432,8 +432,8 @@ exports[`NavList renders with groups 1`] = `
margin-top: calc(8px - 1px);
margin-bottom: 8px;
list-style: none;
- margin-right: calc(-1 * var(--base-size-8,8px));
- margin-left: calc(-1 * var(--base-size-8,8px));
+ margin-right: calc(-1 * var(--base-size-8));
+ margin-left: calc(-1 * var(--base-size-8));
}
.c1:first-child {
From ede5340b8fef812e735d867636964b476a9a6441 Mon Sep 17 00:00:00 2001
From: Katie Langerman <18661030+langermank@users.noreply.github.com>
Date: Fri, 6 Dec 2024 08:24:37 -0800
Subject: [PATCH 2/4] Update packages/react/src/ActionList/List.tsx
---
packages/react/src/ActionList/List.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/react/src/ActionList/List.tsx b/packages/react/src/ActionList/List.tsx
index c0b9d41ed87..c957b40060a 100644
--- a/packages/react/src/ActionList/List.tsx
+++ b/packages/react/src/ActionList/List.tsx
@@ -42,7 +42,7 @@ export const List = React.forwardRef(
enableFocusZone: enableFocusZoneFromContainer,
} = React.useContext(ActionListContainerContext)
- const ariaLabelledBy = slots.heading ? slots.heading.props.id ?? headingId : listLabelledBy
+ const ariaLabelledBy = slots.heading ? (slots.heading.props.id ?? headingId) : listLabelledBy
const listRole = role || listRoleFromContainer
const listRef = useProvidedRefOrCreate(forwardedRef as React.RefObject)
From 7c3cf2ae6e0802954fd9dc6effee5e085fc590b1 Mon Sep 17 00:00:00 2001
From: Katie Langerman <18661030+langermank@users.noreply.github.com>
Date: Fri, 6 Dec 2024 08:27:41 -0800
Subject: [PATCH 3/4] Create twenty-dogs-sparkle.md
---
.changeset/twenty-dogs-sparkle.md | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 .changeset/twenty-dogs-sparkle.md
diff --git a/.changeset/twenty-dogs-sparkle.md b/.changeset/twenty-dogs-sparkle.md
new file mode 100644
index 00000000000..78e2df1e8b9
--- /dev/null
+++ b/.changeset/twenty-dogs-sparkle.md
@@ -0,0 +1,5 @@
+---
+"@primer/react": minor
+---
+
+Convert ActionList (wrapper) and ActionList.Divider to CSS Modules
From 818466618d53313ef6475d328fad7655b3fc611b Mon Sep 17 00:00:00 2001
From: Katie Langerman <18661030+langermank@users.noreply.github.com>
Date: Fri, 6 Dec 2024 11:57:44 -0800
Subject: [PATCH 4/4] lint
---
packages/react/src/ActionList/ActionList.dev.stories.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/packages/react/src/ActionList/ActionList.dev.stories.tsx b/packages/react/src/ActionList/ActionList.dev.stories.tsx
index 03068f9bca7..35c37cf213f 100644
--- a/packages/react/src/ActionList/ActionList.dev.stories.tsx
+++ b/packages/react/src/ActionList/ActionList.dev.stories.tsx
@@ -117,7 +117,6 @@ export const GroupHeadingCustomClassname = () => (
)
-
export const ListCustomClassname = () => (
Copy link