-
+ {/*
*/}
+
diff --git a/docs/src/components/Feedback/Feedback.tsx b/docs/src/components/Feedback/Feedback.tsx
new file mode 100644
index 00000000000..fd1835f6a68
--- /dev/null
+++ b/docs/src/components/Feedback/Feedback.tsx
@@ -0,0 +1,164 @@
+import React, {ReactNode, useRef, useState} from 'react';
+import {saTrack} from '@site/src/utils/segmentAnalytics';
+import styles from './styles.module.scss';
+export const Feedback = ({metadata}: {metadata: any}) => {
+ const [rating, setRating] = useState<1 | 2 | 3 | 4 | 5 | null>(null);
+ const [notes, setNotes] = useState
(null);
+ const [errorText, setErrorText] = useState(null);
+ const [hoveredScore, setHoveredScore] = useState(null);
+ const [textAreaLabel, setTextAreaLabel] = useState(null);
+ const [textAreaPlaceholder, setTextAreaPlaceholder] = useState('This section is optional ✌️');
+ const [isSubmitSuccess, setIsSubmitSuccess] = useState(false);
+
+ const submitDisabled = rating === null || (rating < 4 && (notes === null || notes === ''));
+
+ const scores: (1 | 2 | 3 | 4 | 5)[] = [1, 2, 3, 4, 5];
+
+ const handleSubmit = async () => {
+ if (rating === null) {
+ setErrorText('Please select a score.');
+ return;
+ }
+
+ if (rating < 4 && notes === null) {
+ setErrorText(
+ "Because this doc wasn't up to scratch please provide us with some feedback of where we can improve."
+ );
+ return;
+ }
+
+ const sendData = async () => {
+ const myHeaders = new Headers();
+ myHeaders.append('Content-Type', 'application/json');
+
+ const raw = JSON.stringify({
+ feedback: {
+ isHelpful: rating >= 4 ? `👍` : `👎`,
+ score: rating,
+ notes,
+ pageTitle: document.title,
+ url: window.location.href,
+ },
+ });
+
+ const requestOptions = {
+ method: 'POST',
+ headers: myHeaders,
+ body: raw,
+ redirect: 'follow',
+ }
+
+ fetch('https://us-central1-websitecloud-352908.cloudfunctions.net/docs-feedback', requestOptions)
+ .then(response => response.text())
+ .catch(error => console.error('error', error));
+ };
+
+ if (window.location.hostname === 'localhost') {
+ alert('Testing feedback (not) sent!');
+ setRating(null);
+ setNotes(null);
+ setIsSubmitSuccess(true);
+ return;
+ }
+
+ sendData().then(() => {
+ saTrack('Responded to Did You Find This Page Helpful', {
+ label: 'Responded to Did You Find This Page Helpful',
+ response: rating >= 4 ? 'YES' : 'NO',
+ pageUrl: window.location.href,
+ });
+ setRating(null);
+ setNotes(null);
+ setIsSubmitSuccess(true);
+ }).catch((e) => {console.error(e)});
+
+ return;
+ };
+
+ const handleScoreClick = (scoreItem: 1 | 2 | 3 | 4 | 5) => {
+ if (scoreItem === rating) {
+ setRating(null);
+ setErrorText(null);
+ setHoveredScore(null);
+ return
+ }
+ setErrorText(null);
+ setRating(scoreItem);
+ if (scoreItem < 4) {
+ setTextAreaLabel(<>
+ What can we do to improve it? Please be as detailed as you like.
+ Real human beings read every single review.
+ >);
+ setTextAreaPlaceholder('This section is required... how can we do better? ✍️');
+ }
+ if (scoreItem >= 4) {
+ setTextAreaLabel(
+ <>
+ Any general feedback you'd like to add?
+ We'll take it all... tell us how well we're doing or where we can improve.
+ Real human beings read every single review.
+ >
+ );
+ setTextAreaPlaceholder('This section is optional ✌️');
+ }
+ };
+
+ // Do not show on Intro page
+ if (metadata.source === '@site/docs/index.mdx') {
+ return null;
+ }
+
+ return (
+
+
+
+
What did you think of this doc?
+
+ {isSubmitSuccess ?
+
+
Thanks for your feedback.
+
Feel free to review as many docs pages as you like!
+
+ :
+ {scores.map((star, index) => (
+
handleScoreClick(star)}
+ onMouseEnter={() => setHoveredScore(index + 1)}
+ onMouseLeave={() => setHoveredScore(-1)}>
+ {rating >= star ? (
+
+ ) : (
+
+ )}
+
+ ))}
+
+ }
+
+
+
+
+ );
+};
diff --git a/docs/src/components/Feedback/ScrollToFeedbackButton.tsx b/docs/src/components/Feedback/ScrollToFeedbackButton.tsx
new file mode 100644
index 00000000000..b3e8b6774ed
--- /dev/null
+++ b/docs/src/components/Feedback/ScrollToFeedbackButton.tsx
@@ -0,0 +1,18 @@
+import styles from "./styles.module.scss";
+import Hand from "@site/static/img/mascot-hand.png";
+import React from "react";
+
+export const ScrollToFeedbackButton = () => {
+
+ const scrollToFeedback = () => {
+ const feedbackElement = document.getElementById('feedback');
+ const y = feedbackElement.getBoundingClientRect().top + window.scrollY - 100;
+ window.scrollTo({top: y, behavior: 'smooth'});
+ }
+
+ return (
+
+ Feedback 👋
+
+ )
+}
\ No newline at end of file
diff --git a/docs/src/components/Feedback/styles.module.scss b/docs/src/components/Feedback/styles.module.scss
new file mode 100644
index 00000000000..2f22b8160e1
--- /dev/null
+++ b/docs/src/components/Feedback/styles.module.scss
@@ -0,0 +1,191 @@
+.scrollToWrapper {
+ position: fixed;
+ display: grid;
+ place-items: center center;
+ color: white;
+ bottom: 85px;
+ right: 20px;
+ padding: 10px;
+ border-radius: 10px;
+ cursor: pointer;
+ background-color: var(--ifm-color-primary-light);
+ box-shadow: var(--ifm-global-shadow-tl);
+ font-size: 14px;
+
+ &:hover {
+ background-color: var(--ifm-color-primary);
+ }
+
+ &:active {
+ transform: translateY(3px);
+ }
+}
+
+
+.feedback {
+ height: 100%;
+ padding: 20px;
+ text-align: center;
+ width: 100%;
+ background-color: #f2f5f7;
+ margin-top: 2rem;
+ border-radius: 8px;
+}
+
+html[data-theme='dark'] {
+ .feedback {
+ background-color: var(--color-gray-82);
+ }
+}
+
+.numberRow {
+ display: flex;
+ margin-top: 15px;
+ height: 45px;
+ justify-content: center;
+}
+
+.numberCircle {
+ display: grid;
+ place-items: center center;
+ height: 30px;
+ width: 30px;
+ border-radius: 50%;
+ box-shadow: var(--ifm-global-shadow-tl);
+ padding: 0.25rem;
+ cursor: pointer;
+ background-color: white;
+}
+
+.numberActive {
+ display: grid;
+ place-items: center center;
+ height: 30px;
+ width: 30px;
+ border-radius: 50%;
+ box-shadow: var(--ifm-global-shadow-tl);
+ padding: 0.25rem;
+ cursor: pointer;
+ background-color: var(--ifm-color-primary);
+ color: white;
+}
+
+.form {
+ display: grid;
+ text-align: center;
+
+ h3 {
+ color: var(--ifm-heading-color);
+ margin-bottom: 0.5rem;
+ }
+
+ //p {
+ // margin-bottom: 0.5rem;
+ //}
+
+ input,
+ textarea {
+ border: none;
+ border-radius: 6px;
+ font-size: 1.1rem;
+ padding: 0.75rem;
+ font-family: var(--ifm-font-family-base);
+ color: var(--color-gray-74);
+ margin-top: 1rem;
+ box-shadow: var(--ifm-global-shadow-lw);
+ width: 100%;
+
+ &::placeholder {
+ color: var(--color-gray-36);
+ }
+ }
+
+ button {
+ //margin-top: 20px;
+ margin-left: auto;
+ background: var(--ifm-color-primary);
+ color: white;
+ font-weight: 500;
+ font-size: 16px;
+ font-family: var(--ifm-font-family-base);
+ border: none;
+ border-radius: 6px;
+ padding: 0.5rem 1rem;
+ cursor: pointer;
+ }
+}
+
+.textAreaLabel {
+ margin-top: 1rem;
+ p {
+ margin-bottom: 0.5rem;
+ }
+}
+
+.buttonDisabled {
+ background-color: var(--ifm-color-gray-500) !important;
+}
+
+html[data-theme='dark'] {
+ input,
+ textarea {
+ background-color: white;
+ }
+}
+
+.topSection {
+}
+
+.bottomSection {
+}
+
+.successMessage {
+ display: block;
+ place-items: center center;
+ width: 100%;
+ text-align: center;
+ color: var(--ifm-color-primary);
+ font-size: 1.1rem;
+ font-weight: 500;
+ font-family: var(--ifm-font-family-base);
+ p {
+ margin-bottom: 0 !important;
+ }
+}
+html[data-theme='dark'] {
+ .successMessage {
+ color: var(--ifm-color-primary-lighter);
+ }
+}
+
+
+.errorText {
+ color: var(--ifm-color-primary);
+ margin-top: .8rem;
+ margin-bottom: 1rem;
+ font-weight: 500;
+ font-size: 1.1rem;
+ font-family: var(--ifm-font-family-base);
+}
+html[data-theme='dark'] {
+ .errorText {
+ color: var(--ifm-color-primary-lighter);
+ }
+}
+
+.errorAndButton {
+}
+
+.buttonContainer {
+ display: flex;
+ justify-content: flex-end;
+}
+
+span {
+ transition: .1s ease-out;
+ cursor: pointer;
+ &:hover {
+ transform: translateY(-3px) scale(1.1);
+ transform-origin: center center;
+ }
+}
\ No newline at end of file
diff --git a/docs/src/components/PageHelpful/index.tsx b/docs/src/components/PageHelpful/index.tsx
deleted file mode 100644
index 8735fdd7e6c..00000000000
--- a/docs/src/components/PageHelpful/index.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-import React, { Fragment, useState } from 'react';
-import { saTrack } from '@site/src/utils/segmentAnalytics';
-import styles from './styles.module.scss';
-import Hand from '@site/static/img/mascot-hand.png';
-
-// Sleepy time for space between animations / state after submission
-function wait(ms = 0) {
- return new Promise((resolve) => {
- setTimeout(resolve, ms);
- });
-}
-
-const PageHelpful = () => {
- const [isExpanded, setIsExpanded] = useState(false);
- const [score, setScore] = useState(10);
- const [notes, setNotes] = useState('');
- const [hasResponse, setHasResponse] = useState(false);
-
- function handleNotes(e) {
- setNotes(e.target.value);
- }
-
- const scores = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-
- const recordResponse = async () => {
- // POST request to Cloud Function
- const sendData = async () => {
- var myHeaders = new Headers();
- myHeaders.append('Content-Type', 'application/json');
-
- var raw = JSON.stringify({
- feedback: {
- isHelpful: score >= 7 ? `👍` : `👎`,
- score,
- notes,
- pageTitle: document.title,
- url: window.location.href,
- },
- });
-
- var requestOptions = {
- method: 'POST',
- headers: myHeaders,
- body: raw,
- redirect: 'follow',
- };
-
- fetch('https://us-central1-websitecloud-352908.cloudfunctions.net/docs-feedback', requestOptions)
- .then((response) => response.text())
- .catch((error) => console.log('error', error));
- };
-
- sendData();
-
- // For testing, this has been commented out so as not to introduce noise into our analytics
- saTrack('Responded to Did You Find This Page Helpful', {
- label: 'Responded to Did You Find This Page Helpful',
- response: score >= 7 ? 'YES' : 'NO',
- pageUrl: window.location.href,
- });
-
- // Clear state for next response
- setHasResponse(true);
- setIsExpanded(false);
- setScore(10);
- setNotes('');
- await wait(1000);
- setHasResponse(false);
- };
-
- return (
- !isExpanded && setIsExpanded(true)}
- >
- {!isExpanded ? (
-
{!hasResponse ?
:
✅
}
- ) : (
-
-
-
-
Help us with some docs feedback!
-
On a scale of 1 to 10, how helpful would you rate this page?
-
1 meaning the page is not helpful at all and 10 meaning you found what you needed quickly.
-
- {scores.map((scoreItem) => (
-
setScore(scoreItem)}
- onKeyDown={() => setScore(scoreItem)}
- role='button'
- tabIndex={0}
- >
- {scoreItem}
-
- ))}
-
-
-
- Any general feedback you'd like to share? We'll take it all...tell us how well we're doing or where can
- improve!
-
-
-
- )}
-
- );
-};
-
-export default PageHelpful;
diff --git a/docs/src/components/PageHelpful/styles.module.scss b/docs/src/components/PageHelpful/styles.module.scss
deleted file mode 100644
index 098605ce8f0..00000000000
--- a/docs/src/components/PageHelpful/styles.module.scss
+++ /dev/null
@@ -1,177 +0,0 @@
-.wrapper {
- position: fixed;
- display: grid;
- place-items: center center;
- bottom: 75px;
- right: 15px;
- height: 60px;
- width: 60px;
- color: var(--docsearch-text-color);
- background: var(--ifm-card-background-color);
- border-radius: 50%;
- cursor: pointer;
- transition: cubic-bezier(1, 0, 0, 1) 0.5s;
- box-shadow: var(--ifm-global-shadow-tl);
-
- svg {
- height: 75%;
- width: 75%;
- cursor: pointer;
- color: var(--ifm-heading-color);
- }
-}
-
-.emoji {
- display: grid;
- place-items: center center;
- height: 100%;
- width: 100%;
-
- img {
- height: 35px;
- width: auto;
- }
-
- p {
- margin: 0;
- padding: 0;
- font-size: 1.5rem;
- }
-
- :hover {
- animation-name: wave-animation;
- animation-duration: 2.5s;
- animation-iteration-count: 1;
- transform-origin: 70% 70%;
- display: inline-block;
- }
-}
-
-.expanded {
- width: 80vw;
- height: 500px;
- padding: 20px 20px;
- opacity: 1;
- border-radius: 8px;
- z-index: 1000;
- cursor: default;
- overflow-y: scroll;
-
- // media query for mobile
- @media (max-width: 768px) {
- width: 90vw;
- height: 80svh;
- }
-}
-
-.feedback {
- display: grid;
- place-items: start start;
- height: 100%;
- width: 100%;
- padding: 20px;
- text-align: center;
-}
-
-.numberRow {
- display: flex;
- flex-wrap: wrap;
- gap: 10px;
- margin-top: 20px;
-
- div {
- display: grid;
- place-items: center center;
- height: 30px;
- width: 30px;
- border-radius: 50%;
- box-shadow: var(--ifm-global-shadow-tl);
- padding: 0.25rem;
- cursor: pointer;
- }
-
- :hover {
- box-shadow: var(--ifm-global-shadow-lw);
- }
-}
-
-.numberActive {
- background: var(--ifm-color-primary);
- color: white;
-}
-
-.close {
- position: absolute;
- height: 20px !important;
- width: 20px !important;
- top: 10px;
- right: 10px;
- cursor: pointer;
-}
-
-.form {
- display: grid;
- text-align: left;
-
- h3 {
- color: var(--ifm-heading-color);
- margin-bottom: 0.5rem;
- }
-
- p {
- margin-bottom: 0.5rem;
- }
-
- input,
- textarea {
- border: none;
- border-radius: 6px;
- font-size: 1.1rem;
- padding: 0.75rem;
- font-family: var(--ifm-font-family-base);
- // color: var(--color-gray-74);
- margin-top: 1rem;
- box-shadow: var(--ifm-global-shadow-lw);
- }
-
- button {
- margin-top: 20px;
- margin-left: auto;
- background: var(--ifm-color-primary);
- color: white;
- font-weight: 500;
- font-size: 16px;
- font-family: var(--ifm-font-family-base);
- border: none;
- border-radius: 6px;
- padding: 0.5rem 1rem;
- cursor: pointer;
- }
-}
-
-@keyframes wave-animation {
- 0% {
- transform: rotate(0deg);
- }
- 10% {
- transform: rotate(14deg);
- }
- 20% {
- transform: rotate(-8deg);
- }
- 30% {
- transform: rotate(14deg);
- }
- 40% {
- transform: rotate(-4deg);
- }
- 50% {
- transform: rotate(10deg);
- }
- 60% {
- transform: rotate(0deg);
- }
- 100% {
- transform: rotate(0deg);
- }
-}
diff --git a/docs/src/css/default-fonts-and-colors.scss b/docs/src/css/default-fonts-and-colors.scss
index 18344384763..0ce4134368f 100644
--- a/docs/src/css/default-fonts-and-colors.scss
+++ b/docs/src/css/default-fonts-and-colors.scss
@@ -81,6 +81,22 @@
--color-gray-8: #e7ebef;
--color-gray-12: #dce2e8;
--color-gray-16: #cfd8df;
+ //new
+ --color-gray-20: #c2d0d8;
+ --color-gray-24: #b6c6ce;
+ --color-gray-28: #a9bcc4;
+ --color-gray-32: #9db2ba;
+ --color-gray-36: #91a8b0;
+ --color-gray-40: #849ea6;
+ --color-gray-44: #78949c;
+ --color-gray-48: #6c8a92;
+ --color-gray-52: #608088;
+ --color-gray-56: #54767e;
+ --color-gray-60: #486c74;
+ --color-gray-64: #3c626a;
+ --color-gray-68: #305860;
+ --color-gray-72: #244e56;
+ //end new
--color-gray-74: #344658;
--color-gray-78: #2c3b4b;
--color-gray-82: #23303d;
diff --git a/docs/src/theme/DocItem/Footer/index.js b/docs/src/theme/DocItem/Footer/index.js
new file mode 100644
index 00000000000..e67a341bc32
--- /dev/null
+++ b/docs/src/theme/DocItem/Footer/index.js
@@ -0,0 +1,61 @@
+import React from 'react';
+import clsx from 'clsx';
+import { ThemeClassNames } from '@docusaurus/theme-common';
+import { useDoc } from '@docusaurus/theme-common/internal';
+import LastUpdated from '@theme/LastUpdated';
+import EditThisPage from '@theme/EditThisPage';
+import TagsListInline from '@theme/TagsListInline';
+import styles from './styles.module.css';
+import { Feedback } from '@site/src/components/Feedback/Feedback';
+function TagsRow(props) {
+ return (
+
+ );
+}
+function EditMetaRow({ editUrl, lastUpdatedAt, lastUpdatedBy, formattedLastUpdatedAt }) {
+ return (
+
+
{editUrl && }
+
+
+ {(lastUpdatedAt || lastUpdatedBy) && (
+
+ )}
+
+
+ );
+}
+export default function DocItemFooter() {
+ const { metadata } = useDoc();
+ const { editUrl, lastUpdatedAt, formattedLastUpdatedAt, lastUpdatedBy, tags } = metadata;
+ const canDisplayTagsRow = tags.length > 0;
+ const canDisplayEditMetaRow = !!(editUrl || lastUpdatedAt || lastUpdatedBy);
+ const canDisplayFooter = canDisplayTagsRow || canDisplayEditMetaRow;
+ if (!canDisplayFooter) {
+ return null;
+ }
+ return (
+ <>
+
+
+ >
+ );
+}
diff --git a/docs/src/theme/DocItem/Footer/styles.module.css b/docs/src/theme/DocItem/Footer/styles.module.css
new file mode 100644
index 00000000000..7c1e9644191
--- /dev/null
+++ b/docs/src/theme/DocItem/Footer/styles.module.css
@@ -0,0 +1,11 @@
+.lastUpdated {
+ margin-top: 0.2rem;
+ font-style: italic;
+ font-size: smaller;
+}
+
+@media (min-width: 997px) {
+ .lastUpdated {
+ text-align: right;
+ }
+}