Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BannerCallout: VR Implementation Changes #3804

Merged
merged 14 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/examples/bannercallout/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { BannerCallout, Box, Flex } from 'gestalt';
export default function ResponsiveExample() {
return (
<Flex alignItems="center" height="100%" justifyContent="center" width="100%">
<Box paddingX={8} paddingY={8}>
<Box padding={8} width="100%">
<BannerCallout
dismissButton={{
accessibilityLabel: 'Dismiss this banner',
Expand Down
30 changes: 30 additions & 0 deletions docs/examples/bannercallout/variantDefault.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { BannerCallout, Flex } from 'gestalt';

export default function Example() {
return (
<Flex alignItems="center" height="100%" justifyContent="center" width="100%">
<BannerCallout
dismissButton={{
onDismiss: () => {},
}}
message="Inspiration to build the life you love."
primaryAction={{
accessibilityLabel: 'Log in',
href: 'https://pinterest.com',
label: 'Sign up',
target: 'blank',
role: 'link',
}}
secondaryAction={{
accessibilityLabel: 'Log in',
href: 'https://pinterest.com',
label: 'Log in',
target: 'blank',
role: 'link',
}}
title="Pinterest is the place for inspiration"
type="default"
/>
</Flex>
);
}
36 changes: 13 additions & 23 deletions docs/pages/web/bannercallout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import localizationLabels from '../../examples/bannercallout/localizationLabels'
import main from '../../examples/bannercallout/main';
import placeAtTop from '../../examples/bannercallout/placeAtTop';
import productMessages from '../../examples/bannercallout/productMessages';
import variantDefault from '../../examples/bannercallout/variantDefault';
import variantError from '../../examples/bannercallout/variantError';
import variantInfo from '../../examples/bannercallout/variantInfo';
import variantMessage from '../../examples/bannercallout/variantMessage';
Expand Down Expand Up @@ -146,7 +147,6 @@ export default function DocsPage({ generatedDocGen }: { generatedDocGen: DocGen
code={accessibilityExample}
layout="column"
name="BannerCallout labels"
// hideEditor
/>
}
/>
Expand All @@ -160,19 +160,23 @@ export default function DocsPage({ generatedDocGen }: { generatedDocGen: DocGen
/>

<MainSection name="Variants">
<MainSection.Subsection title="Default">
<MainSection.Card
cardSize="lg"
sandpackExample={
<SandpackExample code={variantDefault} layout="column" name="Variants - Default" />
}
/>
</MainSection.Subsection>

<MainSection.Subsection
description="Info BannerCallouts communicate helpful messages to users about the product. In most cases, they should provide an action for users to take."
title="Info"
>
<MainSection.Card
cardSize="lg"
sandpackExample={
<SandpackExample
code={variantInfo}
layout="column"
name="Variants - Info"
// hideEditor
/>
<SandpackExample code={variantInfo} layout="column" name="Variants - Info" />
}
/>
</MainSection.Subsection>
Expand All @@ -188,7 +192,6 @@ export default function DocsPage({ generatedDocGen }: { generatedDocGen: DocGen
code={variantRecommendation}
layout="column"
name="Variants - Recommendation"
// hideEditor
/>
}
/>
Expand All @@ -200,12 +203,7 @@ export default function DocsPage({ generatedDocGen }: { generatedDocGen: DocGen
<MainSection.Card
cardSize="lg"
sandpackExample={
<SandpackExample
code={variantSuccess}
layout="column"
name="Variants - Success"
// hideEditor
/>
<SandpackExample code={variantSuccess} layout="column" name="Variants - Success" />
}
/>
</MainSection.Subsection>
Expand All @@ -221,7 +219,6 @@ export default function DocsPage({ generatedDocGen }: { generatedDocGen: DocGen
code={variantWarning}
layout="column"
name="Variants - Warning"
// hideEditor
previewHeight={460}
/>
}
Expand All @@ -239,7 +236,6 @@ export default function DocsPage({ generatedDocGen }: { generatedDocGen: DocGen
code={variantError}
layout="column"
name="Variants - Error"
// hideEditor
previewHeight={380}
/>
}
Expand All @@ -262,12 +258,7 @@ export default function DocsPage({ generatedDocGen }: { generatedDocGen: DocGen
<MainSection.Card
cardSize="lg"
sandpackExample={
<SandpackExample
code={actionsExample}
layout="column"
name="BannerCallout actions"
// hideEditor
/>
<SandpackExample code={actionsExample} layout="column" name="BannerCallout actions" />
}
/>
</MainSection.Subsection>
Expand All @@ -289,7 +280,6 @@ export default function DocsPage({ generatedDocGen }: { generatedDocGen: DocGen
code={dismissibleExample}
layout="column"
name="Dismissable BannerCallout"
// hideEditor
/>
}
/>
Expand Down
26 changes: 24 additions & 2 deletions packages/gestalt/src/BannerCallout.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
.dismissButton {
position: absolute;
}

html[dir="rtl"] .rtlPos {
left: 0;
position: absolute;
top: 0;
}

html:not([dir="rtl"]) .rtlPos {
position: absolute;
right: 0;
top: 0;
}

html[dir="rtl"] .smRtlVRPos {
left: var(--sema-space-300);
top: var(--sema-space-500);
}

html:not([dir="rtl"]) .smRtlVRPos {
right: var(--sema-space-300);
top: var(--sema-space-500);
}

html[dir="rtl"] .lgRtlVRPos {
left: var(--sema-space-400);
top: var(--sema-space-400);
}

html:not([dir="rtl"]) .lgRtlVRPos {
right: var(--sema-space-400);
top: var(--sema-space-400);
}
68 changes: 51 additions & 17 deletions packages/gestalt/src/BannerCallout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Children, ComponentProps, ReactElement } from 'react';
import classnames from 'classnames';
import styles from './BannerCallout.css';
import VRBannerCallout from './BannerCallout/VRBannerCallout';
import Box from './Box';
import Button from './Button';
import ButtonLink from './ButtonLink';
Expand All @@ -9,6 +10,7 @@ import Icon from './Icon';
import IconButton from './IconButton';
import MESSAGING_TYPE_ATTRIBUTES from './MESSAGING_TYPE_ATTRIBUTES';
import Text from './Text';
import useInExperiment from './useInExperiment';
import useResponsiveMinWidth from './useResponsiveMinWidth';

export type ActionDataType =
Expand Down Expand Up @@ -98,7 +100,7 @@ type Props = {
/**
* The category of BannerCallout. See [Variants](https://gestalt.pinterest.systems/web/bannercallout#Variants) to learn more.
*/
type: 'error' | 'info' | 'recommendation' | 'success' | 'warning';
type: 'default' | 'error' | 'info' | 'recommendation' | 'success' | 'warning';
/**
* Brief title summarizing BannerCallout. Content should be [localized](https://gestalt.pinterest.systems/web/bannercallout#Localization).
*/
Expand All @@ -108,13 +110,24 @@ type Props = {
function BannerCalloutAction({
data,
stacked,
level,
type,
}: {
data: ActionDataType;
stacked?: boolean;
type: string;
level: string;
type: 'default' | 'error' | 'info' | 'recommendation' | 'success' | 'warning';
}) {
const color = type === 'primary' ? 'white' : 'transparent';
const primaryColor: ComponentProps<typeof Button>['color'] = 'white';

let secondaryColor: 'white' | 'transparent' | 'gray' = 'transparent';

if (type === 'default') {
secondaryColor = 'gray';
}

const color: ComponentProps<typeof Button>['color'] =
level === 'primary' ? primaryColor : secondaryColor;

const { accessibilityLabel, disabled, label } = data;

Expand All @@ -123,7 +136,7 @@ function BannerCalloutAction({
alignItems="center"
display="block"
justifyContent="center"
marginTop={type === 'secondary' && stacked ? 2 : undefined}
marginTop={level === 'secondary' && stacked ? 2 : undefined}
paddingX={1}
smDisplay="flex"
smMarginBottom="auto"
Expand Down Expand Up @@ -183,6 +196,11 @@ export default function BannerCallout({
iconAccessibilityLabelWarning,
} = useDefaultLabelContext('BannerCallout');

const isInVRExperiment = useInExperiment({
webExperimentName: 'web_gestalt_visualRefresh',
mwebExperimentName: 'web_gestalt_visualRefresh',
});

const getDefaultIconAccessibilityLabel = () => {
switch (type) {
case 'success':
Expand All @@ -200,13 +218,28 @@ export default function BannerCallout({
}
};

if (isInVRExperiment) {
return (
<VRBannerCallout
dismissButton={dismissButton}
iconAccessibilityLabel={iconAccessibilityLabel}
message={message}
primaryAction={primaryAction}
secondaryAction={secondaryAction}
title={title}
type={type}
/>
);
}

return (
<Box
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type '"selected" | "default" | "shopping" | "inverse" | "light" | "dark" | "darkWash" | "lightWash" | "transparent" | "transparentDarkGray" | "infoBase" | "infoWeak" | "errorBase" | ... 15 more ... | undefined'.
color={MESSAGING_TYPE_ATTRIBUTES[type].backgroundColor}
borderStyle={type === 'default' ? 'sm' : undefined}
color={MESSAGING_TYPE_ATTRIBUTES[type]?.backgroundColor}
direction="column"
display="flex"
padding={6}
paddingX={6}
paddingY={6}
position="relative"
rounding={4}
smDirection="row"
Expand All @@ -226,10 +259,8 @@ export default function BannerCallout({
<Box marginBottom={4} marginTop={0} smMarginBottom="auto" smMarginTop="auto">
<Icon
accessibilityLabel={iconAccessibilityLabel ?? getDefaultIconAccessibilityLabel()}
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'IconColor | undefined'.
color={MESSAGING_TYPE_ATTRIBUTES[type].iconColor}
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type '"replace" | "search" | "link" | "text" | "dash" | "3D" | "3D-move" | "360" | "accessibility" | "ad" | "ad-group" | "add" | "add-circle" | "add-layout" | "add-pin" | "add-section" | ... 318 more ... | undefined'.
icon={MESSAGING_TYPE_ATTRIBUTES[type].icon}
color={MESSAGING_TYPE_ATTRIBUTES[type]?.iconColor}
icon={MESSAGING_TYPE_ATTRIBUTES[type]?.icon}
size={32}
/>
</Box>
Expand All @@ -253,9 +284,9 @@ export default function BannerCallout({
</Text>
</Box>
)}
{typeof message === 'string' ? (
{typeof message === 'string' && (
<Text align={responsiveMinWidth === 'xs' ? 'center' : undefined}>{message}</Text>
) : null}
)}
{typeof message !== 'string' &&
// @ts-expect-error - TS2339
Children.only<ReactElement>(message).type.displayName === 'Text'
Expand All @@ -267,21 +298,24 @@ export default function BannerCallout({
{(primaryAction || secondaryAction) && (
<Box marginStart="auto" smDisplay="flex" smMarginEnd={4} smPaddingY={3}>
{secondaryAction && responsiveMinWidth !== 'xs' && (
<BannerCalloutAction data={secondaryAction} type="secondary" />
<BannerCalloutAction data={secondaryAction} level="secondary" type={type} />
)}
{primaryAction && (
<BannerCalloutAction data={primaryAction} level="primary" type={type} />
)}
{primaryAction && <BannerCalloutAction data={primaryAction} type="primary" />}
{secondaryAction && responsiveMinWidth === 'xs' && (
<BannerCalloutAction
data={secondaryAction}
level="secondary"
stacked={!!secondaryAction}
type="secondary"
type={type}
/>
)}
</Box>
)}
</Box>
{dismissButton && (
<div className={classnames(styles.rtlPos)}>
<div className={classnames(styles.dismissButton, styles.rtlPos)}>
<IconButton
accessibilityLabel={dismissButton.accessibilityLabel ?? accessibilityDismissButtonLabel}
icon="cancel"
Expand Down
33 changes: 33 additions & 0 deletions packages/gestalt/src/BannerCallout/DismissButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import classnames from 'classnames';
import styles from '../BannerCallout.css';
import { useDefaultLabelContext } from '../contexts/DefaultLabelProvider';
import IconButton from '../IconButton';

type Props = {
size?: 'sm' | 'lg';
dismissButton?: {
accessibilityLabel?: string;
onDismiss: () => void;
};
};

export default function DismissButton({ dismissButton, size = 'lg' }: Props) {
const { accessibilityDismissButtonLabel } = useDefaultLabelContext('BannerCallout');

return (
<div
className={classnames(
styles.dismissButton,
size === 'lg' ? styles.lgRtlVRPos : styles.smRtlVRPos,
)}
>
<IconButton
accessibilityLabel={dismissButton?.accessibilityLabel ?? accessibilityDismissButtonLabel}
icon="cancel"
iconColor="darkGray"
onClick={dismissButton?.onDismiss}
size="sm"
/>
</div>
);
}
Loading
Loading