diff --git a/.changeset/healthy-apricots-rule.md b/.changeset/healthy-apricots-rule.md new file mode 100644 index 00000000000..4a9135dba7d --- /dev/null +++ b/.changeset/healthy-apricots-rule.md @@ -0,0 +1,5 @@ +--- +'@shopify/polaris': minor +--- + +Updated `Banner` component to use new layout primitives diff --git a/.changeset/pink-apricots-help.md b/.changeset/pink-apricots-help.md new file mode 100644 index 00000000000..e58b098d36a --- /dev/null +++ b/.changeset/pink-apricots-help.md @@ -0,0 +1,5 @@ +--- +'@shopify/polaris': minor +--- + +Refactored `AccountConnection` to use new layout primitives diff --git a/polaris-react/src/components/AccountConnection/AccountConnection.scss b/polaris-react/src/components/AccountConnection/AccountConnection.scss deleted file mode 100644 index 2d95d597e42..00000000000 --- a/polaris-react/src/components/AccountConnection/AccountConnection.scss +++ /dev/null @@ -1,10 +0,0 @@ -.TermsOfService { - margin-top: var(--p-space-5); -} - -.Content { - // stylelint-disable-next-line selector-max-combinators - > * + * { - margin-top: var(--p-space-2); - } -} diff --git a/polaris-react/src/components/AccountConnection/AccountConnection.tsx b/polaris-react/src/components/AccountConnection/AccountConnection.tsx index 0810bb83c14..19933ddee88 100644 --- a/polaris-react/src/components/AccountConnection/AccountConnection.tsx +++ b/polaris-react/src/components/AccountConnection/AccountConnection.tsx @@ -3,12 +3,12 @@ import React from 'react'; import type {Action} from '../../types'; import {Avatar} from '../Avatar'; import {buttonFrom} from '../Button'; -import {Card} from '../Card'; -import {Stack} from '../Stack'; -import {TextStyle} from '../TextStyle'; import {SettingAction} from '../SettingAction'; - -import styles from './AccountConnection.scss'; +import {AlphaCard} from '../AlphaCard'; +import {Box} from '../Box'; +import {Inline} from '../Inline'; +import {Text} from '../Text'; +import {AlphaStack} from '../AlphaStack'; export interface AccountConnectionProps { /** Content to display as title */ @@ -54,19 +54,19 @@ export function AccountConnection({ let titleMarkup: React.ReactNode = null; if (title) { - titleMarkup =
{title}
; + titleMarkup = <>{title}; } else if (accountName) { - titleMarkup =
{accountName}
; + titleMarkup = <>{accountName}; } const detailsMarkup = details ? ( -
- {details} -
+ + {details} + ) : null; const termsOfServiceMarkup = termsOfService ? ( -
{termsOfService}
+ {termsOfService} ) : null; const actionElement = action @@ -74,19 +74,17 @@ export function AccountConnection({ : null; return ( - + - + {avatarMarkup} - -
- {titleMarkup} - {detailsMarkup} -
-
-
+ + {titleMarkup} + {detailsMarkup} + +
{termsOfServiceMarkup} -
+ ); } diff --git a/polaris-react/src/components/AccountConnection/tests/AccountConnection.test.tsx b/polaris-react/src/components/AccountConnection/tests/AccountConnection.test.tsx index 3258a5c60ad..aac5109963c 100644 --- a/polaris-react/src/components/AccountConnection/tests/AccountConnection.test.tsx +++ b/polaris-react/src/components/AccountConnection/tests/AccountConnection.test.tsx @@ -1,11 +1,20 @@ import React from 'react'; import {mountWithApp} from 'tests/utilities'; +import {matchMedia} from '@shopify/jest-dom-mocks'; import {Avatar} from '../../Avatar'; import {Button} from '../../Button'; import {AccountConnection} from '../AccountConnection'; describe('', () => { + beforeEach(() => { + matchMedia.mock(); + }); + + afterEach(() => { + matchMedia.restore(); + }); + describe('title', () => { it('shows the title when one is provided', () => { const title = 'Example app'; diff --git a/polaris-react/src/components/Banner/Banner.scss b/polaris-react/src/components/Banner/Banner.scss index f3054443264..427fc7f479c 100644 --- a/polaris-react/src/components/Banner/Banner.scss +++ b/polaris-react/src/components/Banner/Banner.scss @@ -54,8 +54,8 @@ position: relative; display: flex; - // stylelint-disable selector-max-class, selector-max-combinators, selector-max-specificity - &.statusCritical .PrimaryAction .Button { + // stylelint-disable selector-max-class, selector-max-specificity + &.statusCritical .PrimaryAction.Button { border-color: var(--p-border-critical-subdued); background: var(--p-surface-critical-subdued); @@ -75,7 +75,7 @@ } } - &.statusWarning .PrimaryAction .Button { + &.statusWarning .PrimaryAction.Button { border-color: var(--p-border-warning-subdued); background: var(--p-surface-warning-subdued); @@ -95,7 +95,7 @@ } } - &.statusInfo .PrimaryAction .Button { + &.statusInfo .PrimaryAction.Button { border-color: var(--p-border-highlight-subdued); background: var(--p-surface-highlight-subdued); @@ -115,7 +115,7 @@ } } - &.statusSuccess .PrimaryAction .Button { + &.statusSuccess .PrimaryAction.Button { border-color: var(--p-border-success-subdued); background: var(--p-surface-success-subdued); @@ -134,12 +134,7 @@ background: var(--p-surface-success-subdued); } } - // stylelint-enable selector-max-class, selector-max-combinators, selector-max-specificity -} - -.ContentWrapper { - margin-top: calc(-1 * var(--p-space-05)); - flex: 1 1 auto; + // stylelint-enable selector-max-class, selector-max-specificity } .withinContentContainer { @@ -151,19 +146,11 @@ position: absolute; } - .Ribbon { - padding-right: var(--p-space-4); - } - @include banner-variants($in-page: false); + .Banner { margin-top: var(--p-space-2); } - - .Actions { - padding: var(--p-space-3) 0 var(--p-space-1) 0; - } } .withinPage { @@ -180,10 +167,6 @@ padding-right: var(--p-space-4); } - .Actions { - padding-top: var(--p-space-4); - } - .Dismiss { right: var(--p-space-4); top: var(--p-space-5); @@ -195,23 +178,6 @@ padding-right: calc(var(--p-space-8) + var(--p-icon-size-small)); } -.Heading { - word-break: break-word; -} - -.Content { - @include text-breakword; - padding: var(--p-space-05) 0; -} - -.Ribbon { - flex: 0 0 var(--p-space-8); -} - -.PrimaryAction { - margin-right: var(--p-space-2); -} - // We need pretty high specificity to do the descendant selectors // onto the text, which needs to be the relative positioned wrapper // so that the borders/ backgrounds do not extend outside of it. diff --git a/polaris-react/src/components/Banner/Banner.tsx b/polaris-react/src/components/Banner/Banner.tsx index eb3dc1875d2..5a794b91923 100644 --- a/polaris-react/src/components/Banner/Banner.tsx +++ b/polaris-react/src/components/Banner/Banner.tsx @@ -15,17 +15,18 @@ import { import {classNames, variationName} from '../../utilities/css'; import {BannerContext} from '../../utilities/banner-context'; -import {useUniqueId} from '../../utilities/unique-id'; import {useI18n} from '../../utilities/i18n'; import type {Action, DisableableAction, LoadableAction} from '../../types'; import {Button} from '../Button'; -import {Heading} from '../Heading'; import {ButtonGroup} from '../ButtonGroup'; import {UnstyledButton, unstyledButtonFrom} from '../UnstyledButton'; import {UnstyledLink} from '../UnstyledLink'; import {Spinner} from '../Spinner'; import {Icon, IconProps} from '../Icon'; import {WithinContentContext} from '../../utilities/within-content-context'; +import {Text} from '../Text'; +import {Box} from '../Box'; +import {Bleed} from '../Bleed'; import styles from './Banner.scss'; @@ -64,7 +65,6 @@ export const Banner = forwardRef(function Banner( bannerRef, ) { const withinContentContainer = useContext(WithinContentContext); - const id = useUniqueId('Banner'); const i18n = useI18n(); const {wrapperRef, handleKeyUp, handleBlur, handleMouseUp, shouldShowFocus} = useBannerFocus(bannerRef); @@ -79,14 +79,12 @@ export const Banner = forwardRef(function Banner( ); let headingMarkup: React.ReactNode = null; - let headingID: string | undefined; if (title) { - headingID = `${id}Heading`; headingMarkup = ( -
- {title} -
+ + {title} + ); } @@ -109,13 +107,13 @@ export const Banner = forwardRef(function Banner( ) : null; const primaryActionMarkup = action ? ( -
+ {action.loading ? spinnerMarkup : unstyledButtonFrom(action, { - className: styles.Button, + className: `${styles.Button} ${styles.PrimaryAction}`, })} -
+ ) : null; const secondaryActionMarkup = secondaryAction ? ( @@ -124,24 +122,25 @@ export const Banner = forwardRef(function Banner( const actionMarkup = action || secondaryAction ? ( -
+ {primaryActionMarkup} {secondaryActionMarkup} -
+ ) : null; let contentMarkup: React.ReactNode = null; - let contentID: string | undefined; if (children || actionMarkup) { - contentID = `${id}Content`; contentMarkup = ( -
+ {children} {actionMarkup} -
+ ); } @@ -168,19 +167,17 @@ export const Banner = forwardRef(function Banner( onMouseUp={handleMouseUp} onKeyUp={handleKeyUp} onBlur={handleBlur} - aria-labelledby={headingID} - aria-describedby={contentID} > {dismissButton} -
+ -
+ -
+ {headingMarkup} {contentMarkup} -
+ ); diff --git a/polaris-react/src/components/Banner/tests/Banner.test.tsx b/polaris-react/src/components/Banner/tests/Banner.test.tsx index f6cf3e3042b..4de1228e953 100644 --- a/polaris-react/src/components/Banner/tests/Banner.test.tsx +++ b/polaris-react/src/components/Banner/tests/Banner.test.tsx @@ -9,7 +9,7 @@ import { import {mountWithApp} from 'tests/utilities'; import {Button} from '../../Button'; -import {Heading} from '../../Heading'; +import {Text} from '../../Text'; import {Icon} from '../../Icon'; import {Spinner} from '../../Spinner'; import {UnstyledButton} from '../../UnstyledButton'; @@ -21,12 +21,12 @@ import {Banner, BannerHandles} from '../Banner'; describe('', () => { it('renders a title', () => { const banner = mountWithApp(); - expect(banner.find(Heading)).toContainReactText('Banner title'); + expect(banner.find(Text)).toContainReactText('Banner title'); }); - it('passes a p element to Heading', () => { + it('passes an h2 element to Heading', () => { const banner = mountWithApp(); - expect(banner).toContainReactComponent(Heading, {element: 'p'}); + expect(banner).toContainReactComponent(Text, {as: 'h2'}); }); it('passes the provided icon source to Icon', () => {