From fe865b0c845c391409519d370509ed9ca54bb512 Mon Sep 17 00:00:00 2001
From: Valerie K
Date: Wed, 17 Jun 2020 04:44:08 +0900
Subject: [PATCH] Add Timeline component
(https://github.com/woocommerce/woocommerce-admin/pull/3614)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add Timeline component
The overall component is split into smaller components:
* Timeline item: an individual item (event) for the timeline.
* Timeline group: a group of items grouped according to props.
See README.md for prop details.
Ordering and grouping is decided via props. Component also
exports helper objects to make it easier to pass in the correct
props for ordering and grouping.
Item titles and bodies can be passed in as either strings or
React elements. Icons must be React elements.
Has a storybook scenario along with unit and snapshot tests.
Co-authored-by: Valerie K
Co-authored-by: Allen Snook
Co-authored-by: Kristófer R
Co-authored-by: David Levin
---
.../packages/components/CHANGELOG.md | 1 +
.../packages/components/src/index.js | 1 +
.../packages/components/src/style.scss | 1 +
.../components/src/timeline/README.md | 70 ++++++
.../timeline/__mocks__/timeline-mock-data.js | 45 ++++
.../packages/components/src/timeline/index.js | 131 ++++++++++
.../components/src/timeline/stories/index.js | 107 ++++++++
.../components/src/timeline/style.scss | 122 +++++++++
.../timeline/test/__snapshots__/index.js.snap | 231 ++++++++++++++++++
.../components/src/timeline/test/index.js | 189 ++++++++++++++
.../components/src/timeline/timeline-group.js | 113 +++++++++
.../components/src/timeline/timeline-item.js | 81 ++++++
.../packages/components/src/timeline/util.js | 57 +++++
13 files changed, 1149 insertions(+)
create mode 100644 plugins/woocommerce-admin/packages/components/src/timeline/README.md
create mode 100644 plugins/woocommerce-admin/packages/components/src/timeline/__mocks__/timeline-mock-data.js
create mode 100644 plugins/woocommerce-admin/packages/components/src/timeline/index.js
create mode 100644 plugins/woocommerce-admin/packages/components/src/timeline/stories/index.js
create mode 100644 plugins/woocommerce-admin/packages/components/src/timeline/style.scss
create mode 100644 plugins/woocommerce-admin/packages/components/src/timeline/test/__snapshots__/index.js.snap
create mode 100644 plugins/woocommerce-admin/packages/components/src/timeline/test/index.js
create mode 100644 plugins/woocommerce-admin/packages/components/src/timeline/timeline-group.js
create mode 100644 plugins/woocommerce-admin/packages/components/src/timeline/timeline-item.js
create mode 100644 plugins/woocommerce-admin/packages/components/src/timeline/util.js
diff --git a/plugins/woocommerce-admin/packages/components/CHANGELOG.md b/plugins/woocommerce-admin/packages/components/CHANGELOG.md
index e8c017d386d..7ce42d9293f 100644
--- a/plugins/woocommerce-admin/packages/components/CHANGELOG.md
+++ b/plugins/woocommerce-admin/packages/components/CHANGELOG.md
@@ -1,4 +1,5 @@
# 5.0.0 (Unreleased)
+- Added `` component.
- Added `` component.
- Style form components for WordPress 5.3.
- Fix CompareFilter options format (key prop vs. id).
diff --git a/plugins/woocommerce-admin/packages/components/src/index.js b/plugins/woocommerce-admin/packages/components/src/index.js
index 5a0e7c60efe..fcf1c3f01c8 100644
--- a/plugins/woocommerce-admin/packages/components/src/index.js
+++ b/plugins/woocommerce-admin/packages/components/src/index.js
@@ -57,6 +57,7 @@ export { default as TableSummary } from './table/summary';
export { default as Tag } from './tag';
export { default as TextControl } from './text-control';
export { default as TextControlWithAffixes } from './text-control-with-affixes';
+export { default as Timeline } from './timeline';
export { default as useFilters } from './higher-order/use-filters';
export { default as ViewMoreList } from './view-more-list';
export { default as WebPreview } from './web-preview';
diff --git a/plugins/woocommerce-admin/packages/components/src/style.scss b/plugins/woocommerce-admin/packages/components/src/style.scss
index 209ae6ff892..329eef51470 100644
--- a/plugins/woocommerce-admin/packages/components/src/style.scss
+++ b/plugins/woocommerce-admin/packages/components/src/style.scss
@@ -35,5 +35,6 @@
@import 'tag/style.scss';
@import 'text-control/style.scss';
@import 'text-control-with-affixes/style.scss';
+@import 'timeline/style.scss';
@import 'view-more-list/style.scss';
@import 'web-preview/style.scss';
diff --git a/plugins/woocommerce-admin/packages/components/src/timeline/README.md b/plugins/woocommerce-admin/packages/components/src/timeline/README.md
new file mode 100644
index 00000000000..f27300da7bc
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/timeline/README.md
@@ -0,0 +1,70 @@
+Timeline
+===
+
+This is a timeline for displaying data, such as events, in chronological order.
+It accepts `items` for the timeline content and will order the data for you.
+
+## Usage
+
+```jsx
+import Timeline from './Timeline';
+import { orderByOptions, groupByOptions } from './Timeline';
+import GridIcon from 'gridicons';
+
+const items = [
+ {
+ date: new Date( 2019, 9, 28, 9, 0 ),
+ icon: ,
+ headline: 'A payment of $90.00 was successfully charged',
+ body: [
+
{ 'Fee: $2.91 ( 2.9% + $0.30 )' }
,
+
{ 'Net deposit: $87.09' }
,
+ ],
+ },
+ {
+ date: new Date( 2019, 9, 28, 9, 32 ),
+ icon: ,
+ headline: '$94.16 was added to your October 29, 2019 deposit',
+ body: [],
+ },
+ {
+ date: new Date( 2019, 9, 27, 20, 9 ),
+ icon: ,
+ headline: 'A payment of $90.00 was successfully authorized',
+ body: [],
+ },
+]
+
+
+```
+
+### Props
+
+Name | Type | Default | Description
+--- | --- | --- | ---
+`className` | String | `''` | Additional class names that can be applied for styling purposes
+`items` | Array | `[]` | An array of items to be displayed on the timeline
+`orderBy` | String | `'asc'` | How the items should be ordered, either `'asc'` or `'desc'`
+`groupBy` | String | `'day'` | How the items should be grouped, one of `'day'`, `'week'`, or `'month'`
+`dateFormat` | String | `'F j, Y'` | PHP date format string used to format dates, see php.net/date
+`clockFormat` | String | `'g:ia'` | PHP clock format string used to format times, see php.net/date
+
+
+### `items` structure
+
+A list of items with properties:
+
+Name | Type | Default | Description
+--- | --- | --- | ---
+`date` | Date | Required | JavaScript Date object set to when this event happened
+`icon` | Element | Required | The element used to represent the icon for this event
+`headline` | Element | Required | The element used to represent the title of this event
+`body` | Array | `[]` | Elements that contain details pertaining to this event
+`hideTimestamp` | Bool | `false` | Allows the user to hide the timestamp associated with this event
+
+Icon color can be customized by adding 1 of 3 classes to the icon element: `is-success` (green), `is-warning` (yellow), and `is-error` (red)
+ - If no class is provided the icon will be gray
diff --git a/plugins/woocommerce-admin/packages/components/src/timeline/__mocks__/timeline-mock-data.js b/plugins/woocommerce-admin/packages/components/src/timeline/__mocks__/timeline-mock-data.js
new file mode 100644
index 00000000000..0e6902da18a
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/timeline/__mocks__/timeline-mock-data.js
@@ -0,0 +1,45 @@
+/**
+ * External dependencies
+ */
+import GridIcon from 'gridicons';
+
+export default [
+ {
+ date: new Date( 2020, 0, 20, 1, 30 ),
+ body: [
{ 'p element in body' }
, 'string in body' ],
+ headline:
{ 'p tag in headline' }
,
+ icon: (
+
+ ),
+ hideTimestamp: true,
+ },
+ {
+ date: new Date( 2020, 0, 20, 23, 45 ),
+ body: [],
+ headline: { 'span in headline' },
+ icon: (
+
+ ),
+ },
+ {
+ date: new Date( 2020, 0, 22, 15, 13 ),
+ body: [ { 'span in body' } ],
+ headline: 'string in headline',
+ icon: (
+
+ ),
+ },
+ {
+ date: new Date( 2020, 0, 17, 1, 45 ),
+ headline: 'undefined body and string headline',
+ icon: ,
+ },
+];
diff --git a/plugins/woocommerce-admin/packages/components/src/timeline/index.js b/plugins/woocommerce-admin/packages/components/src/timeline/index.js
new file mode 100644
index 00000000000..a6540d90a7e
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/timeline/index.js
@@ -0,0 +1,131 @@
+/**
+ * External dependencies
+ */
+import classnames from 'classnames';
+import PropTypes from 'prop-types';
+import { __ } from '@wordpress/i18n';
+import { format } from '@wordpress/date';
+
+/**
+ * Internal dependencies
+ */
+import TimelineGroup from './timeline-group';
+import { sortByDateUsing, groupItemsUsing } from './util';
+
+const Timeline = ( props ) => {
+ const {
+ className,
+ items,
+ groupBy,
+ orderBy,
+ dateFormat,
+ clockFormat,
+ } = props;
+ const timelineClassName = classnames( 'woocommerce-timeline', className );
+
+ // Early return in case no data was passed to the component.
+ if ( ! items || items.length === 0 ) {
+ return (
+
+
+ { __( 'No data to display', 'woocommerce-admin' ) }
+