From 5938e779ceb41b32127a1a0c92560a6bcd7854cc Mon Sep 17 00:00:00 2001 From: Chloe Rice Date: Fri, 3 May 2024 13:00:23 -0400 Subject: [PATCH] [Button] Reduced space between chevron icon and provided for icon-only disclosures --- .changeset/fast-mugs-repeat.md | 5 + .../src/components/Button/Button.module.css | 8 + .../src/components/Button/Button.stories.tsx | 230 +++++++++++++++++- .../src/components/Button/Button.tsx | 7 +- 4 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 .changeset/fast-mugs-repeat.md diff --git a/.changeset/fast-mugs-repeat.md b/.changeset/fast-mugs-repeat.md new file mode 100644 index 00000000000..4b5bb9fa9bc --- /dev/null +++ b/.changeset/fast-mugs-repeat.md @@ -0,0 +1,5 @@ +--- +'@shopify/polaris': patch +--- + +Reduce space between chevron icon and provided `icon` when `Button` is an icon-only `disclosure` diff --git a/polaris-react/src/components/Button/Button.module.css b/polaris-react/src/components/Button/Button.module.css index 6bad52a3504..6f27960273d 100644 --- a/polaris-react/src/components/Button/Button.module.css +++ b/polaris-react/src/components/Button/Button.module.css @@ -328,6 +328,10 @@ justify-content: space-between; } +.disclosure:is(.iconOnly) { + --pc-button-gap: 0; +} + /* LOADING */ .loading { color: transparent; @@ -349,6 +353,10 @@ margin: calc(-1 * var(--p-space-050)) 0; } +.iconOnly > .DisclosureIcon { + margin-left: calc(-1 * var(--p-space-100)); +} + /* SPINNER */ .Spinner { position: absolute; diff --git a/polaris-react/src/components/Button/Button.stories.tsx b/polaris-react/src/components/Button/Button.stories.tsx index 87964863a20..15108d895cf 100644 --- a/polaris-react/src/components/Button/Button.stories.tsx +++ b/polaris-react/src/components/Button/Button.stories.tsx @@ -19,6 +19,8 @@ import { ActionList, } from '@shopify/polaris'; import { + TextColorIcon, + TextFontIcon, PlusIcon, PlusCircleIcon, XSmallIcon, @@ -28,6 +30,9 @@ import { CheckIcon, ClipboardIcon, DeleteIcon, + TextAlignCenterIcon, + TextAlignLeftIcon, + TextAlignRightIcon, } from '@shopify/polaris-icons'; export default { @@ -42,7 +47,7 @@ export const All = { }; return ( /* eslint-disable react/jsx-pascal-case */ - + Default Critical @@ -81,6 +86,10 @@ export const All = { Select disclosure + Icon only disclosure + + Plain only disclosure + Split Disabled state @@ -857,6 +866,225 @@ export const Split = { }, }; +export const IconOnlyDisclosure = { + render() { + const [alignment, setAlignment] = React.useState('left'); + const [active, setActive] = React.useState(false); + + const toggleActive = () => () => { + setActive((active) => !active); + }; + + const updateAlignment = (alignment: string) => () => { + setAlignment(alignment); + setActive(false); + }; + + const options = { + left: { + content: 'Align text left', + icon: TextAlignLeftIcon, + active: alignment === 'left', + onAction: updateAlignment('left'), + }, + center: { + content: 'Align text center', + icon: TextAlignCenterIcon, + active: alignment === 'center', + onAction: updateAlignment('center'), + }, + right: { + content: 'Align text right', + icon: TextAlignRightIcon, + active: alignment === 'right', + onAction: updateAlignment('right'), + }, + }; + + return ( + + } + autofocusTarget="first-node" + onClose={toggleActive()} + > + + + ); + }, +}; + +export const PlainIconOnlyDisclosure = { + render() { + const [fontVariant, setFontVariant] = React.useState('paragraph'); + const [alignment, setAlignment] = React.useState('left'); + const [activeDisclosure, setActiveDisclosure] = React.useState(''); + + const toggleActive = (id: string) => () => { + setActiveDisclosure((activeDisclosure) => + activeDisclosure === id ? '' : id, + ); + }; + + const updateAlignment = (alignment: string) => () => { + setAlignment(alignment); + setActiveDisclosure(''); + }; + + const updateFontVariant = (fontVariant: string) => () => { + setFontVariant(fontVariant); + setActiveDisclosure(''); + }; + + const options = { + magic: { + content: 'Generate description content', + icon: MagicIcon, + disclosure: activeDisclosure === 'magic' ? 'up' : 'down', + onAction: toggleActive('magic'), + items: [], + }, + fontVariant: { + disclosure: activeDisclosure === 'fontVariant' ? 'up' : 'down', + items: [ + { + content: 'Paragraph', + active: fontVariant === 'paragraph', + onAction: updateFontVariant('paragraph'), + }, + { + content: 'Heading 1', + active: fontVariant === 'heading1', + onAction: updateFontVariant('heading1'), + }, + { + content: 'Heading 2', + active: fontVariant === 'heading2', + onAction: updateFontVariant('heading2'), + }, + { + content: 'Heading 3', + active: fontVariant === 'heading3', + onAction: updateFontVariant('heading3'), + }, + { + content: 'Heading 4', + active: fontVariant === 'heading4', + onAction: updateFontVariant('heading4'), + }, + { + content: 'Heading 5', + active: fontVariant === 'heading5', + onAction: updateFontVariant('heading5'), + }, + { + content: 'Heading 6', + active: fontVariant === 'heading6', + onAction: updateFontVariant('heading6'), + }, + { + content: 'Blockquote', + active: fontVariant === 'blockquote', + onAction: updateFontVariant('blockquote'), + }, + ], + }, + textAlignment: { + items: [ + { + content: 'Align text left', + icon: TextAlignLeftIcon, + active: alignment === 'left', + onAction: updateAlignment('left'), + }, + { + content: 'Align text center', + icon: TextAlignCenterIcon, + active: alignment === 'center', + onAction: updateAlignment('center'), + }, + { + content: 'Align text right', + icon: TextAlignRightIcon, + active: alignment === 'right', + onAction: updateAlignment('right'), + }, + ], + }, + color: { + content: 'Change color', + icon: TextColorIcon, + disclosure: activeDisclosure === 'color' ? 'up' : 'down', + onAction: toggleActive('color'), + items: [], + }, + }; + + return ( + + {Object.keys(options).map((key) => { + const {children, content, icon, items, onAction} = options[key]; + const actionList = items ? ( + + ) : null; + + const activeItem = items + ? items.find((item) => item.active) + : undefined; + + const popoverChildren = children ?? actionList; + const iconSource = icon ? icon : activeItem?.icon; + const buttonContent = !iconSource ? activeItem.content : null; + + return popoverChildren ? ( + + {buttonContent} + + } + > + {popoverChildren} + + ) : ( +