docs: added Feedback component (#2274)
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
.inline-feedback {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.inline-question,
|
||||
.feedback-message {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.inline-feedback span,
|
||||
.inline-question span {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.inline-feedback span {
|
||||
margin-right: 13px;
|
||||
}
|
||||
|
||||
.inline-question span {
|
||||
margin-bottom: 13px;
|
||||
}
|
||||
|
||||
.feedback-btn {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
background-color: transparent;
|
||||
border: 1px solid #E5E7EB;
|
||||
color: var(--ifm-font-color-base);
|
||||
}
|
||||
|
||||
.feedback-btn:focus {
|
||||
box-shadow: 0px 0px 0px 4px rgba(124, 58, 237, 0.1);
|
||||
}
|
||||
|
||||
html:not([data-theme="dark"]) .feedback-btn:hover {
|
||||
background: #F3F4F6;
|
||||
}
|
||||
|
||||
html:not([data-theme="dark"]) .feedback-btn:active,
|
||||
html:not([data-theme="dark"]) .feedback-btn:disabled {
|
||||
background: #E5E7EB;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .feedback-btn,
|
||||
[data-theme="dark"] .inline-question textarea {
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.feedback-btn:not(:last-child) {
|
||||
margin-right: 13px;
|
||||
}
|
||||
|
||||
.inline-question .feedback-btn {
|
||||
margin-top: 13px;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.inline-question textarea {
|
||||
border-radius: 4px;
|
||||
background-color: transparent;
|
||||
border: 1px solid #E5E7EB;
|
||||
padding: 8px;
|
||||
font-family: var(--ifm-font-family-base);
|
||||
}
|
||||
|
||||
.feedback-message {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
-webkit-animation: fade-in .3s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
|
||||
animation: fade-in .3s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
|
||||
}
|
||||
|
||||
@-webkit-keyframes fade-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes fade-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.fade-out {
|
||||
-webkit-animation: fade-out .3s ease-out both;
|
||||
animation: fade-out .3s ease-out both;
|
||||
}
|
||||
|
||||
@-webkit-keyframes fade-out {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-out {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { CSSTransition, SwitchTransition } from 'react-transition-group';
|
||||
import './index.css';
|
||||
|
||||
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||
import {useLocation} from '@docusaurus/router';
|
||||
|
||||
export default function Feedback () {
|
||||
const [showForm, setShowForm] = useState(false);
|
||||
const [submittedFeedback, setSubmittedFeedback] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const inlineFeedbackRef = useRef(null);
|
||||
const inlineQuestionRef = useRef(null);
|
||||
const inlineMessageRef = useRef(null)
|
||||
const [positiveFeedback, setPositiveFeedbac] = useState(false);
|
||||
const [message, setMessage] = useState("");
|
||||
const nodeRef = submittedFeedback ? inlineMessageRef : (showForm ? inlineQuestionRef : inlineFeedbackRef);
|
||||
|
||||
const isBrowser = useIsBrowser();
|
||||
const location = useLocation();
|
||||
|
||||
function handleFeedback (e) {
|
||||
setPositiveFeedbac(e.target.classList.contains('positive'));
|
||||
setShowForm(true);
|
||||
}
|
||||
|
||||
function submitFeedback (e) {
|
||||
if (isBrowser) {
|
||||
if (window.analytics) {
|
||||
setLoading(true);
|
||||
window.analytics.track('survey', {
|
||||
url: location.pathname,
|
||||
label: document.title,
|
||||
feedback: positiveFeedback ? 'yes' : 'no',
|
||||
message
|
||||
}, function () {
|
||||
setLoading(false);
|
||||
setShowForm(false);
|
||||
setSubmittedFeedback(true);
|
||||
})
|
||||
} else {
|
||||
setShowForm(false);
|
||||
setSubmittedFeedback(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='feedback-container'>
|
||||
<SwitchTransition mode="out-in">
|
||||
<CSSTransition
|
||||
key={showForm}
|
||||
nodeRef={nodeRef}
|
||||
timeout={300}
|
||||
addEndListener={(done) => {
|
||||
nodeRef.current.addEventListener("transitionend", done, false);
|
||||
}}
|
||||
classNames={{
|
||||
enter: 'fade-in',
|
||||
exit: 'fade-out'
|
||||
}}
|
||||
>
|
||||
<>
|
||||
{(!showForm && !submittedFeedback) && (
|
||||
<div className='inline-feedback' ref={inlineFeedbackRef}>
|
||||
<span>Was this page helpful?</span>
|
||||
<button className='positive feedback-btn' onClick={handleFeedback}>Yes</button>
|
||||
<button className='negative feedback-btn' onClick={handleFeedback}>No</button>
|
||||
</div>
|
||||
)}
|
||||
{(showForm && !submittedFeedback) && (
|
||||
<div className='inline-question' ref={inlineQuestionRef}>
|
||||
<span>{positiveFeedback ? 'What was most helpful?' : 'What can we improve?'}</span>
|
||||
<textarea rows={4} value={message} onChange={(e) => setMessage(e.target.value)}></textarea>
|
||||
<button className='feedback-btn' onClick={submitFeedback} disabled={loading}>Submit</button>
|
||||
</div>
|
||||
)}
|
||||
{submittedFeedback && (
|
||||
<div className='feedback-message' ref={inlineMessageRef}>
|
||||
Thank you for helping improve our documentation!
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</CSSTransition>
|
||||
</SwitchTransition>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user