Skip to content

Commit 61da173

Browse files
chore: custom prop for activator on usermenu; allow react.node for actionlist title; allow helptext as prop to sections
fix: commits that are messed up ammend: use source path ammend: call hook outside of callback review: use unique id on iteration ammend: use source path ammend: call hook outside of callback review: use unique id on iteration Update .changeset/famous-hairs-jam.md fix: use correct import on usermenu; use correct key changeset chore: update top bar menu stories to reflect new menu chore: use actionlistprops as type of actions Co-Authored-By: Kyle Durand <kyledurand@users.noreply.github.com>
1 parent d2dba78 commit 61da173

File tree

8 files changed

+116
-15
lines changed

8 files changed

+116
-15
lines changed

.changeset/famous-hairs-jam.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@shopify/polaris': minor
3+
---
4+
5+
Updated top bar menu active state

polaris-react/src/components/ActionList/ActionList.scss

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,6 @@
5858
svg {
5959
fill: var(--p-color-icon-interactive);
6060
}
61-
62-
&::before {
63-
// stylelint-disable-next-line -- alignment for left tab style https://github.com/Shopify/polaris/pull/3619
64-
@include list-selected-indicator;
65-
}
6661
}
6762

6863
&.destructive {

polaris-react/src/components/ActionList/ActionList.stories.tsx

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,51 @@ export function WithSections() {
178178
);
179179
}
180180

181+
export function WithSectionsAndHelpTexts() {
182+
const [active, setActive] = useState(true);
183+
184+
const toggleActive = useCallback(() => setActive((active) => !active), []);
185+
186+
const activator = (
187+
<Button onClick={toggleActive} disclosure>
188+
More actions
189+
</Button>
190+
);
191+
192+
return (
193+
<div style={{height: '250px'}}>
194+
<Popover
195+
active={active}
196+
activator={activator}
197+
autofocusTarget="first-node"
198+
onClose={toggleActive}
199+
>
200+
<ActionList
201+
actionRole="menuitem"
202+
sections={[
203+
{
204+
title: 'File options',
205+
helpText: 'Import or export your data',
206+
items: [
207+
{content: 'Import file', icon: ImportMinor},
208+
{content: 'Export file', icon: ExportMinor},
209+
],
210+
},
211+
{
212+
title: 'Bulk actions',
213+
helpText: 'Edit or delete multiple items at once',
214+
items: [
215+
{content: 'Edit', icon: EditMinor},
216+
{content: 'Delete', icon: DeleteMinor},
217+
],
218+
},
219+
]}
220+
/>
221+
</Popover>
222+
</div>
223+
);
224+
}
225+
181226
export function WithSectionsNoTitles() {
182227
const [active, setActive] = useState(true);
183228

polaris-react/src/components/ActionList/ActionList.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {KeypressListener} from '../KeypressListener';
88
import {Key} from '../../types';
99
import type {ActionListItemDescriptor, ActionListSection} from '../../types';
1010
import {Box} from '../Box';
11+
import {useUniqueId} from '../../utilities/unique-id';
1112

1213
import {Section, Item} from './components';
1314
import type {ItemProps} from './components';
@@ -33,6 +34,7 @@ export function ActionList({
3334
}: ActionListProps) {
3435
let finalSections: readonly ActionListSection[] = [];
3536
const actionListRef = useRef<HTMLDivElement & HTMLUListElement>(null);
37+
const sectionId = useUniqueId('ActionListSection');
3638

3739
if (items) {
3840
finalSections = [{items}, ...sections];
@@ -49,7 +51,7 @@ export function ActionList({
4951
const sectionMarkup = finalSections.map((section, index) => {
5052
return section.items.length > 0 ? (
5153
<Section
52-
key={section.title || index}
54+
key={sectionId}
5355
section={section}
5456
hasMultipleSections={hasMultipleSections}
5557
actionRole={actionRole}

polaris-react/src/components/ActionList/components/Section/Section.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export function Section({
6161
<Box
6262
paddingBlockStart="4"
6363
paddingInlineStart="4"
64-
paddingBlockEnd="2"
64+
paddingBlockEnd={section.helpText ? '1' : '2'}
6565
paddingInlineEnd="4"
6666
>
6767
<Text as="p" variant="headingXs">
@@ -70,6 +70,19 @@ export function Section({
7070
</Box>
7171
) : null;
7272

73+
const helpTextMarkup = section.helpText ? (
74+
<Box
75+
paddingBlockStart={section.title ? '0' : '2'}
76+
paddingInlineStart="4"
77+
paddingBlockEnd="2"
78+
paddingInlineEnd="4"
79+
>
80+
<Text as="span" color="subdued" breakWord>
81+
{section.helpText}
82+
</Text>
83+
</Box>
84+
) : null;
85+
7386
let sectionRole: 'menu' | 'presentation' | undefined;
7487
switch (actionRole) {
7588
case 'option':
@@ -86,6 +99,7 @@ export function Section({
8699
const sectionMarkup = (
87100
<>
88101
{titleMarkup}
102+
{helpTextMarkup}
89103
<Box
90104
as="ul"
91105
padding="2"

polaris-react/src/components/TopBar/TopBar.stories.tsx

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import React, {useCallback, useState} from 'react';
22
import type {ComponentMeta} from '@storybook/react';
3-
import {ActionList, Frame, Icon, TopBar, Text} from '@shopify/polaris';
4-
import {ArrowLeftMinor, QuestionMarkMajor} from '@shopify/polaris-icons';
3+
import {ActionList, Frame, Icon, TopBar, Text, Avatar} from '@shopify/polaris';
4+
import {
5+
ArrowLeftMinor,
6+
QuestionMarkMajor,
7+
EditMinor,
8+
TickSmallMinor,
9+
SearchMinor,
10+
} from '@shopify/polaris-icons';
511

612
export default {
713
component: TopBar,
@@ -49,15 +55,42 @@ export function Default() {
4955
<TopBar.UserMenu
5056
actions={[
5157
{
52-
items: [{content: 'Back to Shopify', icon: ArrowLeftMinor}],
58+
helpText: 'Jaded Pixel',
59+
items: [
60+
{
61+
active: true,
62+
content: 'Jaded Pixel',
63+
prefix: <Avatar size="small" name="Jaded Pixel" />,
64+
suffix: <Icon source={TickSmallMinor} />,
65+
},
66+
{
67+
content: 'Jaded Pixel 2.0',
68+
prefix: <Avatar size="small" name="Jaded Pixel 2.0" />,
69+
},
70+
{
71+
content: 'View all 3 stores',
72+
prefix: <Icon source={SearchMinor} />,
73+
},
74+
],
5375
},
5476
{
5577
items: [{content: 'Community forums'}],
5678
},
79+
{
80+
items: [{content: 'Help Center'}],
81+
},
82+
{
83+
items: [{content: 'Keyboard shortcuts'}],
84+
},
85+
{
86+
title: 'Dharma Johnson',
87+
helpText: 'dharma@jadedpixel.com',
88+
items: [{content: 'Manage account'}, {content: 'Log out'}],
89+
},
5790
]}
5891
name="Dharma"
5992
detail="Jaded Pixel"
60-
initials="D"
93+
initials="JP"
6194
open={isUserMenuOpen}
6295
onToggle={toggleIsUserMenuOpen}
6396
/>

polaris-react/src/components/TopBar/components/UserMenu/UserMenu.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import React from 'react';
22

3-
import type {IconableAction} from '../../../../types';
43
import {Avatar} from '../../../Avatar';
54
import type {AvatarProps} from '../../../Avatar';
65
import {MessageIndicator} from '../../../MessageIndicator';
76
import {Menu} from '../Menu';
87
import type {MenuProps} from '../Menu';
98
import {Text} from '../../../Text';
9+
import type {ActionListProps} from '../../../ActionList';
1010

1111
import styles from './UserMenu.scss';
1212

1313
export interface UserMenuProps {
1414
/** An array of action objects that are rendered inside of a popover triggered by this menu */
15-
actions: {items: IconableAction[]}[];
15+
actions: ActionListProps['sections'];
1616
/** Accepts a message that facilitates direct, urgent communication with the merchant through the user menu */
1717
message?: MenuProps['message'];
1818
/** A string detailing the merchant’s full name to be displayed in the user menu */
@@ -29,6 +29,8 @@ export interface UserMenuProps {
2929
open: boolean;
3030
/** A callback function to handle opening and closing the user menu */
3131
onToggle(): void;
32+
/** A custom activator that can be used when the default activator is not desired */
33+
activatorContent?: React.ReactNode;
3234
}
3335

3436
export function UserMenu({
@@ -41,10 +43,13 @@ export function UserMenu({
4143
onToggle,
4244
open,
4345
accessibilityLabel,
46+
activatorContent,
4447
}: UserMenuProps) {
4548
const showIndicator = Boolean(message);
4649

47-
const activatorContentMarkup = (
50+
const activatorContentMarkup = activatorContent ? (
51+
activatorContent
52+
) : (
4853
<>
4954
<MessageIndicator active={showIndicator}>
5055
<Avatar

polaris-react/src/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,11 @@ export interface ActionListItemDescriptor
206206

207207
export interface ActionListSection {
208208
/** Section title */
209-
title?: string;
209+
title?: React.ReactNode;
210210
/** Collection of action items for the list */
211211
items: readonly ActionListItemDescriptor[];
212+
/** Section help text */
213+
helpText?: React.ReactNode;
212214
}
213215

214216
export interface ComplexAction

0 commit comments

Comments
 (0)