diff --git a/plugins/woocommerce-admin/client/analytics/report/example.js b/plugins/woocommerce-admin/client/analytics/report/example.js index 3f9db534f08..90ecd0841cb 100644 --- a/plugins/woocommerce-admin/client/analytics/report/example.js +++ b/plugins/woocommerce-admin/client/analytics/report/example.js @@ -9,7 +9,7 @@ import { Component, Fragment } from '@wordpress/element'; * Internal dependencies */ import Header from 'layout/header'; -import { SummaryList, SummaryNumber } from 'components/summary'; +import { SummaryList, SummaryNumber } from '@woocommerce/components'; export default class extends Component { render() { diff --git a/plugins/woocommerce-admin/client/analytics/report/orders/index.js b/plugins/woocommerce-admin/client/analytics/report/orders/index.js index 362f5e5ea75..d23405e18c6 100644 --- a/plugins/woocommerce-admin/client/analytics/report/orders/index.js +++ b/plugins/woocommerce-admin/client/analytics/report/orders/index.js @@ -13,10 +13,9 @@ import { partial } from 'lodash'; /** * Internal dependencies */ -import Card from 'components/card'; +import { Card, ReportFilters } from '@woocommerce/components'; import { filters, filterPaths, advancedFilterConfig } from './constants'; import Header from 'layout/header/index'; -import { ReportFilters } from 'components/filters'; import './style.scss'; class OrdersReport extends Component { diff --git a/plugins/woocommerce-admin/client/analytics/report/products/index.js b/plugins/woocommerce-admin/client/analytics/report/products/index.js index dc801341cc6..3e79933f206 100644 --- a/plugins/woocommerce-admin/client/analytics/report/products/index.js +++ b/plugins/woocommerce-admin/client/analytics/report/products/index.js @@ -10,7 +10,7 @@ import { Component, Fragment } from '@wordpress/element'; */ import { filterPaths, filters } from './constants'; import Header from 'layout/header'; -import { ReportFilters } from 'components/filters'; +import { ReportFilters } from '@woocommerce/components'; import './style.scss'; export default class extends Component { diff --git a/plugins/woocommerce-admin/client/analytics/report/revenue/index.js b/plugins/woocommerce-admin/client/analytics/report/revenue/index.js index 94aac356cdb..b9a3989c796 100644 --- a/plugins/woocommerce-admin/client/analytics/report/revenue/index.js +++ b/plugins/woocommerce-admin/client/analytics/report/revenue/index.js @@ -11,15 +11,18 @@ import PropTypes from 'prop-types'; /** * Internal dependencies */ -import Card from 'components/card'; -import Chart from 'components/chart'; +import { + Card, + Chart, + ReportFilters, + SummaryList, + SummaryNumber, + TableCard, +} from '@woocommerce/components'; import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency'; import { getAdminLink, updateQueryString } from 'lib/nav-utils'; import { getReportData } from 'lib/swagger'; import Header from 'layout/header'; -import { ReportFilters } from 'components/filters'; -import { SummaryList, SummaryNumber } from 'components/summary'; -import { TableCard } from 'components/table'; // Mock data until we fetch from an API import rawData from './mock-data'; diff --git a/plugins/woocommerce-admin/client/components/README.md b/plugins/woocommerce-admin/client/components/README.md new file mode 100644 index 00000000000..2174cb42280 --- /dev/null +++ b/plugins/woocommerce-admin/client/components/README.md @@ -0,0 +1,38 @@ +Components +========== + +This folder contains the WooCommerce-created components. These are exported onto a global, `wc.components`, for general use. + +## How to use: + +For any files not imported into `components/index.js` (`analytics/*`, `layout/*`, `dashboard/*`, etc), we can use `import { Card, etc … } from @woocommerce/components`. + +For any `component/*` files, we should import from component-specific paths, not from `component/index.js`, to prevent circular dependencies. See `components/card/index.js` for an example. + +```jsx +import { Card, Link } from '@woocommerce/components'; + +render: function() { + return ( + + Card content with an example link. + + ); +} +``` + +## For external development + +External developers will need to enqueue the components library, `wc-components`, and then can access them from the global. + +```jsx +const { Card, Link } = wc.components; + +render: function() { + return ( + + Card content with an example link. + + ); +} +``` diff --git a/plugins/woocommerce-admin/client/components/card/index.js b/plugins/woocommerce-admin/client/components/card/index.js index 02ed089153b..5c76d2e2eab 100644 --- a/plugins/woocommerce-admin/client/components/card/index.js +++ b/plugins/woocommerce-admin/client/components/card/index.js @@ -10,7 +10,7 @@ import PropTypes from 'prop-types'; * Internal dependencies */ import './style.scss'; -import { EllipsisMenu } from '../ellipsis-menu'; +import { EllipsisMenu } from 'components/ellipsis-menu'; import { H, Section } from 'layout/section'; class Card extends Component { diff --git a/plugins/woocommerce-admin/client/components/chart/example.js b/plugins/woocommerce-admin/client/components/chart/example.js index d95bc48d9e8..8d95b924aec 100644 --- a/plugins/woocommerce-admin/client/components/chart/example.js +++ b/plugins/woocommerce-admin/client/components/chart/example.js @@ -9,7 +9,7 @@ import { Component, Fragment } from '@wordpress/element'; * Internal dependencies */ import Card from 'components/card'; -import Chart from 'components/chart'; +import Chart from './index'; import dummyOrders from './test/fixtures/dummy'; class WidgetCharts extends Component { diff --git a/plugins/woocommerce-admin/client/components/filters/date/content.js b/plugins/woocommerce-admin/client/components/filters/date/content.js index 5ceff28e005..18ac2415eb3 100644 --- a/plugins/woocommerce-admin/client/components/filters/date/content.js +++ b/plugins/woocommerce-admin/client/components/filters/date/content.js @@ -14,7 +14,6 @@ import classnames from 'classnames'; import ComparePeriods from './compare-periods'; import { DateRange } from 'components/calendar'; import { H, Section } from 'layout/section'; -import Link from 'components/link'; import PresetPeriods from './preset-periods'; const isMobileViewport = () => window.innerWidth < 782; @@ -45,7 +44,7 @@ class DatePickerContent extends Component { before, onUpdate, onClose, - getUpdatePath, + onSelect, isValidSelection, resetCustomValues, focusedInput, @@ -127,13 +126,13 @@ class DatePickerContent extends Component { ) } { isValidSelection( selectedTab ) ? ( - { __( 'Update', 'wc-admin' ) } - + ) : ( ); } diff --git a/plugins/woocommerce-admin/client/components/index.js b/plugins/woocommerce-admin/client/components/index.js new file mode 100644 index 00000000000..c1839bfaa2c --- /dev/null +++ b/plugins/woocommerce-admin/client/components/index.js @@ -0,0 +1,30 @@ +/** @format */ + +/** + * External Dependencies + */ +// Turn on react-dates classes/styles, see https://github.com/airbnb/react-dates#initialize +import 'react-dates/initialize'; + +export { AdvancedFilters, DatePicker, FilterPicker, ReportFilters } from './filters'; +export { default as AnimationSlider } from './animation-slider'; +export { default as Card } from './card'; +export { default as Chart } from './chart'; +export { default as Count } from './count'; +export { DateRange } from './calendar'; +export { default as DropdownButton } from './dropdown-button'; +export { EllipsisMenu, MenuItem, MenuTitle } from './ellipsis-menu'; +export { default as Flag } from './flag'; +export { default as Gravatar } from './gravatar'; +export { default as Link } from './link'; +export { default as OrderStatus } from './order-status'; +export { default as Pagination } from './pagination'; +export { default as ProductImage } from './product-image'; +export { default as ProductRating } from './rating/product'; +export { default as Rating } from './rating'; +export { default as ReviewRating } from './rating/review'; +export { default as SegmentedSelection } from './segmented-selection'; +export { default as SplitButton } from './split-button'; +export { SummaryList, SummaryNumber } from './summary'; +export { TableCard, Table, TableSummary } from './table'; +export { default as useFilters } from './higher-order/use-filters'; diff --git a/plugins/woocommerce-admin/client/components/rating/index.js b/plugins/woocommerce-admin/client/components/rating/index.js index 86e1f5965fe..eed7aaeb3bb 100644 --- a/plugins/woocommerce-admin/client/components/rating/index.js +++ b/plugins/woocommerce-admin/client/components/rating/index.js @@ -64,6 +64,4 @@ Rating.defaultProps = { size: 18, }; -export { Rating }; -export { default as ProductRating } from './product'; -export { default as ReviewRating } from './review'; +export default Rating; diff --git a/plugins/woocommerce-admin/client/components/rating/product.js b/plugins/woocommerce-admin/client/components/rating/product.js index d33b0a28a44..6f87cbc0b35 100644 --- a/plugins/woocommerce-admin/client/components/rating/product.js +++ b/plugins/woocommerce-admin/client/components/rating/product.js @@ -3,21 +3,17 @@ /** * External dependencies */ -import { Component } from '@wordpress/element'; import PropTypes from 'prop-types'; /** * Internal dependencies */ -import { Rating } from './index'; +import Rating from './index'; -class ProductRating extends Component { - render() { - const { product, restOfProps } = this.props; - const rating = ( product && product.average_rating ) || 0; - return ; - } -} +const ProductRating = ( { product, ...props } ) => { + const rating = ( product && product.average_rating ) || 0; + return ; +}; ProductRating.propTypes = { product: PropTypes.object.isRequired, diff --git a/plugins/woocommerce-admin/client/components/rating/review.js b/plugins/woocommerce-admin/client/components/rating/review.js index 802449c7444..4410d8fd333 100644 --- a/plugins/woocommerce-admin/client/components/rating/review.js +++ b/plugins/woocommerce-admin/client/components/rating/review.js @@ -3,21 +3,17 @@ /** * External dependencies */ -import { Component } from '@wordpress/element'; import PropTypes from 'prop-types'; /** * Internal dependencies */ -import { Rating } from './index'; +import Rating from './index'; -class ReviewRating extends Component { - render() { - const { review, restOfProps } = this.props; - const rating = ( review && review.rating ) || 0; - return ; - } -} +const ReviewRating = ( { review, ...props } ) => { + const rating = ( review && review.rating ) || 0; + return ; +}; ReviewRating.propTypes = { review: PropTypes.object.isRequired, diff --git a/plugins/woocommerce-admin/client/components/rating/test/index.js b/plugins/woocommerce-admin/client/components/rating/test/index.js index 982f1e68940..02974d9b6ba 100644 --- a/plugins/woocommerce-admin/client/components/rating/test/index.js +++ b/plugins/woocommerce-admin/client/components/rating/test/index.js @@ -7,7 +7,9 @@ import { shallow } from 'enzyme'; /** * Internal dependencies */ -import { ReviewRating, ProductRating, Rating } from '../'; +import Rating from '../'; +import ProductRating from '../product'; +import ReviewRating from '../review'; describe( 'Rating', () => { test( 'should render the passed rating prop', () => { @@ -28,28 +30,22 @@ describe( 'Rating', () => { describe( 'ReviewRating', () => { test( 'should render rating based on review object', () => { - const rating = shallow( - - ); + const review = { + review: 'Nice T-shirt!', + rating: 1.5, + }; + const rating = shallow( ); expect( rating ).toMatchSnapshot(); } ); } ); describe( 'ProductRating', () => { test( 'should render rating based on product object', () => { - const rating = shallow( - - ); + const product = { + name: 'Test Product', + average_rating: 2.5, + }; + const rating = shallow( ); expect( rating ).toMatchSnapshot(); } ); } ); diff --git a/plugins/woocommerce-admin/client/dashboard/index.js b/plugins/woocommerce-admin/client/dashboard/index.js index 18eaa67b76b..db7efa21239 100644 --- a/plugins/woocommerce-admin/client/dashboard/index.js +++ b/plugins/woocommerce-admin/client/dashboard/index.js @@ -9,11 +9,11 @@ import { Component, Fragment } from '@wordpress/element'; * Internal dependencies */ import './style.scss'; +import { Card } from '@woocommerce/components'; +import ChartExample from 'components/chart/example'; import Header from 'layout/header'; import StorePerformance from './store-performance'; import TopSellingProducts from './top-selling-products'; -import Chart from 'components/chart/example'; -import Card from 'components/card'; export default class Dashboard extends Component { render() { @@ -21,7 +21,7 @@ export default class Dashboard extends Component {
- +
diff --git a/plugins/woocommerce-admin/client/dashboard/store-performance/index.js b/plugins/woocommerce-admin/client/dashboard/store-performance/index.js index 70e1e80831d..c808b1c4a10 100644 --- a/plugins/woocommerce-admin/client/dashboard/store-performance/index.js +++ b/plugins/woocommerce-admin/client/dashboard/store-performance/index.js @@ -9,9 +9,14 @@ import { Component } from '@wordpress/element'; /** * Internal dependencies */ -import Card from 'components/card'; -import { EllipsisMenu, MenuItem, MenuTitle } from 'components/ellipsis-menu'; -import { SummaryList, SummaryNumber } from 'components/summary'; +import { + Card, + EllipsisMenu, + MenuItem, + MenuTitle, + SummaryList, + SummaryNumber, +} from '@woocommerce/components'; import './style.scss'; class StorePerformance extends Component { diff --git a/plugins/woocommerce-admin/client/dashboard/top-selling-products/index.js b/plugins/woocommerce-admin/client/dashboard/top-selling-products/index.js index 32d04320fb6..6e299c79dbb 100644 --- a/plugins/woocommerce-admin/client/dashboard/top-selling-products/index.js +++ b/plugins/woocommerce-admin/client/dashboard/top-selling-products/index.js @@ -9,11 +9,10 @@ import { map } from 'lodash'; /** * Internal dependencies */ -import Card from 'components/card'; +import { Card, Table } from '@woocommerce/components'; import { getAdminLink } from 'lib/nav-utils'; import { numberFormat } from 'lib/number'; import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency'; -import { Table } from 'components/table'; import './style.scss'; // Mock data until we fetch from an API diff --git a/plugins/woocommerce-admin/client/index.js b/plugins/woocommerce-admin/client/index.js index c62c96202e7..25b619142f4 100644 --- a/plugins/woocommerce-admin/client/index.js +++ b/plugins/woocommerce-admin/client/index.js @@ -6,7 +6,6 @@ import { APIProvider } from '@wordpress/components'; import { pick } from 'lodash'; import { render } from '@wordpress/element'; import { Provider as SlotFillProvider } from 'react-slot-fill'; -import 'react-dates/initialize'; /** * Internal dependencies diff --git a/plugins/woocommerce-admin/client/layout/activity-panel/activity-card/test/index.js b/plugins/woocommerce-admin/client/layout/activity-panel/activity-card/test/index.js index c765db87af7..b643a346fd5 100644 --- a/plugins/woocommerce-admin/client/layout/activity-panel/activity-card/test/index.js +++ b/plugins/woocommerce-admin/client/layout/activity-panel/activity-card/test/index.js @@ -10,7 +10,7 @@ import { shallow } from 'enzyme'; * Internal dependencies */ import { ActivityCard } from '../'; -import Gravatar from 'components/gravatar'; +import { Gravatar } from '@woocommerce/components'; describe( 'ActivityCard', () => { test( 'should have correct title', () => { diff --git a/plugins/woocommerce-admin/client/layout/activity-panel/activity-header/index.js b/plugins/woocommerce-admin/client/layout/activity-panel/activity-header/index.js index cfb0adb2b90..1428a164fb3 100644 --- a/plugins/woocommerce-admin/client/layout/activity-panel/activity-header/index.js +++ b/plugins/woocommerce-admin/client/layout/activity-panel/activity-header/index.js @@ -10,7 +10,7 @@ import PropTypes from 'prop-types'; * Internal dependencies */ import './style.scss'; -import { EllipsisMenu } from 'components/ellipsis-menu'; +import { EllipsisMenu } from '@woocommerce/components'; import { H } from 'layout/section'; class ActivityHeader extends Component { diff --git a/plugins/woocommerce-admin/client/layout/activity-panel/activity-outbound-link/index.js b/plugins/woocommerce-admin/client/layout/activity-panel/activity-outbound-link/index.js index f8e63a53471..d93b2fd4fba 100644 --- a/plugins/woocommerce-admin/client/layout/activity-panel/activity-outbound-link/index.js +++ b/plugins/woocommerce-admin/client/layout/activity-panel/activity-outbound-link/index.js @@ -11,7 +11,7 @@ import Gridicon from 'gridicons'; * Internal dependencies */ import './style.scss'; -import Link from 'components/link'; +import { Link } from '@woocommerce/components'; const ActivityOutboundLink = props => { const { href, type, className, children, ...restOfProps } = props; diff --git a/plugins/woocommerce-admin/client/layout/activity-panel/panels/orders.js b/plugins/woocommerce-admin/client/layout/activity-panel/panels/orders.js index ebd3f6261d1..618b764ea90 100644 --- a/plugins/woocommerce-admin/client/layout/activity-panel/panels/orders.js +++ b/plugins/woocommerce-admin/client/layout/activity-panel/panels/orders.js @@ -14,12 +14,16 @@ import { noop } from 'lodash'; import { ActivityCard } from '../activity-card'; import ActivityHeader from '../activity-header'; import ActivityOutboundLink from '../activity-outbound-link'; -import { EllipsisMenu, MenuTitle, MenuItem } from 'components/ellipsis-menu'; +import { + EllipsisMenu, + Gravatar, + Flag, + MenuTitle, + MenuItem, + OrderStatus, +} from '@woocommerce/components'; import { formatCurrency, getCurrencyFormatDecimal } from 'lib/currency'; import { getOrderRefundTotal } from 'lib/order-values'; -import Gravatar from 'components/gravatar'; -import Flag from 'components/flag'; -import OrderStatus from 'components/order-status'; import { Section } from 'layout/section'; function OrdersPanel( { orders } ) { diff --git a/plugins/woocommerce-admin/client/layout/activity-panel/panels/reviews.js b/plugins/woocommerce-admin/client/layout/activity-panel/panels/reviews.js index 964fb13d4c7..ce2f220c0dc 100644 --- a/plugins/woocommerce-admin/client/layout/activity-panel/panels/reviews.js +++ b/plugins/woocommerce-admin/client/layout/activity-panel/panels/reviews.js @@ -13,12 +13,8 @@ import { noop } from 'lodash'; */ import { ActivityCard, ActivityCardPlaceholder } from '../activity-card'; import ActivityHeader from '../activity-header'; -import Gravatar from 'components/gravatar'; -import Link from 'components/link'; -import ProductImage from 'components/product-image'; -import { ReviewRating } from 'components/rating'; +import { Gravatar, Link, ProductImage, ReviewRating, SplitButton } from '@woocommerce/components'; import { Section } from 'layout/section'; -import SplitButton from 'components/split-button'; // TODO Pull proper data from the API const demoReviews = [ diff --git a/plugins/woocommerce-admin/client/layout/header/index.js b/plugins/woocommerce-admin/client/layout/header/index.js index bce5d0d2539..689f5526c1a 100644 --- a/plugins/woocommerce-admin/client/layout/header/index.js +++ b/plugins/woocommerce-admin/client/layout/header/index.js @@ -8,7 +8,6 @@ import classnames from 'classnames'; import { decodeEntities } from '@wordpress/html-entities'; import { Fill } from 'react-slot-fill'; import { isArray } from 'lodash'; -import Link from 'components/link'; import PropTypes from 'prop-types'; import ReactDom from 'react-dom'; @@ -17,6 +16,7 @@ import ReactDom from 'react-dom'; */ import './style.scss'; import ActivityPanel from '../activity-panel'; +import { Link } from '@woocommerce/components'; class Header extends Component { constructor() { diff --git a/plugins/woocommerce-admin/lib/client-assets.php b/plugins/woocommerce-admin/lib/client-assets.php index f525594ec96..637afca6305 100644 --- a/plugins/woocommerce-admin/lib/client-assets.php +++ b/plugins/woocommerce-admin/lib/client-assets.php @@ -1,4 +1,10 @@ admin_url(), - 'wcAssetUrl' => plugins_url( 'assets/', WC_PLUGIN_FILE ), - 'embedBreadcrumbs' => wc_admin_get_embed_breadcrumbs(), - 'siteLocale' => esc_attr( get_bloginfo( 'language' ) ), - 'currency' => wc_admin_currency_settings(), - 'date' => array( + 'adminUrl' => admin_url(), + 'wcAssetUrl' => plugins_url( 'assets/', WC_PLUGIN_FILE ), + 'embedBreadcrumbs' => wc_admin_get_embed_breadcrumbs(), + 'siteLocale' => esc_attr( get_bloginfo( 'language' ) ), + 'currency' => wc_admin_currency_settings(), + 'date' => array( 'dow' => get_option( 'start_of_week', 0 ), ), - 'orderStatuses' => wc_get_order_statuses(), - 'siteTitle' => get_bloginfo( 'name' ), + 'orderStatuses' => wc_get_order_statuses(), + 'siteTitle' => get_bloginfo( 'name' ), ); wp_add_inline_script( - WC_ADMIN_APP, - 'var wcSettings = '. json_encode( $settings ) . ';', + 'wc-components', + 'var wcSettings = ' . json_encode( $settings ) . ';', 'before' ); - // Resets lodash to wp-admin's version of lodash + // Resets lodash to wp-admin's version of lodash. wp_add_inline_script( WC_ADMIN_APP, '_.noConflict();', diff --git a/plugins/woocommerce-admin/tests/js/jest.config.json b/plugins/woocommerce-admin/tests/js/jest.config.json index a4b5a4da145..5541e2154b4 100644 --- a/plugins/woocommerce-admin/tests/js/jest.config.json +++ b/plugins/woocommerce-admin/tests/js/jest.config.json @@ -8,7 +8,8 @@ ], "moduleDirectories": ["node_modules", "/client"], "moduleNameMapper": { - "tinymce": "/tests/js/mocks/tinymce" + "tinymce": "/tests/js/mocks/tinymce", + "@woocommerce/components": "/client/components" }, "setupFiles": [ "/node_modules/@wordpress/jest-preset-default/scripts/setup-globals.js", diff --git a/plugins/woocommerce-admin/tests/js/setup-globals.js b/plugins/woocommerce-admin/tests/js/setup-globals.js index d2c44d51624..4da8f2f6ae8 100644 --- a/plugins/woocommerce-admin/tests/js/setup-globals.js +++ b/plugins/woocommerce-admin/tests/js/setup-globals.js @@ -14,6 +14,8 @@ global.wp = { }, }; +global.wc = {}; + Object.defineProperty( global.wp, 'element', { get: () => require( '@wordpress/element' ), } ); @@ -22,6 +24,10 @@ Object.defineProperty( global.wp, 'date', { get: () => require( '@wordpress/date' ), } ); +Object.defineProperty( global.wc, 'components', { + get: () => require( '@woocommerce/components' ), +} ); + global.wcSettings = { adminUrl: 'https://vagrant.local/wp/wp-admin/', locale: 'en-US', diff --git a/plugins/woocommerce-admin/webpack.config.js b/plugins/woocommerce-admin/webpack.config.js index bf1a85234b7..012bee0db8b 100644 --- a/plugins/woocommerce-admin/webpack.config.js +++ b/plugins/woocommerce-admin/webpack.config.js @@ -9,6 +9,7 @@ const ExtractTextPlugin = require( 'extract-text-webpack-plugin' ); const NODE_ENV = process.env.NODE_ENV || 'development'; const externals = { + '@woocommerce/components': { this: [ 'wc', 'components' ] }, '@wordpress/blocks': { this: [ 'wp', 'blocks' ] }, '@wordpress/components': { this: [ 'wp', 'components' ] }, '@wordpress/compose': { this: [ 'wp', 'compose' ] }, @@ -31,6 +32,7 @@ const webpackConfig = { mode: NODE_ENV, entry: { index: './client/index.js', + components: './client/components/index.js', embedded: './client/embedded.js', }, output: { @@ -85,9 +87,7 @@ const webpackConfig = { 'gutenberg-components': path.resolve( __dirname, 'node_modules/@wordpress/components/src' ), }, }, - plugins: [ - new ExtractTextPlugin( 'css/[name].css' ), - ], + plugins: [ new ExtractTextPlugin( 'css/[name].css' ) ], }; if ( webpackConfig.mode !== 'production' ) {