Add Muriel Styled Spinner (https://github.com/woocommerce/woocommerce-admin/pull/2289)
* Add Muriel Styled Spinner * Handle PR feedback: Fix ordering of example components, fix tabbing/spacing in stepper example file, and fix base muriel colors for the stepper and profile wizard.
This commit is contained in:
parent
0e1db89f67
commit
c921593cfd
|
@ -25,6 +25,28 @@
|
|||
}
|
||||
}
|
||||
|
||||
.woocommerce-stepper .woocommerce-stepper__step {
|
||||
.woocommerce-stepper__step-label {
|
||||
color: $muriel-gray-800;
|
||||
}
|
||||
|
||||
&.is-active,
|
||||
&.is-complete {
|
||||
.woocommerce-stepper__step-icon {
|
||||
background: $muriel-gray-900;
|
||||
color: $muriel-white;
|
||||
}
|
||||
|
||||
.woocommerce-stepper__step-label {
|
||||
color: $muriel-gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-spinner__circle {
|
||||
stroke: $muriel-gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-profile-wizard__header {
|
||||
height: 56px;
|
||||
border-bottom: 1px solid $muriel-gray-50;
|
||||
|
@ -111,6 +133,7 @@
|
|||
.woocommerce-profile-wizard__plugins-actions {
|
||||
text-align: left;
|
||||
margin-left: 64px;
|
||||
min-height: 28px;
|
||||
|
||||
button {
|
||||
display: initial;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
{ "component": "SearchListControl" },
|
||||
{ "component": "Section" },
|
||||
{ "component": "SegmentedSelection" },
|
||||
{ "component": "Spinner" },
|
||||
{ "component": "SplitButton" },
|
||||
{ "component": "Stepper" },
|
||||
{ "component": "Summary", "render": "MySummaryList" },
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
- EllipsisMenu component (breaking change): Remove `children` prop in favor of a render prop `renderContent` so that function arguments `isOpen`, `onToggle`, and `onClose` can be passed down.
|
||||
- Chart has a new prop named `yBelow1Format` which overrides the `yFormat` for values between -1 and 1 (not included).
|
||||
- Add new component `<Stepper />` for showing a list of steps and progress.
|
||||
- Add new `<Spinner />` component.
|
||||
- Card component: updated default Muriel design.
|
||||
- Card component: new `description` prop.
|
||||
- Card component: new `isInactive` prop.
|
||||
|
|
|
@ -40,6 +40,7 @@ export { default as SearchListItem } from './search-list-control/item';
|
|||
export { default as SectionHeader } from './section-header';
|
||||
export { default as SegmentedSelection } from './segmented-selection';
|
||||
export { default as SplitButton } from './split-button';
|
||||
export { default as Spinner } from './spinner';
|
||||
export { default as Stepper } from './stepper';
|
||||
export { default as SummaryList } from './summary';
|
||||
export { default as SummaryListPlaceholder } from './summary/placeholder';
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
```jsx
|
||||
import { MySpinner } from '@woocommerce/components';
|
||||
|
||||
const MySpinner = () => (
|
||||
<div>
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
```
|
|
@ -0,0 +1,39 @@
|
|||
/** @format */
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { Component } from '@wordpress/element';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
|
||||
/**
|
||||
* Spinner - An indeterminate circular progress indicator.
|
||||
*/
|
||||
class Spinner extends Component {
|
||||
render() {
|
||||
const { className } = this.props;
|
||||
const classes = classnames( 'woocommerce-spinner', className );
|
||||
return (
|
||||
<svg className={ classes } viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle
|
||||
className="woocommerce-spinner__circle"
|
||||
fill="none"
|
||||
strokeWidth="5"
|
||||
strokeLinecap="round"
|
||||
cx="50"
|
||||
cy="50"
|
||||
r="30"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Spinner.propTypes = {
|
||||
/**
|
||||
* Additional class name to style the component.
|
||||
*/
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Spinner;
|
|
@ -0,0 +1,38 @@
|
|||
@keyframes rotate {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes growAndShrink {
|
||||
0%,
|
||||
100% {
|
||||
stroke-dashoffset: 200;
|
||||
}
|
||||
50% {
|
||||
stroke-dashoffset: 50;
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(450deg);
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-spinner {
|
||||
animation: rotate 2s linear infinite;
|
||||
width: 40px;
|
||||
min-width: 40px;
|
||||
height: 40px;
|
||||
max-height: 40px;
|
||||
}
|
||||
|
||||
.woocommerce-spinner__circle {
|
||||
stroke-dasharray: 200;
|
||||
stroke-dashoffset: 0;
|
||||
transform-origin: center;
|
||||
animation: growAndShrink 2s ease-in-out infinite;
|
||||
stroke: $muriel-gray-900;
|
||||
}
|
|
@ -2,73 +2,82 @@
|
|||
import { Stepper } from '@woocommerce/components';
|
||||
|
||||
const MyStepper = withState( {
|
||||
currentStep: 'first',
|
||||
isComplete: false,
|
||||
} )( ( { currentStep, isComplete, setState } ) => {
|
||||
const steps = [
|
||||
{
|
||||
label: 'First',
|
||||
key: 'first',
|
||||
},
|
||||
{
|
||||
label: 'Second',
|
||||
key: 'second',
|
||||
},
|
||||
{
|
||||
label: 'Third',
|
||||
key: 'third',
|
||||
},
|
||||
{
|
||||
label: 'Fourth',
|
||||
key: 'fourth',
|
||||
},
|
||||
];
|
||||
const currentIndex = steps.findIndex( s => currentStep === s.key );
|
||||
currentStep: 'first',
|
||||
isComplete: false,
|
||||
isPending: false,
|
||||
} )( ( { currentStep, isComplete, isPending, setState } ) => {
|
||||
const steps = [
|
||||
{
|
||||
label: 'First',
|
||||
key: 'first',
|
||||
},
|
||||
{
|
||||
label: 'Second',
|
||||
key: 'second',
|
||||
},
|
||||
{
|
||||
label: 'Third',
|
||||
key: 'third',
|
||||
},
|
||||
{
|
||||
label: 'Fourth',
|
||||
key: 'fourth',
|
||||
},
|
||||
];
|
||||
|
||||
if ( isComplete ) {
|
||||
steps.forEach( s => s.isComplete = true );
|
||||
}
|
||||
const currentIndex = steps.findIndex( s => currentStep === s.key );
|
||||
|
||||
return (
|
||||
<div>
|
||||
{ isComplete ? (
|
||||
<button onClick={ () => setState( { currentStep: 'first', isComplete: false } ) } >
|
||||
Reset
|
||||
</button>
|
||||
) : (
|
||||
<div>
|
||||
<button
|
||||
onClick={ () => setState( { currentStep: steps[ currentIndex - 1 ]['key'] } ) }
|
||||
disabled={ currentIndex < 1 }
|
||||
>
|
||||
Previous step
|
||||
</button>
|
||||
<button
|
||||
onClick={ () => setState( { currentStep: steps[ currentIndex + 1 ]['key'] } ) }
|
||||
disabled={ currentIndex >= steps.length - 1 }
|
||||
>
|
||||
Next step
|
||||
</button>
|
||||
<button
|
||||
onClick={ () => setState( { isComplete: true } ) }
|
||||
disabled={ currentIndex !== steps.length - 1 }
|
||||
>
|
||||
Complete
|
||||
</button>
|
||||
</div>
|
||||
) }
|
||||
if ( isComplete ) {
|
||||
steps.forEach( s => s.isComplete = true );
|
||||
}
|
||||
|
||||
<Stepper
|
||||
steps={ steps }
|
||||
currentStep={ currentStep }
|
||||
return (
|
||||
<div>
|
||||
{ isComplete ? (
|
||||
<button onClick={ () => setState( { currentStep: 'first', isComplete: false } ) } >
|
||||
Reset
|
||||
</button>
|
||||
) : (
|
||||
<div>
|
||||
<button
|
||||
onClick={ () => setState( { currentStep: steps[ currentIndex - 1 ]['key'] } ) }
|
||||
disabled={ currentIndex < 1 }
|
||||
>
|
||||
Previous step
|
||||
</button>
|
||||
<button
|
||||
onClick={ () => setState( { currentStep: steps[ currentIndex + 1 ]['key'] } ) }
|
||||
disabled={ currentIndex >= steps.length - 1 }
|
||||
>
|
||||
Next step
|
||||
</button>
|
||||
<button
|
||||
onClick={ () => setState( { isComplete: true } ) }
|
||||
disabled={ currentIndex !== steps.length - 1 }
|
||||
>
|
||||
Complete
|
||||
</button>
|
||||
<button
|
||||
onClick={ () => setState( { isPending: ! isPending } ) }
|
||||
>
|
||||
Toggle Spinner
|
||||
</button>
|
||||
</div>
|
||||
) }
|
||||
|
||||
<Stepper
|
||||
steps={ steps }
|
||||
currentStep={ currentStep }
|
||||
isPending={ isPending }
|
||||
/>
|
||||
|
||||
<Stepper
|
||||
isPending={ isPending }
|
||||
direction="vertical"
|
||||
steps={ steps }
|
||||
currentStep={ currentStep }
|
||||
/>
|
||||
|
||||
<Stepper
|
||||
direction="vertical"
|
||||
steps={ steps }
|
||||
currentStep={ currentStep }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} );
|
||||
```
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
import classnames from 'classnames';
|
||||
import { Component, Fragment } from '@wordpress/element';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Spinner } from '@wordpress/components';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import Spinner from '../spinner';
|
||||
import CheckIcon from './check-icon';
|
||||
|
||||
/**
|
||||
|
@ -32,8 +32,6 @@ class Stepper extends Component {
|
|||
'is-complete': 'undefined' !== typeof isComplete ? isComplete : currentIndex > i,
|
||||
} );
|
||||
|
||||
// @todo Update Spinner Styles
|
||||
// https://material.io/design/components/progress-indicators.html
|
||||
const icon = currentStep === key && isPending ? <Spinner /> : (
|
||||
<div className="woocommerce-stepper__step-icon">
|
||||
<span className="woocommerce-stepper__step-number">{ i + 1 }</span>
|
||||
|
@ -47,7 +45,7 @@ class Stepper extends Component {
|
|||
className={ stepClassName }
|
||||
>
|
||||
{ icon }
|
||||
<span className="woocommerce-stepper_step-label">
|
||||
<span className="woocommerce-stepper__step-label">
|
||||
{ label }
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.woocommerce-stepper {
|
||||
background: #fff;
|
||||
background: $muriel-white;
|
||||
box-shadow: $muriel-box-shadow-1dp;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
@ -15,26 +15,33 @@
|
|||
padding: $gap-small;
|
||||
font-weight: 400;
|
||||
color: $muriel-gray-900;
|
||||
height: 48px;
|
||||
|
||||
svg {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:not(.is-vertical).woocommerce-stepper_step-label {
|
||||
margin: 0 4px 0 4px;
|
||||
.woocommerce-spinner {
|
||||
display: block;
|
||||
margin-left: -$gap-smaller;
|
||||
margin-right: $gap-smallest;
|
||||
}
|
||||
|
||||
.woocommerce-spinner__circle {
|
||||
stroke: $muriel-hot-blue-500;
|
||||
}
|
||||
|
||||
&.is-active,
|
||||
&.is-complete {
|
||||
.woocommerce-stepper__step-icon,
|
||||
.components-spinner {
|
||||
background: $muriel-hot-orange-700;
|
||||
.woocommerce-stepper__step-icon {
|
||||
background: $muriel-hot-blue-500;
|
||||
color: $muriel-white;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
font-weight: 600;
|
||||
.woocommerce-stepper_step-label {
|
||||
.woocommerce-stepper__step-label {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
@ -49,8 +56,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.woocommerce-stepper__step-icon,
|
||||
.components-spinner {
|
||||
.woocommerce-stepper__step-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
@ -58,15 +64,11 @@
|
|||
height: 24px;
|
||||
min-width: 24px;
|
||||
margin-right: $gap-small;
|
||||
background: $muriel-gray-300;
|
||||
color: #fff;
|
||||
background: $muriel-gray-50;
|
||||
color: $muriel-gray-600;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.components-spinner {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.woocommerce-stepper__step-divider {
|
||||
flex-grow: 1;
|
||||
border-bottom: 1px solid $muriel-gray-50;
|
||||
|
@ -77,7 +79,7 @@
|
|||
}
|
||||
|
||||
@include breakpoint( '<782px' ) {
|
||||
.woocommerce-stepper_step-label {
|
||||
.woocommerce-stepper__step-label {
|
||||
display: none;
|
||||
padding-top: 24px;
|
||||
}
|
||||
|
@ -97,7 +99,7 @@
|
|||
margin-left: 24px;
|
||||
}
|
||||
|
||||
.woocommerce-stepper_step-label {
|
||||
.woocommerce-stepper__step-label {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
@import 'segmented-selection/style.scss';
|
||||
@import 'split-button/style.scss';
|
||||
@import 'stepper/style.scss';
|
||||
@import 'spinner/style.scss';
|
||||
@import 'summary/style.scss';
|
||||
@import 'table/style.scss';
|
||||
@import 'tag/style.scss';
|
||||
|
|
Loading…
Reference in New Issue