@automattic/launchpad 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/action-components/index.js +2 -1
- package/dist/cjs/action-components/index.js.map +1 -1
- package/dist/cjs/action-components/share-site-modal/index.js +132 -21
- package/dist/cjs/action-components/share-site-modal/index.js.map +1 -1
- package/dist/cjs/action-components/share-site-modal/style.scss +23 -116
- package/dist/cjs/checklist/index.js +11 -3
- package/dist/cjs/checklist/index.js.map +1 -1
- package/dist/cjs/checklist-item/index.js +25 -4
- package/dist/cjs/checklist-item/index.js.map +1 -1
- package/dist/cjs/checklist-item/index.stories.js +2 -5
- package/dist/cjs/checklist-item/index.stories.js.map +1 -1
- package/dist/cjs/checklist-item/style.scss +14 -29
- package/dist/cjs/launchpad-internal.js +2 -2
- package/dist/cjs/launchpad-internal.js.map +1 -1
- package/dist/cjs/launchpad-internal.stories.js +1 -1
- package/dist/cjs/launchpad-internal.stories.js.map +1 -1
- package/dist/cjs/launchpad.js +7 -5
- package/dist/cjs/launchpad.js.map +1 -1
- package/dist/cjs/msw/resolver.js +1 -7
- package/dist/cjs/msw/resolver.js.map +1 -1
- package/dist/cjs/msw/setup-free.js +1 -1
- package/dist/cjs/msw/setup-free.js.map +1 -1
- package/dist/cjs/setup-actions.js +4 -9
- package/dist/cjs/setup-actions.js.map +1 -1
- package/dist/cjs/use-tracking/index.js +4 -0
- package/dist/cjs/use-tracking/index.js.map +1 -1
- package/dist/esm/action-components/share-site-modal/index.js +137 -26
- package/dist/esm/action-components/share-site-modal/index.js.map +1 -1
- package/dist/esm/action-components/share-site-modal/style.scss +23 -116
- package/dist/esm/checklist/index.js +11 -3
- package/dist/esm/checklist/index.js.map +1 -1
- package/dist/esm/checklist-item/index.js +28 -7
- package/dist/esm/checklist-item/index.js.map +1 -1
- package/dist/esm/checklist-item/index.stories.js +3 -6
- package/dist/esm/checklist-item/index.stories.js.map +1 -1
- package/dist/esm/checklist-item/style.scss +14 -29
- package/dist/esm/launchpad-internal.js +2 -2
- package/dist/esm/launchpad-internal.js.map +1 -1
- package/dist/esm/launchpad-internal.stories.js +1 -1
- package/dist/esm/launchpad-internal.stories.js.map +1 -1
- package/dist/esm/launchpad.js +9 -7
- package/dist/esm/launchpad.js.map +1 -1
- package/dist/esm/msw/resolver.js +1 -7
- package/dist/esm/msw/resolver.js.map +1 -1
- package/dist/esm/msw/setup-free.js +1 -1
- package/dist/esm/msw/setup-free.js.map +1 -1
- package/dist/esm/setup-actions.js +4 -9
- package/dist/esm/setup-actions.js.map +1 -1
- package/dist/esm/use-tracking/index.js +4 -0
- package/dist/esm/use-tracking/index.js.map +1 -1
- package/dist/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/action-components/share-site-modal/index.d.ts +3 -1
- package/dist/types/action-components/share-site-modal/index.d.ts.map +1 -1
- package/dist/types/checklist/index.d.ts +1 -0
- package/dist/types/checklist/index.d.ts.map +1 -1
- package/dist/types/checklist-item/index.d.ts +1 -0
- package/dist/types/checklist-item/index.d.ts.map +1 -1
- package/dist/types/checklist-item/index.stories.d.ts.map +1 -1
- package/dist/types/launchpad-internal.d.ts +1 -0
- package/dist/types/launchpad-internal.d.ts.map +1 -1
- package/dist/types/launchpad.d.ts +2 -1
- package/dist/types/launchpad.d.ts.map +1 -1
- package/dist/types/msw/resolver.d.ts.map +1 -1
- package/dist/types/setup-actions.d.ts.map +1 -1
- package/dist/types/types.d.ts +1 -7
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/use-tracking/index.d.ts.map +1 -1
- package/package.json +29 -23
- package/src/action-components/share-site-modal/index.tsx +239 -76
- package/src/action-components/share-site-modal/style.scss +23 -116
- package/src/checklist/index.tsx +15 -3
- package/src/checklist/test/test-checklist.tsx +38 -0
- package/src/checklist-item/index.stories.tsx +11 -5
- package/src/checklist-item/index.tsx +55 -29
- package/src/checklist-item/style.scss +14 -29
- package/src/checklist-item/test/index.tsx +1 -20
- package/src/launchpad-internal.stories.tsx +1 -1
- package/src/launchpad-internal.tsx +6 -1
- package/src/launchpad.tsx +15 -7
- package/src/msw/resolver.ts +1 -10
- package/src/msw/setup-free.ts +1 -1
- package/src/setup-actions.ts +4 -9
- package/src/test/launchpad.tsx +1 -1
- package/src/test/lib/fixtures.ts +7 -7
- package/src/types.ts +1 -8
- package/src/use-tracking/index.tsx +4 -0
- package/dist/cjs/badge/index.js +0 -13
- package/dist/cjs/badge/index.js.map +0 -1
- package/dist/cjs/badge/style.scss +0 -50
- package/dist/cjs/msw/link-in-bio.js +0 -68
- package/dist/cjs/msw/link-in-bio.js.map +0 -1
- package/dist/esm/badge/index.js +0 -10
- package/dist/esm/badge/index.js.map +0 -1
- package/dist/esm/badge/style.scss +0 -50
- package/dist/esm/msw/link-in-bio.js +0 -66
- package/dist/esm/msw/link-in-bio.js.map +0 -1
- package/dist/types/badge/index.d.ts +0 -10
- package/dist/types/badge/index.d.ts.map +0 -1
- package/dist/types/msw/link-in-bio.d.ts +0 -35
- package/dist/types/msw/link-in-bio.d.ts.map +0 -1
- package/src/badge/index.tsx +0 -25
- package/src/badge/style.scss +0 -50
- package/src/msw/link-in-bio.ts +0 -66
- package/src/test/badge.tsx +0 -50
|
@@ -3,138 +3,45 @@
|
|
|
3
3
|
.share-site-modal__modal {
|
|
4
4
|
max-width: 640px;
|
|
5
5
|
|
|
6
|
-
.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
.components-modal__content {
|
|
11
|
-
margin: 0;
|
|
12
|
-
padding: 0;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.share-site-modal__modal-content {
|
|
16
|
-
padding: 48px;
|
|
17
|
-
padding-bottom: 40px;
|
|
18
|
-
display: flex;
|
|
19
|
-
flex-direction: column;
|
|
20
|
-
gap: 32px;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.share-site-modal__modal-heading {
|
|
24
|
-
color: var(--studio-gray-100);
|
|
25
|
-
font-family: Recoleta, "Noto Serif", Georgia, "Times New Roman", Times, serif;
|
|
26
|
-
font-size: 2rem;
|
|
27
|
-
line-height: 40px;
|
|
28
|
-
font-weight: 400;
|
|
29
|
-
letter-spacing: 0.2px;
|
|
30
|
-
margin: 0;
|
|
31
|
-
padding-bottom: 8px;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.share-site-modal__modal-domain {
|
|
35
|
-
display: flex;
|
|
36
|
-
justify-content: center;
|
|
37
|
-
align-items: center;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.share-site-modal__modal-body,
|
|
41
|
-
.share-site-modal__modal-domain-text {
|
|
42
|
-
margin: 0;
|
|
43
|
-
color: var(--studio-gray-80);
|
|
44
|
-
font-size: 1rem;
|
|
45
|
-
line-height: 24px;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.share-site-modal__modal-domain-text {
|
|
49
|
-
padding: 0 8px;
|
|
50
|
-
|
|
51
|
-
// prevent text overflow
|
|
52
|
-
text-overflow: ellipsis;
|
|
53
|
-
white-space: nowrap;
|
|
54
|
-
overflow: hidden;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.share-site-modal__modal-buttons {
|
|
58
|
-
display: flex;
|
|
59
|
-
flex-direction: row;
|
|
60
|
-
justify-content: end;
|
|
61
|
-
gap: 16px;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
.share-site-modal__modal-site {
|
|
65
|
-
padding: 8px;
|
|
66
|
-
background: var(--studio-gray-0);
|
|
67
|
-
display: flex;
|
|
68
|
-
flex-direction: row;
|
|
69
|
-
justify-content: space-between;
|
|
70
|
-
align-items: center;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
.launchpad__clipboard-button {
|
|
74
|
-
opacity: 0;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.launchpad__clipboard-button:focus {
|
|
78
|
-
opacity: 1;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.share-site-modal__modal-site:hover {
|
|
82
|
-
.launchpad__clipboard-button {
|
|
83
|
-
opacity: 1;
|
|
6
|
+
.share-site-modal__modal-input-container {
|
|
7
|
+
input {
|
|
8
|
+
/* Required to tame the WordPress component's outrageously specific font size */
|
|
9
|
+
font-size: $font-body !important;
|
|
84
10
|
}
|
|
85
11
|
}
|
|
86
12
|
|
|
87
|
-
.share-site-modal__modal-
|
|
88
|
-
|
|
89
|
-
font-size: 0.875rem;
|
|
90
|
-
display: inline-flex;
|
|
91
|
-
flex-direction: row;
|
|
92
|
-
justify-content: start;
|
|
93
|
-
gap: 6px;
|
|
94
|
-
padding: 0;
|
|
13
|
+
.share-site-modal__modal-social {
|
|
14
|
+
flex-wrap: wrap;
|
|
95
15
|
margin: 0;
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.share-site-modal__modal-upsell {
|
|
100
|
-
border-top: 1px solid var(--studio-gray-5);
|
|
101
|
-
background: var(--studio-gray-0);
|
|
102
|
-
display: flex;
|
|
103
|
-
justify-content: center;
|
|
104
|
-
align-items: center;
|
|
105
|
-
padding: 32px 48px;
|
|
106
|
-
gap: 32px;
|
|
107
|
-
|
|
108
|
-
.components-button {
|
|
109
|
-
height: 42px;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.share-site-modal__modal-upsell-content p {
|
|
114
|
-
margin-bottom: 0;
|
|
16
|
+
list-style: none;
|
|
115
17
|
}
|
|
116
18
|
|
|
117
|
-
.share-site-modal__modal-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
.share-site-modal__modal-view-site {
|
|
122
|
-
display: flex;
|
|
19
|
+
.share-site-modal__modal-copy-link,
|
|
20
|
+
.share-site-modal__modal-share-link {
|
|
123
21
|
gap: 4px;
|
|
124
|
-
|
|
22
|
+
display: inline-flex;
|
|
23
|
+
align-items: center;
|
|
125
24
|
font-weight: 500;
|
|
126
|
-
|
|
127
|
-
font-size:
|
|
25
|
+
padding: 4px 8px;
|
|
26
|
+
font-size: $font-body-small;
|
|
128
27
|
line-height: 20px;
|
|
129
28
|
letter-spacing: -0.154px;
|
|
130
29
|
color: #101517;
|
|
30
|
+
.share-site-modal__modal-icon {
|
|
31
|
+
border-radius: 100%;
|
|
32
|
+
padding: 4px;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.share-site-modal__modal-copy-link:disabled {
|
|
37
|
+
opacity: 0.5;
|
|
131
38
|
}
|
|
132
39
|
|
|
133
|
-
.share-site-modal__modal-
|
|
40
|
+
.share-site-modal__modal-share-link:visited {
|
|
134
41
|
color: #101517;
|
|
135
42
|
}
|
|
136
43
|
|
|
137
|
-
.share-site-modal__modal-
|
|
44
|
+
.share-site-modal__modal-share-link:hover:not(:disabled) {
|
|
138
45
|
text-decoration: underline;
|
|
139
46
|
}
|
|
140
47
|
}
|
package/src/checklist/index.tsx
CHANGED
|
@@ -5,13 +5,15 @@ import './style.scss';
|
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
7
|
makeLastTaskPrimaryAction?: boolean;
|
|
8
|
+
highlightNextAction?: boolean;
|
|
8
9
|
children?:
|
|
9
10
|
| ReactElement< ComponentProps< typeof ChecklistItem > >
|
|
10
11
|
| ReactElement< ComponentProps< typeof ChecklistItem > >[];
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
const Checklist: FC< Props > = ( { children, makeLastTaskPrimaryAction } ) => {
|
|
14
|
+
const Checklist: FC< Props > = ( { children, makeLastTaskPrimaryAction, highlightNextAction } ) => {
|
|
14
15
|
const lastChildIndex = Children.count( children ) - 1;
|
|
16
|
+
let hasHighlightedItem = false;
|
|
15
17
|
|
|
16
18
|
return (
|
|
17
19
|
<ul
|
|
@@ -21,8 +23,18 @@ const Checklist: FC< Props > = ( { children, makeLastTaskPrimaryAction } ) => {
|
|
|
21
23
|
aria-label="Launchpad Checklist"
|
|
22
24
|
>
|
|
23
25
|
{ Children.map( children || [], ( child, index ) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
const shouldHighlightItem =
|
|
27
|
+
highlightNextAction && ! hasHighlightedItem && child.props.task.completed === false;
|
|
28
|
+
|
|
29
|
+
if ( shouldHighlightItem ) {
|
|
30
|
+
hasHighlightedItem = true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if ( index === lastChildIndex || shouldHighlightItem ) {
|
|
34
|
+
return cloneElement( child, {
|
|
35
|
+
isPrimaryAction: makeLastTaskPrimaryAction,
|
|
36
|
+
isHighlighted: shouldHighlightItem,
|
|
37
|
+
} );
|
|
26
38
|
}
|
|
27
39
|
return child;
|
|
28
40
|
} ) }
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import Checklist from '..';
|
|
4
|
+
import ChecklistItem from '../../checklist-item';
|
|
5
|
+
|
|
6
|
+
describe( 'Checklist', () => {
|
|
7
|
+
const createTask = ( id: string, completed = false ) => ( {
|
|
8
|
+
id,
|
|
9
|
+
title: `Task ${ id }`,
|
|
10
|
+
completed,
|
|
11
|
+
onClick: jest.fn(),
|
|
12
|
+
disabled: false,
|
|
13
|
+
} );
|
|
14
|
+
|
|
15
|
+
it( 'highlights the first incomplete task when highlightNextAction is true', () => {
|
|
16
|
+
const tasks = [
|
|
17
|
+
createTask( '1', true ), // completed
|
|
18
|
+
createTask( '2', false ), // should be highlighted
|
|
19
|
+
createTask( '3', false ), // should not be highlighted
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
render(
|
|
23
|
+
<Checklist highlightNextAction>
|
|
24
|
+
{ tasks.map( ( task ) => (
|
|
25
|
+
<ChecklistItem key={ task.id } task={ task } />
|
|
26
|
+
) ) }
|
|
27
|
+
</Checklist>
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
// Get all checklist items
|
|
31
|
+
const items = screen.getAllByRole( 'listitem' );
|
|
32
|
+
|
|
33
|
+
// Second task should have the highlighted class
|
|
34
|
+
expect( items[ 1 ] ).toHaveClass( 'highlighted' );
|
|
35
|
+
// Third task should not be highlighted
|
|
36
|
+
expect( items[ 2 ] ).not.toHaveClass( 'highlighted' );
|
|
37
|
+
} );
|
|
38
|
+
} );
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Button } from '@wordpress/components';
|
|
1
2
|
import ChecklistItem from './';
|
|
2
3
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
4
|
|
|
@@ -79,12 +80,17 @@ export const ExpandedWithAction: Story = {
|
|
|
79
80
|
args: {
|
|
80
81
|
task: baseTask,
|
|
81
82
|
expandable: {
|
|
82
|
-
content:
|
|
83
|
+
content: (
|
|
84
|
+
<>
|
|
85
|
+
<p>This is the expanded content.</p>
|
|
86
|
+
<div>
|
|
87
|
+
<Button variant="primary" onClick={ () => {} }>
|
|
88
|
+
Action
|
|
89
|
+
</Button>
|
|
90
|
+
</div>
|
|
91
|
+
</>
|
|
92
|
+
),
|
|
83
93
|
isOpen: true,
|
|
84
|
-
action: {
|
|
85
|
-
label: 'Next',
|
|
86
|
-
onClick: () => {},
|
|
87
|
-
},
|
|
88
94
|
},
|
|
89
95
|
},
|
|
90
96
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Badge
|
|
2
|
-
import { Button } from '@wordpress/components';
|
|
3
|
-
import { __, isRTL } from '@wordpress/i18n';
|
|
1
|
+
import { Badge } from '@automattic/components';
|
|
2
|
+
import { Button, Icon } from '@wordpress/components';
|
|
3
|
+
import { __, isRTL, sprintf } from '@wordpress/i18n';
|
|
4
|
+
import { check, chevronLeft, chevronRight } from '@wordpress/icons';
|
|
4
5
|
import clsx from 'clsx';
|
|
5
6
|
import type { Task, Expandable } from '../types';
|
|
6
7
|
import type { FC, Key } from 'react';
|
|
@@ -11,11 +12,18 @@ interface Props {
|
|
|
11
12
|
key?: Key;
|
|
12
13
|
task: Task;
|
|
13
14
|
isPrimaryAction?: boolean;
|
|
15
|
+
isHighlighted?: boolean;
|
|
14
16
|
expandable?: Expandable;
|
|
15
17
|
onClick?: () => void;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
const ChecklistItem: FC< Props > = ( {
|
|
20
|
+
const ChecklistItem: FC< Props > = ( {
|
|
21
|
+
task,
|
|
22
|
+
isPrimaryAction,
|
|
23
|
+
isHighlighted,
|
|
24
|
+
expandable,
|
|
25
|
+
onClick,
|
|
26
|
+
} ) => {
|
|
19
27
|
const { id, completed, disabled = false, title, subtitle, actionDispatch } = task;
|
|
20
28
|
|
|
21
29
|
// If the task says we should use the Calypso path, ensure we use that link for the button's href.
|
|
@@ -48,6 +56,29 @@ const ChecklistItem: FC< Props > = ( { task, isPrimaryAction, expandable, onClic
|
|
|
48
56
|
const buttonClassName = isClickable ? '' : 'components-button';
|
|
49
57
|
const ButtonElement = isClickable ? Button : 'div';
|
|
50
58
|
|
|
59
|
+
const getStatusText = () => {
|
|
60
|
+
const taskTitle = typeof title === 'string' ? title : String( title );
|
|
61
|
+
|
|
62
|
+
if ( completed ) {
|
|
63
|
+
/* translators: %s: Task title */
|
|
64
|
+
return sprintf( __( 'Completed: %s', 'launchpad' ), taskTitle );
|
|
65
|
+
}
|
|
66
|
+
if ( disabled ) {
|
|
67
|
+
/* translators: %s: Task title */
|
|
68
|
+
return sprintf( __( 'Not available yet: %s', 'launchpad' ), taskTitle );
|
|
69
|
+
}
|
|
70
|
+
if ( isClickable ) {
|
|
71
|
+
if ( isPrimaryAction ) {
|
|
72
|
+
/* translators: %s: Task title */
|
|
73
|
+
return sprintf( __( 'Start task: %s', 'launchpad' ), taskTitle );
|
|
74
|
+
}
|
|
75
|
+
/* translators: %s: Task title in lowercase */
|
|
76
|
+
return sprintf( __( 'Select to %s', 'launchpad' ), taskTitle.toLowerCase() );
|
|
77
|
+
}
|
|
78
|
+
/* translators: %s: Task title */
|
|
79
|
+
return sprintf( __( 'To do: %s', 'launchpad' ), taskTitle );
|
|
80
|
+
};
|
|
81
|
+
|
|
51
82
|
return (
|
|
52
83
|
<li
|
|
53
84
|
className={ clsx( 'checklist-item__task', {
|
|
@@ -56,16 +87,20 @@ const ChecklistItem: FC< Props > = ( { task, isPrimaryAction, expandable, onClic
|
|
|
56
87
|
enabled: ! disabled,
|
|
57
88
|
disabled: disabled,
|
|
58
89
|
expanded: expandable && expandable.isOpen,
|
|
90
|
+
highlighted: isHighlighted,
|
|
59
91
|
} ) }
|
|
92
|
+
aria-current={ isHighlighted ? 'step' : undefined }
|
|
60
93
|
>
|
|
61
94
|
{ isPrimaryAction ? (
|
|
62
95
|
<ButtonElement
|
|
96
|
+
variant="primary"
|
|
63
97
|
className={ clsx( 'checklist-item__checklist-primary-button', buttonClassName ) }
|
|
64
98
|
data-task={ id }
|
|
65
99
|
onClick={ onClickHandler }
|
|
66
100
|
{ ...buttonProps }
|
|
67
101
|
>
|
|
68
|
-
{
|
|
102
|
+
<span className="screen-reader-text">{ getStatusText() }</span>
|
|
103
|
+
<span aria-hidden="true">{ title }</span>
|
|
69
104
|
</ButtonElement>
|
|
70
105
|
) : (
|
|
71
106
|
<ButtonElement
|
|
@@ -75,17 +110,18 @@ const ChecklistItem: FC< Props > = ( { task, isPrimaryAction, expandable, onClic
|
|
|
75
110
|
{ ...buttonProps }
|
|
76
111
|
>
|
|
77
112
|
{ completed && (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
size={ 18 }
|
|
85
|
-
/>
|
|
113
|
+
<div
|
|
114
|
+
className="checklist-item__checkmark-container"
|
|
115
|
+
aria-hidden="true"
|
|
116
|
+
data-testid="checklist-item-checkmark"
|
|
117
|
+
>
|
|
118
|
+
<Icon icon={ check } className="checklist-item__checkmark" size={ 25 } />
|
|
86
119
|
</div>
|
|
87
120
|
) }
|
|
88
|
-
<span className="checklist-item__text">
|
|
121
|
+
<span className="checklist-item__text">
|
|
122
|
+
<span className="screen-reader-text">{ getStatusText() }</span>
|
|
123
|
+
<span aria-hidden="true">{ title }</span>
|
|
124
|
+
</span>
|
|
89
125
|
{ task.badge_text ? <Badge type="info-blue">{ task.badge_text }</Badge> : null }
|
|
90
126
|
{ shouldDisplayTaskCounter && (
|
|
91
127
|
<span className="checklist-item__counter">
|
|
@@ -93,28 +129,18 @@ const ChecklistItem: FC< Props > = ( { task, isPrimaryAction, expandable, onClic
|
|
|
93
129
|
</span>
|
|
94
130
|
) }
|
|
95
131
|
{ shouldDisplayChevron && (
|
|
96
|
-
<
|
|
97
|
-
aria-
|
|
132
|
+
<Icon
|
|
133
|
+
aria-hidden="true"
|
|
98
134
|
className="checklist-item__chevron"
|
|
99
|
-
icon={
|
|
100
|
-
size={
|
|
135
|
+
icon={ isRTL() ? chevronLeft : chevronRight }
|
|
136
|
+
size={ 25 }
|
|
101
137
|
/>
|
|
102
138
|
) }
|
|
103
139
|
{ subtitle && <p className="checklist-item__subtext">{ subtitle }</p> }
|
|
104
140
|
</ButtonElement>
|
|
105
141
|
) }
|
|
106
142
|
{ expandable && expandable.isOpen && (
|
|
107
|
-
<div className="checklist-item__expanded-content">
|
|
108
|
-
{ expandable.content }
|
|
109
|
-
{ expandable.action && (
|
|
110
|
-
<Button
|
|
111
|
-
className="checklist-item__checklist-expanded-action-button"
|
|
112
|
-
onClick={ expandable.action.onClick }
|
|
113
|
-
>
|
|
114
|
-
{ expandable.action.label }
|
|
115
|
-
</Button>
|
|
116
|
-
) }
|
|
117
|
-
</div>
|
|
143
|
+
<div className="checklist-item__expanded-content">{ expandable.content }</div>
|
|
118
144
|
) }
|
|
119
145
|
</li>
|
|
120
146
|
);
|
|
@@ -111,7 +111,6 @@
|
|
|
111
111
|
|
|
112
112
|
.checklist-item__checkmark-container {
|
|
113
113
|
margin-right: 7px;
|
|
114
|
-
width: 20px;
|
|
115
114
|
display: flex;
|
|
116
115
|
margin-left: 1px;
|
|
117
116
|
margin-bottom: -2px;
|
|
@@ -191,7 +190,7 @@
|
|
|
191
190
|
|
|
192
191
|
.checklist-item__chevron,
|
|
193
192
|
.checklist-item__checkmark {
|
|
194
|
-
fill: var(--color-
|
|
193
|
+
fill: var(--color-success);
|
|
195
194
|
}
|
|
196
195
|
.checklist-item__counter {
|
|
197
196
|
color: var(--color-neutral-40);
|
|
@@ -208,12 +207,12 @@
|
|
|
208
207
|
.checklist-item__task.completed.enabled > a:focus,
|
|
209
208
|
.checklist-item__task.pending > a:focus {
|
|
210
209
|
.checklist-item__text {
|
|
211
|
-
color: var(--
|
|
210
|
+
color: var(--color-accent);
|
|
212
211
|
}
|
|
213
212
|
|
|
214
213
|
.checklist-item__chevron,
|
|
215
214
|
.checklist-item__checkmark {
|
|
216
|
-
fill: var(--
|
|
215
|
+
fill: var(--color-accent);
|
|
217
216
|
}
|
|
218
217
|
|
|
219
218
|
// change badge color on hover (Choose a Plan step)
|
|
@@ -249,44 +248,30 @@
|
|
|
249
248
|
font-weight: 600;
|
|
250
249
|
}
|
|
251
250
|
|
|
252
|
-
.checklist-item__checklist-expanded-action-button.components-button,
|
|
253
251
|
.checklist-item__checklist-primary-button.components-button {
|
|
254
252
|
width: 100%;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.checklist-item__checklist-expanded-cta,
|
|
256
|
+
.checklist-item__checklist-primary-button.components-button {
|
|
255
257
|
font-weight: 500;
|
|
256
258
|
padding: 11px;
|
|
257
259
|
margin-top: 12px;
|
|
258
|
-
background-color: var(--color-primary);
|
|
259
|
-
border-color: var(--color-primary);
|
|
260
260
|
border-radius: 4px;
|
|
261
|
-
color: var(--color-text-inverted);
|
|
262
261
|
justify-content: center;
|
|
263
262
|
font-size: $font-body-small;
|
|
264
263
|
height: auto;
|
|
265
264
|
line-height: 22px;
|
|
265
|
+
}
|
|
266
266
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
&[disabled] {
|
|
274
|
-
background-color: var(--color-primary-10);
|
|
275
|
-
border-color: var(--color-primary-10);
|
|
276
|
-
color: var(--color-text-inverted);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
&:disabled {
|
|
280
|
-
opacity: 1;
|
|
281
|
-
&:hover {
|
|
282
|
-
color: var(--color-text-inverted);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
267
|
+
// Expanded content
|
|
268
|
+
.checklist-item__checklist-expanded-ctas {
|
|
269
|
+
display: flex;
|
|
270
|
+
gap: 16px;
|
|
285
271
|
}
|
|
286
272
|
|
|
287
|
-
.checklist-item__checklist-expanded-
|
|
288
|
-
|
|
289
|
-
margin: 16px 0;
|
|
273
|
+
.checklist-item__checklist-expanded-cta {
|
|
274
|
+
flex: 1;
|
|
290
275
|
}
|
|
291
276
|
|
|
292
277
|
.checklist-item__expanded-content {
|
|
@@ -126,7 +126,7 @@ describe( 'ChecklistItem', () => {
|
|
|
126
126
|
describe( 'when the task is completed', () => {
|
|
127
127
|
it( 'shows the task completed icon', () => {
|
|
128
128
|
renderComponent( { task: buildTask( { completed: true } ) } );
|
|
129
|
-
const taskCompleteIcon = screen.
|
|
129
|
+
const taskCompleteIcon = screen.getByTestId( 'checklist-item-checkmark' );
|
|
130
130
|
|
|
131
131
|
expect( taskCompleteIcon ).toBeVisible();
|
|
132
132
|
} );
|
|
@@ -181,25 +181,6 @@ describe( 'ChecklistItem', () => {
|
|
|
181
181
|
expect( screen.getByText( 'Expanded' ) ).toBeVisible();
|
|
182
182
|
} );
|
|
183
183
|
|
|
184
|
-
it( 'calls the action click', async () => {
|
|
185
|
-
const onClick = jest.fn();
|
|
186
|
-
renderComponent( {
|
|
187
|
-
expandable: {
|
|
188
|
-
isOpen: true,
|
|
189
|
-
content: <div>Expanded</div>,
|
|
190
|
-
action: {
|
|
191
|
-
label: 'Action',
|
|
192
|
-
onClick,
|
|
193
|
-
},
|
|
194
|
-
},
|
|
195
|
-
} );
|
|
196
|
-
|
|
197
|
-
const actionButton = screen.queryByRole( 'button', { name: 'Action' } )!;
|
|
198
|
-
await userEvent.click( actionButton );
|
|
199
|
-
|
|
200
|
-
expect( onClick ).toHaveBeenCalled();
|
|
201
|
-
} );
|
|
202
|
-
|
|
203
184
|
it( 'has the expanded class', () => {
|
|
204
185
|
const { container } = renderComponent( {
|
|
205
186
|
expandable: { isOpen: true, content: <div>Expanded</div> },
|
|
@@ -11,6 +11,7 @@ interface Props {
|
|
|
11
11
|
siteSlug: string | null;
|
|
12
12
|
checklistSlug: string | null;
|
|
13
13
|
makeLastTaskPrimaryAction?: boolean;
|
|
14
|
+
highlightNextAction?: boolean;
|
|
14
15
|
taskFilter?: ( tasks: Task[] ) => Task[];
|
|
15
16
|
useLaunchpadOptions?: UseLaunchpadOptions;
|
|
16
17
|
launchpadContext: string;
|
|
@@ -28,6 +29,7 @@ const LaunchpadInternal: FC< Props > = ( {
|
|
|
28
29
|
checklistSlug,
|
|
29
30
|
taskFilter,
|
|
30
31
|
makeLastTaskPrimaryAction,
|
|
32
|
+
highlightNextAction,
|
|
31
33
|
useLaunchpadOptions = {},
|
|
32
34
|
launchpadContext,
|
|
33
35
|
} ) => {
|
|
@@ -66,7 +68,10 @@ const LaunchpadInternal: FC< Props > = ( {
|
|
|
66
68
|
return (
|
|
67
69
|
<div className="launchpad__checklist-wrapper">
|
|
68
70
|
{ isFetchedAfterMount ? (
|
|
69
|
-
<Checklist
|
|
71
|
+
<Checklist
|
|
72
|
+
makeLastTaskPrimaryAction={ makeLastTaskPrimaryAction }
|
|
73
|
+
highlightNextAction={ highlightNextAction }
|
|
74
|
+
>
|
|
70
75
|
{ tasks.map( ( task ) => (
|
|
71
76
|
<ChecklistItem
|
|
72
77
|
task={ task }
|
package/src/launchpad.tsx
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { recordTracksEvent } from '@automattic/calypso-analytics';
|
|
2
2
|
import {
|
|
3
|
-
LaunchpadNavigator,
|
|
4
3
|
Site,
|
|
5
4
|
type SiteSelect,
|
|
6
|
-
|
|
5
|
+
defaultSuccessCallback,
|
|
7
6
|
useSortedLaunchpadTasks,
|
|
8
7
|
} from '@automattic/data-stores';
|
|
9
|
-
import {
|
|
8
|
+
import { useSelect } from '@wordpress/data';
|
|
10
9
|
import { useState } from 'react';
|
|
11
10
|
import { ShareSiteModal } from './action-components';
|
|
12
11
|
import LaunchpadInternal from './launchpad-internal';
|
|
@@ -22,6 +21,7 @@ type LaunchpadProps = {
|
|
|
22
21
|
onSiteLaunched?: () => void;
|
|
23
22
|
onTaskClick?: EventHandlers[ 'onTaskClick' ];
|
|
24
23
|
onPostFilterTasks?: ( tasks: Task[] ) => Task[];
|
|
24
|
+
highlightNextAction?: boolean;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
const Launchpad = ( {
|
|
@@ -31,11 +31,11 @@ const Launchpad = ( {
|
|
|
31
31
|
onSiteLaunched,
|
|
32
32
|
onTaskClick,
|
|
33
33
|
onPostFilterTasks,
|
|
34
|
+
highlightNextAction,
|
|
34
35
|
}: LaunchpadProps ) => {
|
|
35
36
|
const {
|
|
36
37
|
data: { checklist },
|
|
37
38
|
} = useSortedLaunchpadTasks( siteSlug, checklistSlug, launchpadContext );
|
|
38
|
-
const { setActiveChecklist } = useDispatch( LaunchpadNavigator.store );
|
|
39
39
|
|
|
40
40
|
const tasklistCompleted = checklist?.every( ( task: Task ) => task.completed ) || false;
|
|
41
41
|
|
|
@@ -55,7 +55,6 @@ const Launchpad = ( {
|
|
|
55
55
|
siteSlug,
|
|
56
56
|
tracksData,
|
|
57
57
|
extraActions: {
|
|
58
|
-
setActiveChecklist,
|
|
59
58
|
setShareSiteModalIsOpen,
|
|
60
59
|
},
|
|
61
60
|
eventHandlers: {
|
|
@@ -72,13 +71,21 @@ const Launchpad = ( {
|
|
|
72
71
|
};
|
|
73
72
|
|
|
74
73
|
const launchpadOptions = {
|
|
75
|
-
onSuccess:
|
|
74
|
+
onSuccess: defaultSuccessCallback,
|
|
76
75
|
};
|
|
77
76
|
|
|
77
|
+
if ( ! launchpadContext ) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
const shareSiteTask = checklist?.find( ( task: Task ) => task.id === 'share_site' ) ?? null;
|
|
78
81
|
return (
|
|
79
82
|
<>
|
|
80
83
|
{ shareSiteModalIsOpen && site && (
|
|
81
|
-
<ShareSiteModal
|
|
84
|
+
<ShareSiteModal
|
|
85
|
+
setModalIsOpen={ setShareSiteModalIsOpen }
|
|
86
|
+
site={ site }
|
|
87
|
+
task={ shareSiteTask }
|
|
88
|
+
/>
|
|
82
89
|
) }
|
|
83
90
|
<LaunchpadInternal
|
|
84
91
|
site={ site }
|
|
@@ -87,6 +94,7 @@ const Launchpad = ( {
|
|
|
87
94
|
taskFilter={ taskFilter }
|
|
88
95
|
useLaunchpadOptions={ launchpadOptions }
|
|
89
96
|
launchpadContext={ launchpadContext }
|
|
97
|
+
highlightNextAction={ highlightNextAction }
|
|
90
98
|
/>
|
|
91
99
|
</>
|
|
92
100
|
);
|
package/src/msw/resolver.ts
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
import { HttpResponse, HttpResponseResolver, delay } from 'msw';
|
|
2
|
-
import linkInBio from './link-in-bio';
|
|
3
2
|
import free from './setup-free';
|
|
4
3
|
|
|
5
|
-
export const launchpadResolver: HttpResponseResolver = async (
|
|
6
|
-
const searchParams = new URL( request.url ).searchParams;
|
|
7
|
-
const checklistSlug = searchParams.get( 'checklist_slug' );
|
|
8
|
-
|
|
4
|
+
export const launchpadResolver: HttpResponseResolver = async () => {
|
|
9
5
|
// Random delay to make the UI feel more realistic
|
|
10
|
-
|
|
11
6
|
await delay();
|
|
12
7
|
|
|
13
|
-
if ( checklistSlug === 'link-in-bio' ) {
|
|
14
|
-
return HttpResponse.json( linkInBio );
|
|
15
|
-
}
|
|
16
|
-
|
|
17
8
|
return HttpResponse.json( free );
|
|
18
9
|
};
|
package/src/msw/setup-free.ts
CHANGED
|
@@ -36,7 +36,7 @@ export default {
|
|
|
36
36
|
subtitle: '',
|
|
37
37
|
badge_text: '',
|
|
38
38
|
isLaunchTask: false,
|
|
39
|
-
calypso_path: '/setup/update-design/
|
|
39
|
+
calypso_path: '/setup/update-design/design-setup?siteSlug=site62798.wordpress.com',
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
id: 'domain_upsell',
|