Skip to content
6 changes: 6 additions & 0 deletions .changeset/serious-tomatoes-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@shopify/polaris': minor
'polaris.shopify.com': patch
---

Rebuilt `ActionList` to use layout primitives
50 changes: 0 additions & 50 deletions polaris-react/src/components/ActionList/ActionList.scss
Original file line number Diff line number Diff line change
@@ -1,44 +1,5 @@
@import '../../styles/common';

.ActionList {
outline: none;
list-style: none;
margin: 0;
padding: 0;
}

.Section:not(:first-child) {
border-top: var(--p-border-divider);

// stylelint-disable-next-line selector-max-class, selector-max-combinators, selector-max-specificity
> .Section-withoutTitle .Actions {
padding-top: var(--p-space-2);
}
}

.Actions {
outline: none;
list-style: none;
margin: 0;
padding: var(--p-space-2);
}

.ActionList,
.Section:first-child {
// stylelint-disable-next-line selector-max-class, selector-max-combinators, selector-max-specificity
> .Section-withoutTitle .Actions {
border-top: none;
padding-top: var(--p-space-2);
}
}

.ActionList .Section {
// stylelint-disable-next-line selector-max-class, selector-max-combinators
.Actions {
padding-top: 0;
}
}

.Item {
--pc-action-list-image-size: 20px;
--pc-action-list-item-min-height: var(--p-space-10);
Expand Down Expand Up @@ -117,11 +78,6 @@
}
}

.Content {
display: flex;
align-items: center;
}

.Prefix {
@include recolor-icon(var(--p-icon));
display: flex;
Expand All @@ -142,12 +98,6 @@

.Suffix {
@include recolor-icon(var(--p-icon));
margin-left: var(--p-space-4);
}

.ContentBlock,
.ContentBlockInner {
display: block;
}

.Text {
Expand Down
13 changes: 5 additions & 8 deletions polaris-react/src/components/ActionList/ActionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import {
} from '../../utilities/focus';
import {KeypressListener} from '../KeypressListener';
import {ActionListItemDescriptor, ActionListSection, Key} from '../../types';
import {classNames} from '../../utilities/css';
import {Box} from '../Box';

import {Section, Item} from './components';
import type {ItemProps} from './components';
import styles from './ActionList.scss';

export interface ActionListProps {
/** Collection of actions for list */
Expand Down Expand Up @@ -40,10 +39,7 @@ export function ActionList({
finalSections = sections;
}

const className = classNames(styles.ActionList);

const hasMultipleSections = finalSections.length > 1;
const Element = hasMultipleSections ? 'ul' : 'div';
const elementRole =
hasMultipleSections && actionRole === 'menuitem' ? 'menu' : undefined;
const elementTabIndex =
Expand All @@ -57,6 +53,7 @@ export function ActionList({
hasMultipleSections={hasMultipleSections}
actionRole={actionRole}
onActionAnyItem={onActionAnyItem}
isFirst={index === 0}
/>
) : null;
});
Expand Down Expand Up @@ -102,15 +99,15 @@ export function ActionList({
) : null;

return (
<Element
<Box
as={hasMultipleSections ? 'ul' : 'div'}
ref={actionListRef}
className={className}
role={elementRole}
tabIndex={elementTabIndex}
>
{listeners}
{sectionMarkup}
</Element>
</Box>
);
}

Expand Down
16 changes: 10 additions & 6 deletions polaris-react/src/components/ActionList/components/Item/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {Badge} from '../../../Badge';
import {Text} from '../../../Text';
import styles from '../../ActionList.scss';
import {handleMouseUpByBlurring} from '../../../../utilities/focus';
import {Inline} from '../../../Inline';
import {Box} from '../../../Box';

export type ItemProps = ActionListItemDescriptor;

Expand Down Expand Up @@ -61,12 +63,12 @@ export function Item({
const contentText = ellipsis && content ? `${content}…` : content;

const contentMarkup = helpText ? (
<span className={styles.ContentBlock}>
<span className={styles.ContentBlockInner}>{contentText}</span>
<>
<Box>{contentText}</Box>
<Text variant="bodyMd" color="subdued" as="span">
{helpText}
</Text>
</span>
</>
) : (
contentText
);
Expand All @@ -78,18 +80,20 @@ export function Item({
);

const suffixMarkup = suffix && (
<span className={styles.Suffix}>{suffix}</span>
<Box paddingInlineStart="4">
<span className={styles.Suffix}>{suffix}</span>
</Box>
);

const textMarkup = <span className={styles.Text}>{contentMarkup}</span>;

const contentElement = (
<span className={styles.Content}>
<Inline blockAlign="center" gap="0">
{prefixMarkup}
{textMarkup}
{badgeMarkup}
{suffixMarkup}
</span>
</Inline>
);

const scrollMarkup = active ? <Scrollable.ScrollTo /> : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type {
ActionListItemDescriptor,
ActionListSection,
} from '../../../../types';
import styles from '../../ActionList.scss';

export interface SectionProps {
/** Section of action items */
Expand All @@ -18,11 +17,14 @@ export interface SectionProps {
actionRole?: 'option' | 'menuitem' | string;
/** Callback when any item is clicked or keypressed */
onActionAnyItem?: ActionListItemDescriptor['onAction'];
/** Whether it is the first in a group of sections */
isFirst?: boolean;
}

export function Section({
section,
hasMultipleSections,
isFirst,
actionRole,
onActionAnyItem,
}: SectionProps) {
Expand Down Expand Up @@ -55,8 +57,6 @@ export function Section({
},
);

const className = section.title ? undefined : styles['Section-withoutTitle'];

const titleMarkup = section.title ? (
<Box
paddingBlockStart="4"
Expand All @@ -70,7 +70,7 @@ export function Section({
</Box>
) : null;

let sectionRole;
let sectionRole: 'menu' | 'presentation' | undefined;
switch (actionRole) {
case 'option':
sectionRole = 'presentation';
Expand All @@ -84,22 +84,29 @@ export function Section({
}

const sectionMarkup = (
<div className={className}>
<>
{titleMarkup}
<ul
className={styles.Actions}
role={sectionRole}
<Box
as="ul"
padding="2"
{...(hasMultipleSections && {paddingBlockStart: '0'})}
{...(sectionRole && {role: sectionRole})}
tabIndex={!hasMultipleSections ? -1 : undefined}
>
{actionMarkup}
</ul>
</div>
</Box>
</>
);

return hasMultipleSections ? (
<li className={styles.Section} role="presentation">
<Box
as="li"
role="presentation"
{...(!isFirst && {borderBlockStart: 'divider'})}
{...(!section.title && {paddingBlockStart: '2'})}
>
{sectionMarkup}
</li>
</Box>
) : (
sectionMarkup
);
Expand Down
Loading