@automattic/launchpad 1.0.0 → 1.0.1
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/.storybook/main.ts +16 -0
- package/.storybook/preview.ts +6 -0
- package/README.md +11 -2
- package/dist/cjs/action-components/index.js +6 -0
- package/dist/cjs/action-components/index.js.map +1 -0
- package/dist/cjs/action-components/share-site-modal/index.js +44 -0
- package/dist/cjs/action-components/share-site-modal/index.js.map +1 -0
- package/dist/cjs/action-components/share-site-modal/style.scss +159 -0
- package/dist/cjs/badge/index.js +2 -2
- package/dist/cjs/badge/index.js.map +1 -1
- package/dist/cjs/checklist/index.js +16 -8
- package/dist/cjs/checklist/index.js.map +1 -1
- package/dist/cjs/checklist/index.stories.js +29 -0
- package/dist/cjs/checklist/index.stories.js.map +1 -0
- package/dist/cjs/checklist-item/index.js +30 -13
- package/dist/cjs/checklist-item/index.js.map +1 -1
- package/dist/cjs/checklist-item/index.stories.js +79 -0
- package/dist/cjs/checklist-item/index.stories.js.map +1 -0
- package/dist/cjs/checklist-item/style.scss +142 -22
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/launchpad-container/index.js +11 -0
- package/dist/cjs/launchpad-container/index.js.map +1 -0
- package/dist/cjs/launchpad-container/style.scss +59 -0
- package/dist/cjs/launchpad-internal.js +40 -0
- package/dist/cjs/launchpad-internal.js.map +1 -0
- package/dist/cjs/launchpad-internal.stories.js +45 -0
- package/dist/cjs/launchpad-internal.stories.js.map +1 -0
- package/dist/cjs/launchpad.js +39 -10
- package/dist/cjs/launchpad.js.map +1 -1
- package/dist/cjs/msw/link-in-bio.js +68 -0
- package/dist/cjs/msw/link-in-bio.js.map +1 -0
- package/dist/cjs/msw/resolver.js +19 -0
- package/dist/cjs/msw/resolver.js.map +1 -0
- package/dist/cjs/msw/setup-free.js +88 -0
- package/dist/cjs/msw/setup-free.js.map +1 -0
- package/dist/cjs/setup-actions.js +51 -54
- package/dist/cjs/setup-actions.js.map +1 -1
- package/dist/cjs/use-tracking/index.js +72 -0
- package/dist/cjs/use-tracking/index.js.map +1 -0
- package/dist/esm/action-components/index.js +2 -0
- package/dist/esm/action-components/index.js.map +1 -0
- package/dist/esm/action-components/share-site-modal/index.js +42 -0
- package/dist/esm/action-components/share-site-modal/index.js.map +1 -0
- package/dist/esm/action-components/share-site-modal/style.scss +159 -0
- package/dist/esm/badge/index.js +2 -2
- package/dist/esm/badge/index.js.map +1 -1
- package/dist/esm/checklist/index.js +14 -8
- package/dist/esm/checklist/index.js.map +1 -1
- package/dist/esm/checklist/index.stories.js +25 -0
- package/dist/esm/checklist/index.stories.js.map +1 -0
- package/dist/esm/checklist-item/index.js +29 -14
- package/dist/esm/checklist-item/index.js.map +1 -1
- package/dist/esm/checklist-item/index.stories.js +75 -0
- package/dist/esm/checklist-item/index.stories.js.map +1 -0
- package/dist/esm/checklist-item/style.scss +142 -22
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/launchpad-container/index.js +8 -0
- package/dist/esm/launchpad-container/index.js.map +1 -0
- package/dist/esm/launchpad-container/style.scss +59 -0
- package/dist/esm/launchpad-internal.js +37 -0
- package/dist/esm/launchpad-internal.js.map +1 -0
- package/dist/esm/launchpad-internal.stories.js +41 -0
- package/dist/esm/launchpad-internal.stories.js.map +1 -0
- package/dist/esm/launchpad.js +41 -13
- package/dist/esm/launchpad.js.map +1 -1
- package/dist/esm/msw/link-in-bio.js +66 -0
- package/dist/esm/msw/link-in-bio.js.map +1 -0
- package/dist/esm/msw/resolver.js +14 -0
- package/dist/esm/msw/resolver.js.map +1 -0
- package/dist/esm/msw/setup-free.js +86 -0
- package/dist/esm/msw/setup-free.js.map +1 -0
- package/dist/esm/setup-actions.js +51 -54
- package/dist/esm/setup-actions.js.map +1 -1
- package/dist/esm/use-tracking/index.js +68 -0
- package/dist/esm/use-tracking/index.js.map +1 -0
- package/dist/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/action-components/index.d.ts +2 -0
- package/dist/types/action-components/index.d.ts.map +1 -0
- package/dist/types/action-components/share-site-modal/index.d.ts +9 -0
- package/dist/types/action-components/share-site-modal/index.d.ts.map +1 -0
- package/dist/types/badge/index.d.ts.map +1 -1
- package/dist/types/checklist/index.d.ts +6 -7
- package/dist/types/checklist/index.d.ts.map +1 -1
- package/dist/types/checklist/index.stories.d.ts +8 -0
- package/dist/types/checklist/index.stories.d.ts.map +1 -0
- package/dist/types/checklist-item/index.d.ts +11 -8
- package/dist/types/checklist-item/index.d.ts.map +1 -1
- package/dist/types/checklist-item/index.stories.d.ts +14 -0
- package/dist/types/checklist-item/index.stories.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/launchpad-container/index.d.ts +15 -0
- package/dist/types/launchpad-container/index.d.ts.map +1 -0
- package/dist/types/launchpad-internal.d.ts +20 -0
- package/dist/types/launchpad-internal.d.ts.map +1 -0
- package/dist/types/launchpad-internal.stories.d.ts +8 -0
- package/dist/types/launchpad-internal.stories.d.ts.map +1 -0
- package/dist/types/launchpad.d.ts +10 -9
- package/dist/types/launchpad.d.ts.map +1 -1
- package/dist/types/msw/link-in-bio.d.ts +35 -0
- package/dist/types/msw/link-in-bio.d.ts.map +1 -0
- package/dist/types/msw/resolver.d.ts +3 -0
- package/dist/types/msw/resolver.d.ts.map +1 -0
- package/dist/types/msw/setup-free.d.ts +35 -0
- package/dist/types/msw/setup-free.d.ts.map +1 -0
- package/dist/types/setup-actions.d.ts +1 -1
- package/dist/types/setup-actions.d.ts.map +1 -1
- package/dist/types/types.d.ts +19 -9
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/use-tracking/index.d.ts +14 -0
- package/dist/types/use-tracking/index.d.ts.map +1 -0
- package/package.json +24 -16
- package/src/action-components/index.ts +1 -0
- package/src/action-components/share-site-modal/index.tsx +100 -0
- package/src/action-components/share-site-modal/style.scss +159 -0
- package/src/badge/index.tsx +2 -4
- package/src/checklist/index.stories.tsx +45 -0
- package/src/checklist/index.tsx +22 -21
- package/src/checklist/test/index.tsx +26 -0
- package/src/checklist-item/index.stories.tsx +92 -0
- package/src/checklist-item/index.tsx +62 -22
- package/src/checklist-item/style.scss +142 -22
- package/src/checklist-item/test/index.tsx +232 -0
- package/src/index.ts +3 -0
- package/src/launchpad-container/index.tsx +45 -0
- package/src/launchpad-container/style.scss +59 -0
- package/src/launchpad-container/test/index.tsx +72 -0
- package/src/launchpad-internal.stories.tsx +49 -0
- package/src/launchpad-internal.tsx +85 -0
- package/src/launchpad.tsx +80 -30
- package/src/msw/link-in-bio.ts +66 -0
- package/src/msw/resolver.ts +18 -0
- package/src/msw/setup-free.ts +85 -0
- package/src/setup-actions.ts +67 -54
- package/src/test/launchpad.tsx +51 -24
- package/src/test/lib/fixtures.ts +7 -2
- package/src/types.ts +24 -9
- package/src/use-tracking/index.tsx +87 -0
- package/src/use-tracking/test/index.tsx +116 -0
- package/static/mockServiceWorker.js +287 -0
- package/src/test/checklist-item.tsx +0 -96
- package/src/test/checklist.tsx +0 -25
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
@import "@automattic/typography/styles/variables";
|
|
2
|
+
|
|
3
|
+
.share-site-modal__modal {
|
|
4
|
+
max-width: 640px;
|
|
5
|
+
|
|
6
|
+
.components-modal__header {
|
|
7
|
+
padding: 48px;
|
|
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;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.share-site-modal__modal-customize {
|
|
88
|
+
color: var(--studio-blue-50);
|
|
89
|
+
font-size: 0.875rem;
|
|
90
|
+
display: inline-flex;
|
|
91
|
+
flex-direction: row;
|
|
92
|
+
justify-content: start;
|
|
93
|
+
gap: 6px;
|
|
94
|
+
padding: 0;
|
|
95
|
+
margin: 0;
|
|
96
|
+
margin-top: 16px;
|
|
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;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.share-site-modal__modal-upsell-content-highlight {
|
|
118
|
+
font-weight: bold;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.share-site-modal__modal-view-site {
|
|
122
|
+
display: flex;
|
|
123
|
+
gap: 4px;
|
|
124
|
+
|
|
125
|
+
font-weight: 500;
|
|
126
|
+
/* stylelint-disable-next-line */
|
|
127
|
+
font-size: 14px;
|
|
128
|
+
line-height: 20px;
|
|
129
|
+
letter-spacing: -0.154px;
|
|
130
|
+
color: #101517;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.share-site-modal__modal-view-site:visited {
|
|
134
|
+
color: #101517;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.share-site-modal__modal-view-site:hover:not(:disabled) {
|
|
138
|
+
text-decoration: underline;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.share-site-modal__popover {
|
|
143
|
+
outline: none;
|
|
144
|
+
z-index: 100000;
|
|
145
|
+
.popover__inner {
|
|
146
|
+
border: 0;
|
|
147
|
+
box-shadow: none;
|
|
148
|
+
border-radius: 2px;
|
|
149
|
+
color: var(--color-text-inverted);
|
|
150
|
+
background: var(--color-neutral-60);
|
|
151
|
+
font-size: $font-body-extra-small;
|
|
152
|
+
padding: 6px 10px;
|
|
153
|
+
text-align: left;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.popover__arrow {
|
|
157
|
+
display: none;
|
|
158
|
+
}
|
|
159
|
+
}
|
package/src/badge/index.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import clsx from 'clsx';
|
|
2
2
|
|
|
3
3
|
import './style.scss';
|
|
4
4
|
|
|
@@ -19,9 +19,7 @@ export interface BadgeProps {
|
|
|
19
19
|
const Badge: React.FunctionComponent< BadgeProps > = ( props ) => {
|
|
20
20
|
const className = props.className;
|
|
21
21
|
const type = props.type || 'warning';
|
|
22
|
-
return (
|
|
23
|
-
<div className={ classNames( `badge badge--${ type }`, className ) }>{ props.children }</div>
|
|
24
|
-
);
|
|
22
|
+
return <div className={ clsx( `badge badge--${ type }`, className ) }>{ props.children }</div>;
|
|
25
23
|
};
|
|
26
24
|
|
|
27
25
|
export default Badge;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import ChecklistItem from '../checklist-item';
|
|
2
|
+
import Checklist from './';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
4
|
+
|
|
5
|
+
const meta: Meta< typeof Checklist > = {
|
|
6
|
+
title: 'Launchpad/Checklist',
|
|
7
|
+
component: Checklist,
|
|
8
|
+
decorators: [
|
|
9
|
+
( Story ) => (
|
|
10
|
+
<div style={ { width: 300 } }>
|
|
11
|
+
<Story />
|
|
12
|
+
</div>
|
|
13
|
+
),
|
|
14
|
+
],
|
|
15
|
+
args: {
|
|
16
|
+
children: [
|
|
17
|
+
<ChecklistItem
|
|
18
|
+
key="1"
|
|
19
|
+
task={ { id: '1', title: 'Task 1', completed: true, disabled: true } }
|
|
20
|
+
onClick={ () => {} }
|
|
21
|
+
/>,
|
|
22
|
+
<ChecklistItem
|
|
23
|
+
key="2"
|
|
24
|
+
task={ { id: '2', title: 'Task 2', disabled: false, completed: false } }
|
|
25
|
+
onClick={ () => {} }
|
|
26
|
+
/>,
|
|
27
|
+
<ChecklistItem
|
|
28
|
+
key="3"
|
|
29
|
+
task={ { id: '3', title: 'Task 3', disabled: false, completed: false } }
|
|
30
|
+
onClick={ () => {} }
|
|
31
|
+
/>,
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
type Story = StoryObj< typeof meta >;
|
|
37
|
+
export const Default: Story = {};
|
|
38
|
+
|
|
39
|
+
export const WithMakeLastTaskPrimaryAction: Story = {
|
|
40
|
+
args: {
|
|
41
|
+
makeLastTaskPrimaryAction: true,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default meta;
|
package/src/checklist/index.tsx
CHANGED
|
@@ -1,41 +1,42 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
import { Children, cloneElement, type FC, type ReactElement, type ComponentProps } from 'react';
|
|
3
|
+
import ChecklistItem, { Placeholder as ChecklistItemPlaceholder } from '../checklist-item';
|
|
5
4
|
import './style.scss';
|
|
6
5
|
|
|
7
|
-
interface
|
|
8
|
-
tasks: Task[] | null;
|
|
6
|
+
interface Props {
|
|
9
7
|
makeLastTaskPrimaryAction?: boolean;
|
|
8
|
+
children?:
|
|
9
|
+
| ReactElement< ComponentProps< typeof ChecklistItem > >
|
|
10
|
+
| ReactElement< ComponentProps< typeof ChecklistItem > >[];
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
const Checklist = ( {
|
|
13
|
+
const Checklist: FC< Props > = ( { children, makeLastTaskPrimaryAction } ) => {
|
|
14
|
+
const lastChildIndex = Children.count( children ) - 1;
|
|
15
|
+
|
|
13
16
|
return (
|
|
14
17
|
<ul
|
|
15
|
-
className={
|
|
18
|
+
className={ clsx( 'checklist__tasks', {
|
|
16
19
|
'checklist__has-primary-action': makeLastTaskPrimaryAction,
|
|
17
20
|
} ) }
|
|
18
21
|
aria-label="Launchpad Checklist"
|
|
19
22
|
>
|
|
20
|
-
{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
/>
|
|
27
|
-
) ) }
|
|
23
|
+
{ Children.map( children || [], ( child, index ) => {
|
|
24
|
+
if ( index === lastChildIndex ) {
|
|
25
|
+
return cloneElement( child, { isPrimaryAction: makeLastTaskPrimaryAction } );
|
|
26
|
+
}
|
|
27
|
+
return child;
|
|
28
|
+
} ) }
|
|
28
29
|
</ul>
|
|
29
30
|
);
|
|
30
31
|
};
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
export const Placeholder = () => {
|
|
33
34
|
return (
|
|
34
35
|
<ul className="checklist__tasks" aria-label="Launchpad Checklist">
|
|
35
|
-
<
|
|
36
|
-
<
|
|
37
|
-
<
|
|
38
|
-
<
|
|
36
|
+
<ChecklistItemPlaceholder />
|
|
37
|
+
<ChecklistItemPlaceholder />
|
|
38
|
+
<ChecklistItemPlaceholder />
|
|
39
|
+
<ChecklistItemPlaceholder />
|
|
39
40
|
</ul>
|
|
40
41
|
);
|
|
41
42
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import Checklist from '../';
|
|
4
|
+
import ChecklistItem from '../../checklist-item';
|
|
5
|
+
import { buildTask } from '../../test/lib/fixtures';
|
|
6
|
+
import '@testing-library/jest-dom';
|
|
7
|
+
|
|
8
|
+
describe( 'Checklist', () => {
|
|
9
|
+
it( 'renders the list of items', () => {
|
|
10
|
+
render(
|
|
11
|
+
<Checklist>
|
|
12
|
+
<ChecklistItem key={ 0 } task={ buildTask( {} ) } />
|
|
13
|
+
<ChecklistItem key={ 1 } task={ buildTask( {} ) } />
|
|
14
|
+
</Checklist>
|
|
15
|
+
);
|
|
16
|
+
const checklistItems = screen.getAllByRole( 'listitem' );
|
|
17
|
+
expect( checklistItems.length ).toBe( 2 );
|
|
18
|
+
} );
|
|
19
|
+
|
|
20
|
+
it( 'renders a empty list when provided no tasks', () => {
|
|
21
|
+
render( <Checklist /> );
|
|
22
|
+
const checklistItems = screen.queryByRole( 'listitem' );
|
|
23
|
+
|
|
24
|
+
expect( checklistItems ).not.toBeInTheDocument();
|
|
25
|
+
} );
|
|
26
|
+
} );
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import ChecklistItem from './';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
|
|
4
|
+
const meta: Meta< typeof ChecklistItem > = {
|
|
5
|
+
title: 'Launchpad/ChecklistItem',
|
|
6
|
+
component: ChecklistItem,
|
|
7
|
+
decorators: [
|
|
8
|
+
( Story ) => (
|
|
9
|
+
<div style={ { width: 300 } }>
|
|
10
|
+
<ul className="checklist__tasks">
|
|
11
|
+
<Story />
|
|
12
|
+
</ul>
|
|
13
|
+
</div>
|
|
14
|
+
),
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type Story = StoryObj< typeof meta >;
|
|
19
|
+
const baseTask = {
|
|
20
|
+
id: '1',
|
|
21
|
+
title: 'Task 1',
|
|
22
|
+
completed: false,
|
|
23
|
+
disabled: false,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const Default: Story = {
|
|
27
|
+
args: {
|
|
28
|
+
onClick: () => {},
|
|
29
|
+
task: baseTask,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const Completed: Story = {
|
|
34
|
+
args: {
|
|
35
|
+
onClick: () => {},
|
|
36
|
+
task: { ...baseTask, completed: true },
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const Disabled: Story = {
|
|
41
|
+
args: {
|
|
42
|
+
onClick: () => {},
|
|
43
|
+
task: { ...baseTask, disabled: true },
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const WithBadgetText: Story = {
|
|
48
|
+
args: {
|
|
49
|
+
onClick: () => {},
|
|
50
|
+
task: { ...baseTask, badge_text: 'Upgrade plan' },
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const WithTaskCounter: Story = {
|
|
55
|
+
args: {
|
|
56
|
+
onClick: () => {},
|
|
57
|
+
task: { ...baseTask, repetition_count: 1, target_repetitions: 3 },
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const WithSubtitle: Story = {
|
|
62
|
+
args: {
|
|
63
|
+
onClick: () => {},
|
|
64
|
+
task: { ...baseTask, subtitle: 'This is a subtitle' },
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const Expanded: Story = {
|
|
69
|
+
args: {
|
|
70
|
+
task: baseTask,
|
|
71
|
+
expandable: {
|
|
72
|
+
content: <p>This is the expanded content.</p>,
|
|
73
|
+
isOpen: true,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const ExpandedWithAction: Story = {
|
|
79
|
+
args: {
|
|
80
|
+
task: baseTask,
|
|
81
|
+
expandable: {
|
|
82
|
+
content: <p>This is the expanded content.</p>,
|
|
83
|
+
isOpen: true,
|
|
84
|
+
action: {
|
|
85
|
+
label: 'Next',
|
|
86
|
+
onClick: () => {},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export default meta;
|
|
@@ -1,52 +1,79 @@
|
|
|
1
|
-
import { Badge,
|
|
2
|
-
import
|
|
1
|
+
import { Badge, Gridicon } from '@automattic/components';
|
|
2
|
+
import { Button } from '@wordpress/components';
|
|
3
|
+
import clsx from 'clsx';
|
|
3
4
|
import { translate, useRtl } from 'i18n-calypso';
|
|
4
|
-
import { Task } from '../types';
|
|
5
|
+
import type { Task, Expandable } from '../types';
|
|
6
|
+
import type { FC, Key } from 'react';
|
|
5
7
|
|
|
6
8
|
import './style.scss';
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
interface Props {
|
|
11
|
+
key?: Key;
|
|
12
|
+
task: Task;
|
|
13
|
+
isPrimaryAction?: boolean;
|
|
14
|
+
expandable?: Expandable;
|
|
15
|
+
onClick?: () => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const ChecklistItem: FC< Props > = ( { task, isPrimaryAction, expandable, onClick } ) => {
|
|
9
19
|
const isRtl = useRtl();
|
|
10
|
-
const { id, completed, disabled, title, subtitle, actionDispatch } = task;
|
|
20
|
+
const { id, completed, disabled = false, title, subtitle, actionDispatch } = task;
|
|
11
21
|
|
|
12
|
-
//
|
|
13
|
-
|
|
22
|
+
// If the task says we should use the Calypso path, ensure we use that link for the button's href.
|
|
23
|
+
// This allows the UI routing code to hook into the URL changes and should reduce full-page (re)loads
|
|
24
|
+
// when clicking on the task list items.
|
|
25
|
+
const buttonHref = task.useCalypsoPath && task.calypso_path ? task.calypso_path : undefined;
|
|
14
26
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
27
|
+
// The Button component does not accept the `disabled` and `href` props together.
|
|
28
|
+
// This code will only add href property if the disabled variable is false.
|
|
29
|
+
const buttonProps = {
|
|
30
|
+
disabled,
|
|
31
|
+
...( disabled ? {} : { href: buttonHref } ),
|
|
18
32
|
};
|
|
19
33
|
|
|
34
|
+
const onClickHandler = onClick || actionDispatch;
|
|
35
|
+
const isClickable = !! ( buttonProps.href || onClickHandler );
|
|
36
|
+
|
|
37
|
+
// Display chevron if task is incomplete.
|
|
38
|
+
// Don't display chevron and badge at the same time.
|
|
39
|
+
// Don't display chevron if item is not clickable.
|
|
40
|
+
const shouldDisplayChevron = ! completed && ! disabled && ! task.badge_text && isClickable;
|
|
41
|
+
|
|
20
42
|
// Display task counter if task is incomplete and has the count properties;
|
|
21
43
|
const shouldDisplayTaskCounter =
|
|
22
44
|
task.target_repetitions &&
|
|
23
45
|
null !== task.repetition_count &&
|
|
24
46
|
undefined !== task.repetition_count;
|
|
25
47
|
|
|
48
|
+
// Make sure the button keeps the button styles if it is not clickable.
|
|
49
|
+
const buttonClassName = isClickable ? '' : 'components-button';
|
|
50
|
+
const ButtonElement = isClickable ? Button : 'div';
|
|
51
|
+
|
|
26
52
|
return (
|
|
27
53
|
<li
|
|
28
|
-
className={
|
|
54
|
+
className={ clsx( 'checklist-item__task', {
|
|
29
55
|
completed: completed,
|
|
30
56
|
pending: ! completed,
|
|
31
57
|
enabled: ! disabled,
|
|
32
58
|
disabled: disabled,
|
|
59
|
+
expanded: expandable && expandable.isOpen,
|
|
33
60
|
} ) }
|
|
34
61
|
>
|
|
35
62
|
{ isPrimaryAction ? (
|
|
36
|
-
<
|
|
37
|
-
className=
|
|
38
|
-
disabled={ disabled }
|
|
63
|
+
<ButtonElement
|
|
64
|
+
className={ clsx( 'checklist-item__checklist-primary-button', buttonClassName ) }
|
|
39
65
|
data-task={ id }
|
|
40
|
-
onClick={
|
|
66
|
+
onClick={ onClickHandler }
|
|
67
|
+
{ ...buttonProps }
|
|
41
68
|
>
|
|
42
69
|
{ title }
|
|
43
|
-
</
|
|
70
|
+
</ButtonElement>
|
|
44
71
|
) : (
|
|
45
|
-
<
|
|
46
|
-
className=
|
|
47
|
-
disabled={ disabled }
|
|
72
|
+
<ButtonElement
|
|
73
|
+
className={ clsx( 'checklist-item__task-content', buttonClassName ) }
|
|
48
74
|
data-task={ id }
|
|
49
|
-
onClick={
|
|
75
|
+
onClick={ onClickHandler }
|
|
76
|
+
{ ...buttonProps }
|
|
50
77
|
>
|
|
51
78
|
{ completed && (
|
|
52
79
|
// show checkmark for completed tasks regardless if they are disabled or kept active
|
|
@@ -75,13 +102,26 @@ const ChecklistItem = ( { task, isPrimaryAction }: { task: Task; isPrimaryAction
|
|
|
75
102
|
/>
|
|
76
103
|
) }
|
|
77
104
|
{ subtitle && <p className="checklist-item__subtext">{ subtitle }</p> }
|
|
78
|
-
</
|
|
105
|
+
</ButtonElement>
|
|
106
|
+
) }
|
|
107
|
+
{ expandable && expandable.isOpen && (
|
|
108
|
+
<div className="checklist-item__expanded-content">
|
|
109
|
+
{ expandable.content }
|
|
110
|
+
{ expandable.action && (
|
|
111
|
+
<Button
|
|
112
|
+
className="checklist-item__checklist-expanded-action-button"
|
|
113
|
+
onClick={ expandable.action.onClick }
|
|
114
|
+
>
|
|
115
|
+
{ expandable.action.label }
|
|
116
|
+
</Button>
|
|
117
|
+
) }
|
|
118
|
+
</div>
|
|
79
119
|
) }
|
|
80
120
|
</li>
|
|
81
121
|
);
|
|
82
122
|
};
|
|
83
123
|
|
|
84
|
-
|
|
124
|
+
export const Placeholder: FC = () => {
|
|
85
125
|
return (
|
|
86
126
|
<div className="checklist-item__task-content is-placeholder">
|
|
87
127
|
<div className="checklist-item__content">
|