Skip to content

Commit

Permalink
feat: Add confirmation to Mac Next Steps card (#1300)
Browse files Browse the repository at this point in the history
* feat: Add confirmation to Mac Next Steps card

* chore: Make the fix better

* fix: Text wrap in nextsteps button.

* chore: Update to use strings for confirm text

* chore: ordered the imports

* fix: remove pause from the test

* chore: set max-width to confirmation p tage

* fix: Confirmation text styling

* chore: Fix local var to a data.js solution

* fix: TS nest
  • Loading branch information
vkraucunas authored Dec 12, 2024
1 parent dc52beb commit 21b31fe
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 9 deletions.
20 changes: 20 additions & 0 deletions special-pages/pages/new-tab/app/components/Icons.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,23 @@ export function Cross() {
</svg>
);
}

export function CheckColor() {
return (
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path fill="#4CBA3C" d="M15.5 8a7.5 7.5 0 1 1-15 0 7.5 7.5 0 0 1 15 0" />
<path
fill="#fff"
fill-rule="evenodd"
d="M11.844 5.137a.5.5 0 0 1 .019.707l-4.5 4.75a.5.5 0 0 1-.733-.008l-2.5-2.75a.5.5 0 0 1 .74-.672l2.138 2.351 4.129-4.359a.5.5 0 0 1 .707-.019"
clip-rule="evenodd"
/>
<path
fill="#288419"
fill-rule="evenodd"
d="M8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8"
clip-rule="evenodd"
/>
</svg>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@
font-size: calc(11 * var(--px-in-rem));
line-height: calc(14 * var(--px-in-rem));
color: var(--ntp-color-primary);
text-wrap: wrap; /* needed for some languages */

/* the active state created an awkward flash, adding transition out */
&.supressActiveStateForSwitchToConfirmationText {
opacity: 1;
transition: opacity .3s ease-out;

&:active {
background-color: var(--color-black-at-6);
opacity: 0;
}
}

&:hover {
background-color: var(--color-black-at-6);
Expand All @@ -73,6 +85,12 @@
}

@media screen and (prefers-color-scheme: dark) {
&.supressActiveStateForSwitchToConfirmationText {
&:active {
background-color: var(--color-black-at-9);
}
}

&:hover:not(:active) {
background-color: var(--color-black-at-9);
}
Expand All @@ -89,6 +107,26 @@
}
}

.confirmation {
display: flex;
align-items: center;
transition: all .2s ease-in;
min-height: 26px;

svg {
height: 1rem;
width: 1rem;
margin-right: var(--sp-2);
}

p {
font-size: calc(11 * var(--px-in-rem));
line-height: calc(14 * var(--px-in-rem));
font-weight: 600;
max-width: 8rem;
}
}

.dismissBtn {
position: absolute;
top: 0.5rem;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { h } from 'preact';
import styles from './NextSteps.module.css';
import cn from 'classnames';

import { useState } from 'preact/hooks';
import { DismissButton } from '../../components/DismissButton';
import { variants } from '../nextsteps.data';
import { CheckColor } from '../../components/Icons';
import { useTypedTranslationWith } from '../../types';
import { variants, additionalCardStates } from '../nextsteps.data';
import styles from './NextSteps.module.css';

/**
* @param {object} props
Expand All @@ -14,14 +18,35 @@ import { useTypedTranslationWith } from '../../types';
export function NextStepsCard({ type, dismiss, action }) {
const { t } = useTypedTranslationWith(/** @type {import("../strings.json")} */ ({}));
const message = variants[type]?.(t);
const [showConfirmation, setShowConfirmation] = useState(false);
const hasConfirmationState = additionalCardStates.hasConfirmationText(message.id);

const handleClick = () => {
if (!hasConfirmationState) {
return action(message.id);
}

action(message.id);
setShowConfirmation(true);
};
return (
<div class={styles.card}>
<img src={`./icons/${message.icon}-128.svg`} alt="" class={styles.icon} />
<h3 class={styles.title}>{message.title}</h3>
<p class={styles.description}>{message.summary}</p>
<button class={styles.btn} onClick={() => action(message.id)}>
{message.actionText}
</button>
{hasConfirmationState && !!showConfirmation ? (
<div class={styles.confirmation}>
<CheckColor />
<p>{message.confirmationText}</p>
</div>
) : (
<button
class={cn(styles.btn, hasConfirmationState && styles.supressActiveStateForSwitchToConfirmationText)}
onClick={handleClick}
>
{message.actionText}
</button>
)}

<DismissButton className={styles.dismissBtn} onClick={() => dismiss(message.id)} />
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { h } from 'preact';
import cn from 'classnames';
import styles from './NextSteps.module.css';
import { useId } from 'preact/hooks';
import { ShowHideButton } from '../../components/ShowHideButton';
import { useTypedTranslationWith } from '../../types';
import { NextStepsCard } from './NextStepsCard';
import { otherText } from '../nextsteps.data';
import { ShowHideButton } from '../../components/ShowHideButton';
import { useId } from 'preact/hooks';
import styles from './NextSteps.module.css';
import { NextStepsCard } from './NextStepsCard';

/**
* @import enStrings from '../strings.json';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,14 @@ test.describe('newtab NextSteps cards', () => {
await page.getByRole('button', { name: 'Try DuckPlayer' }).click();
await ntp.mocks.waitForCallCount({ method: 'nextSteps_action', count: 1 });
});

test('shows a confirmation state', async ({ page }, workerInfo) => {
const ntp = NewtabPage.create(page, workerInfo);
await ntp.reducedMotion();
await ntp.openPage({ nextSteps: ['addAppToDockMac', 'defaultApp'] });
await page.getByRole('button', { name: 'Add to Dock' }).click();

await expect(page.getByText('Added to Dock!')).toBeVisible();
await expect(page.getByRole('button', { name: 'Add to Dock' })).not.toBeVisible();
});
});
8 changes: 8 additions & 0 deletions special-pages/pages/new-tab/app/next-steps/nextsteps.data.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const variants = {
title: t('nextSteps_addAppDockMac_title'),
summary: t('nextSteps_addAppDockMac_summary'),
actionText: t('nextSteps_addAppDockMac_actionText'),
confirmationText: t('nextSteps_addAppDockMac_confirmationText'),
}),
/** @param {(translationId: keyof enStrings) => string} t */
pinAppToTaskbarWindows: (t) => ({
Expand All @@ -69,3 +70,10 @@ export const otherText = {
/** @param {(translationId: keyof enStrings) => string} t */
nextSteps_sectionTitle: (t) => t('nextSteps_sectionTitle'),
};

/** @type {string[]} cardsWithConfirmationText */
const cardsWithConfirmationText = ['addAppToDockMac'];

export const additionalCardStates = {
hasConfirmationText: (/** @type {keyof variants} */ variantId) => cardsWithConfirmationText.includes(variantId),
};

0 comments on commit 21b31fe

Please sign in to comment.