Просмотр исходного кода

Improve `StatusImage` animation

Added animation to alerts (i.e. delete confirmation, errors).
Reversed animation direction so that it appears like it is drawn from
left to right, instead of right to left (the same direction used for
multiple selection checkmark symbol in dropdown component)
Sergiu Miclea 8 лет назад
Родитель
Сommit
9451f63a56

+ 23 - 7
src/components/atoms/StatusImage/StatusImage.jsx

@@ -23,6 +23,7 @@ import Palette from '../../styleUtils/Palette'
 import errorImage from './images/error'
 import successImage from './images/success'
 import loadingImage from './images/loading.svg'
+import questionImage from './images/question'
 
 type Props = {
   status?: string,
@@ -54,15 +55,25 @@ const dashAnimationStyle = css`
   .circle {
     stroke-dasharray: 300;
     stroke-dashoffset: 300;
-    animation: dash 300ms ease-in-out forwards;
+    animation: circleDash 300ms ease-in-out 100ms forwards;
   }
   .path {
     stroke-dasharray: 60;
     stroke-dashoffset: 60;
-    animation: dash 300ms ease-in-out forwards;
+    animation: pathDash 300ms ease-in-out 100ms forwards;
   }
-  @keyframes dash {
-    to { stroke-dashoffset: 0; }
+  .dot {
+    fill-opacity: 0;
+    animation: appear 300ms ease-in-out 100ms forwards;
+  }
+  @keyframes appear {
+    to { fill-opacity: 1; }
+  }
+  @keyframes circleDash {
+    to { stroke-dashoffset: 600; }
+  }
+  @keyframes pathDash {
+    to { stroke-dashoffset: 120; }
   }
 `
 const loadingAnimationStyle = css`
@@ -90,6 +101,10 @@ const Images = {
     style: loadingAnimationStyle,
     image: '',
   },
+  QUESTION: {
+    image: questionImage,
+    style: dashAnimationStyle,
+  },
 }
 @observer
 class StatusImage extends React.Component<Props> {
@@ -132,9 +147,10 @@ class StatusImage extends React.Component<Props> {
   }
 
   render() {
-    let status = this.props.status || ''
+    let status = this.props.status || 'QUESTION'
     status = status.toUpperCase()
     status = status === 'SUCCESS' ? 'COMPLETED' : status
+    status = status === 'CONFIRMATION' ? 'QUESTION' : status
     if (this.props.loading) {
       status = 'RUNNING'
       if (this.props.loadingProgress !== undefined && this.props.loadingProgress > -1) {
@@ -147,8 +163,8 @@ class StatusImage extends React.Component<Props> {
         {status !== 'PROGRESS' ? (
           <Image
             data-test-id="statusImage-image"
-            dangerouslySetInnerHTML={{ __html: Images[status || 'RUNNING'].image }}
-            cssStyle={Images[status || 'RUNNING'].style}
+            dangerouslySetInnerHTML={{ __html: Images[status].image }}
+            cssStyle={Images[status].style}
           />
         ) : null}
         {status === 'PROGRESS' ? this.renderProgressImage() : null}

+ 16 - 0
src/components/atoms/StatusImage/images/question.js

@@ -0,0 +1,16 @@
+export default `<?xml version="1.0" encoding="UTF-8"?>
+<svg width="96px" height="96px" viewBox="0 0 96 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
+    <title>Icon/Question/Red96</title>
+    <desc>Created with Sketch.</desc>
+    <defs></defs>
+    <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="Icon/Question/Red96">
+            <g id="Group" transform="translate(39.750000, 30.750000)">
+                <path class="path" d="M7.43292882,27.75 L7.43292882,22.9296826 C7.43292882,19.8274093 9.2399564,16.9006131 12.129714,15.4306856 C15.1045372,13.8815894 16.8529273,10.6168976 16.4399868,7.26895625 C16.0270463,3.51374455 12.962202,0.484926772 9.16232359,0.0768403025 C8.91373342,-0.0064093374 8.58751043,0.00012004612 8.2588098,0.00012004612 C6.19410735,0.00012004612 4.30366579,0.733043346 2.73614369,2.0405524 C1.00014187,3.58964864 0,5.87574904 0,8.16184944" id="Page-1" stroke="#F91661" stroke-width="1.5"></path>
+                <rect class="dot" id="Rectangle-2" fill="#F91661" x="6" y="31.5" width="3" height="3" rx="0.75"></rect>
+            </g>
+            <circle class="circle" id="Oval-5" stroke="#F91661" stroke-width="1.5" cx="48" cy="48" r="47"></circle>
+        </g>
+    </g>
+</svg>`

+ 3 - 0
src/components/atoms/StatusImage/story.jsx

@@ -53,3 +53,6 @@ storiesOf('StatusImage', module)
   .add('error', () => (
     <StatusImage status="ERROR" />
   ))
+  .add('question', () => (
+    <StatusImage status="QUESTION" />
+  ))

+ 3 - 9
src/components/organisms/AlertModal/AlertModal.jsx

@@ -25,9 +25,6 @@ import StatusImage from '../../atoms/StatusImage'
 import Palette from '../../styleUtils/Palette'
 import KeyboardManager from '../../../utils/KeyboardManager'
 
-import questionImage from './images/question.svg'
-import errorImage from './images/error.svg'
-
 const Wrapper = styled.div`
   display: flex;
   flex-direction: column;
@@ -35,11 +32,6 @@ const Wrapper = styled.div`
   justify-content: center;
   padding: 48px;
 `
-const Image = styled.div`
-  width: 96px;
-  height: 96px;
-  background: url('${props => props.type === 'error' ? errorImage : questionImage}');
-`
 const Message = styled.div`
   font-size: 18px;
   text-align: center;
@@ -112,10 +104,12 @@ class AlertModal extends React.Component<Props> {
   }
 
   render() {
+    let status = this.props.type === 'loading' ? 'RUNNING' : (this.props.type || 'confirmation')
+
     return (
       <Modal {...this.props}>
         <Wrapper data-test-id="alertModal">
-          {this.props.type === 'loading' ? <StatusImage loading data-test-id="aModal-status" /> : <Image type={this.props.type} data-test-id="aModal-image" />}
+          {<StatusImage status={status} data-test-id="aModal-status" />}
           {this.props.message ? <Message data-test-id="aModal-message">{this.props.message}</Message> : null}
           {this.props.extraMessage ? <ExtraMessage data-test-id="aModal-extraMessage">{this.props.extraMessage}</ExtraMessage> : null}
           {this.renderConfirmationButtons()}

+ 0 - 18
src/components/organisms/AlertModal/images/error.svg

@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="96px" height="96px" viewBox="0 0 96 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
-    <title>User-VL Copy</title>
-    <desc>Created with Sketch.</desc>
-    <defs></defs>
-    <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="Modal/Icon64-Message/2-Buttons" transform="translate(-240.000000, -96.000000)" stroke="#F91661" stroke-width="1.5">
-            <g id="Group" transform="translate(32.000000, 96.000000)">
-                <g id="Icon/Error/Red-96" transform="translate(208.000000, 0.000000)">
-                    <circle id="Oval-2" cx="48" cy="48" r="47"></circle>
-                    <path d="M68.5714286,27.4285714 L27.4285714,68.5714286" id="Line"></path>
-                    <path d="M68.5714286,68.5714286 L27.4285714,27.4285714" id="Line-Copy"></path>
-                </g>
-            </g>
-        </g>
-    </g>
-</svg>

+ 0 - 16
src/components/organisms/AlertModal/images/question.svg

@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="96px" height="96px" viewBox="0 0 96 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
-    <title>Icon/Question/Red96</title>
-    <desc>Created with Sketch.</desc>
-    <defs></defs>
-    <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="Icon/Question/Red96">
-            <g id="Group" transform="translate(39.750000, 30.750000)">
-                <path d="M7.43292882,27.75 L7.43292882,22.9296826 C7.43292882,19.8274093 9.2399564,16.9006131 12.129714,15.4306856 C15.1045372,13.8815894 16.8529273,10.6168976 16.4399868,7.26895625 C16.0270463,3.51374455 12.962202,0.484926772 9.16232359,0.0768403025 C8.91373342,-0.0064093374 8.58751043,0.00012004612 8.2588098,0.00012004612 C6.19410735,0.00012004612 4.30366579,0.733043346 2.73614369,2.0405524 C1.00014187,3.58964864 0,5.87574904 0,8.16184944" id="Page-1" stroke="#F91661" stroke-width="1.5"></path>
-                <rect id="Rectangle-2" fill="#F91661" x="6" y="31.5" width="3" height="3" rx="0.75"></rect>
-            </g>
-            <circle id="Oval-5" stroke="#F91661" stroke-width="1.5" cx="48" cy="48" r="47"></circle>
-        </g>
-    </g>
-</svg>

+ 2 - 2
src/components/organisms/AlertModal/test.jsx

@@ -26,7 +26,7 @@ describe('AlertModal Component', () => {
     let wrapper = wrap({ message: 'alert-message', extraMessage: 'alert-extra' })
     expect(wrapper.findText('message')).toBe('alert-message')
     expect(wrapper.findText('extraMessage')).toBe('alert-extra')
-    expect(wrapper.find('image').prop('type')).toBe('confirmation')
+    expect(wrapper.find('status').prop('status')).toBe('confirmation')
     expect(wrapper.find('noButton').length).toBe(1)
     expect(wrapper.find('yesButton').length).toBe(1)
     expect(wrapper.find('dismissButton').length).toBe(0)
@@ -47,7 +47,7 @@ describe('AlertModal Component', () => {
 
   it('renders loading', () => {
     let wrapper = wrap({ message: 'alert-message', extraMessage: 'alert-extra', type: 'loading' })
-    expect(wrapper.find('status').prop('loading')).toBe(true)
+    expect(wrapper.find('status').prop('status')).toBe('RUNNING')
     expect(wrapper.find('noButton').length).toBe(0)
     expect(wrapper.find('yesButton').length).toBe(0)
     expect(wrapper.find('dismissButton').length).toBe(0)