preview bar

This commit is contained in:
Joel Varty 2021-06-23 10:21:22 -04:00
parent 4929032e5f
commit 00922a8c7d
11 changed files with 396 additions and 139 deletions

View File

@ -0,0 +1,15 @@
import { CgSpinner } from "react-icons/cg";
const Widget = ({ message }) => {
return (
<section
id="loading-widget"
className="flex flex-col items-center justify-center h-screen"
>
<CgSpinner className="animate-spin text-2xl mb-2" />
<p>{message}</p>
</section>
);
};
export default Widget;

View File

@ -0,0 +1,155 @@
import React, { useState } from "react";
import {
FaInfoCircle,
FaGithub,
FaChevronDown,
FaChevronUp,
} from "react-icons/fa";
/**
* This is a preview bar that is enabled by default to handle viewing content in preview & live mode, remove this for production use.
**/
const PreviewBar = ({ isPreview, isDevelopmentMode }) => {
const [open, setOpen] = useState(false);
// handle view function to determine preview / live mode
const handleView = () => {
if (isDevelopmentMode) {
alert("You are currently in Development Mode, Live Mode is unavailable.");
} else {
if (!isDevelopmentMode && !isPreview) {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
// Process our return data
if (xhr.status >= 200 && xhr.status < 300) {
// What do when the request is successful
const previewKey = xhr.responseText;
window.location.replace(
`${window.location.pathname}?agilitypreviewkey=${escape(
previewKey
)}`
);
}
};
// Create and send a GET request
xhr.open("GET", "/api/generatePreviewKey");
xhr.send();
} else {
const exit = confirm("Would you like to exit Preview Mode?");
if (exit === true) {
window.location.href = `/api/exitPreview?slug=${window.location.pathname}`;
} else return;
}
}
};
return (
<div className="bg-agility relative px-8 text-gray-200">
<div className="flex justify-between items-center max-w-screen-xl mx-auto">
<div className="flex items-center">
<span className="p-2 rounded-lg mr-4">
<a
href="https://www.agilitycms.com"
target="_blank"
title="Agility CMS"
>
<img
src="https://static.agilitycms.com/brand/agility-triangle-yellow.svg"
alt="Agility CMS"
className="w-5 h-5 block md:hidden"
/>
<img
src="/assets/agility-preview-logo.svg"
alt="Agility CMS"
className="h-5 w-20 hidden md:block"
/>
</a>
</span>
<div className="mr-4">
<a
href="https://help.agilitycms.com/hc/en-us"
target="_blank"
title="Help Center"
>
<div className="flex items-center">
<FaInfoCircle className="text-2xl mr-2" />
<p className="hidden md:block text-sm">Help Center</p>
</div>
</a>
</div>
<div>
<a
href="https://github.com/agility/agilitycms-nextjs-starter"
target="_blank"
title="View on GitHub"
className="text-2xl"
>
<div className="flex items-center">
<FaGithub className="mr-2" />
<p className="hidden md:block text-sm">View on GitHub</p>
</div>
</a>
</div>
</div>
<div
className={`relative flex items-center ${
open ? `bg-white ` : `bg-agility`
} py-4`}
>
{isPreview ? (
<p
className={`hidden md:block text-sm px-2 ${
open ? `text-agility` : `text-gray-200`
}`}
>
Previewing <span className="font-bold">Latest</span> Changes
</p>
) : (
<p
className={`hidden md:block text-sm px-2 ${
open ? `text-agility` : `text-gray-200`
}`}
>
Viewing <span className="font-bold">Published</span> Content
</p>
)}
<div
className="p-2 text-gray-200 rounded-lg cursor-pointer z-50"
onClick={() => setOpen(!open)}
>
{open ? (
<FaChevronUp className="text-agility" />
) : (
<FaChevronDown className="text-gray-200" />
)}
</div>
<div
className="absolute bg-white text-white text-sm py-4 px-4 -right-0 -bottom-28 md:-bottom-16 z-50 rounded-b-lg shadow-xl md:max-w-full"
style={{ display: open ? "block" : "none", width: "15.1rem" }}
>
{isPreview ? (
<p className="mb-4 text-center md:hidden text-agility z-20">
Previewing <span className="font-bold">Latest</span> Changes
</p>
) : (
<p className="mb-4 text-center md:hidden text-agility z-20">
Viewing <span className="font-bold">Published</span> Content
</p>
)}
<button
className="text-gray-200 bg-agility p-2 w-full rounded-md text-sm"
onClick={() => handleView()}
>
{`View ${isPreview ? `Live` : `Preview`} Mode`}
</button>
</div>
</div>
</div>
</div>
);
};
export default PreviewBar;

View File

@ -13,122 +13,138 @@ import { useAcceptCookies } from '@lib/hooks/useAcceptCookies'
import { Sidebar, Button, Modal, LoadingDots } from '@components/ui'
import PaymentMethodView from '@components/checkout/PaymentMethodView'
import CheckoutSidebarView from '@components/checkout/CheckoutSidebarView'
import { handlePreview } from "@agility/nextjs";
import LoginView from '@components/auth/LoginView'
import s from './Layout.module.css'
import LoadingWidget from '@components/agility-common/LoadingWidget'
import PreviewBar from '@components/agility-common/PreviewBar'
const Loading = () => (
<div className="w-80 h-80 flex items-center text-center justify-center p-3">
<LoadingDots />
</div>
<div className="w-80 h-80 flex items-center text-center justify-center p-3">
<LoadingDots />
</div>
)
const dynamicProps = {
loading: () => <Loading />,
loading: () => <Loading />,
}
const SignUpView = dynamic(
() => import('@components/auth/SignUpView'),
dynamicProps
() => import('@components/auth/SignUpView'),
dynamicProps
)
const ForgotPassword = dynamic(
() => import('@components/auth/ForgotPassword'),
dynamicProps
() => import('@components/auth/ForgotPassword'),
dynamicProps
)
const FeatureBar = dynamic(
() => import('@components/common/FeatureBar'),
dynamicProps
() => import('@components/common/FeatureBar'),
dynamicProps
)
interface Props {
pageProps: {
pages?: Page[]
categories: Category[],
agilityProps: any
}
pageProps: {
pages?: Page[]
categories: Category[],
agilityProps: any
}
}
const ModalView: FC<{ modalView: string; closeModal(): any }> = ({
modalView,
closeModal,
modalView,
closeModal,
}) => {
return (
<Modal onClose={closeModal}>
{modalView === 'LOGIN_VIEW' && <LoginView />}
{modalView === 'SIGNUP_VIEW' && <SignUpView />}
{modalView === 'FORGOT_VIEW' && <ForgotPassword />}
</Modal>
)
return (
<Modal onClose={closeModal}>
{modalView === 'LOGIN_VIEW' && <LoginView />}
{modalView === 'SIGNUP_VIEW' && <SignUpView />}
{modalView === 'FORGOT_VIEW' && <ForgotPassword />}
</Modal>
)
}
const ModalUI: FC = () => {
const { displayModal, closeModal, modalView } = useUI()
return displayModal ? (
<ModalView modalView={modalView} closeModal={closeModal} />
) : null
const { displayModal, closeModal, modalView } = useUI()
return displayModal ? (
<ModalView modalView={modalView} closeModal={closeModal} />
) : null
}
const SidebarView: FC<{ sidebarView: string; closeSidebar(): any }> = ({
sidebarView,
closeSidebar,
sidebarView,
closeSidebar,
}) => {
return (
<Sidebar onClose={closeSidebar}>
{sidebarView === 'CART_VIEW' && <CartSidebarView />}
{sidebarView === 'CHECKOUT_VIEW' && <CheckoutSidebarView />}
{sidebarView === 'PAYMENT_VIEW' && <PaymentMethodView />}
{sidebarView === 'SHIPPING_VIEW' && <ShippingView />}
</Sidebar>
)
return (
<Sidebar onClose={closeSidebar}>
{sidebarView === 'CART_VIEW' && <CartSidebarView />}
{sidebarView === 'CHECKOUT_VIEW' && <CheckoutSidebarView />}
{sidebarView === 'PAYMENT_VIEW' && <PaymentMethodView />}
{sidebarView === 'SHIPPING_VIEW' && <ShippingView />}
</Sidebar>
)
}
const SidebarUI: FC = () => {
const { displaySidebar, closeSidebar, sidebarView } = useUI()
return displaySidebar ? (
<SidebarView sidebarView={sidebarView} closeSidebar={closeSidebar} />
) : null
const { displaySidebar, closeSidebar, sidebarView } = useUI()
return displaySidebar ? (
<SidebarView sidebarView={sidebarView} closeSidebar={closeSidebar} />
) : null
}
const Layout: FC<Props> = (props) => {
// set up handle preview
const isPreviewLoading = handlePreview();
const {
children,
pageProps: { agilityProps, ...pageProps },
} = props
} = props
const { acceptedCookies, onAcceptCookies } = useAcceptCookies()
const { locale = 'en-US' } = useRouter()
const { acceptedCookies, onAcceptCookies } = useAcceptCookies()
const { locale = 'en-US' } = useRouter()
const categories = agilityProps?.globalData?.sitedata?.categoryLinks || []
const categories = agilityProps?.globalData?.sitedata?.categoryLinks || []
const navBarlinks = categories.slice(0, 2).map((c:any) => ({
label: c.name,
href: `/search/${c.slug}`,
}))
const navBarlinks = categories.slice(0, 2).map((c: any) => ({
label: c.name,
href: `/search/${c.slug}`,
}))
return (
<CommerceProvider locale={locale}>
<div className={cn(s.root)}>
<Navbar links={navBarlinks} agilityProps={agilityProps}/>
<main className="fit">{children}</main>
<Footer pages={pageProps.pages} agilityProps={agilityProps} />
<ModalUI />
<SidebarUI />
<FeatureBar
title="This site uses cookies to improve your experience. By clicking, you agree to our Privacy Policy."
hide={acceptedCookies}
action={
<Button className="mx-5" onClick={() => onAcceptCookies()}>
Accept cookies
</Button>
}
/>
</div>
</CommerceProvider>
)
return (
<CommerceProvider locale={locale}>
<div className={cn(s.root)}>
{isPreviewLoading &&
<LoadingWidget message="Loading Preview Mode" />
}
{!isPreviewLoading &&
<>
<PreviewBar isDevelopmentMode={agilityProps.isDevelopmentMode} isPreview={agilityProps.isPreview}/>
<Navbar links={navBarlinks} agilityProps={agilityProps} />
<main className="fit">{children}</main>
<Footer pages={pageProps.pages} agilityProps={agilityProps} />
<ModalUI />
<SidebarUI />
<FeatureBar
title="This site uses cookies to improve your experience. By clicking, you agree to our Privacy Policy."
hide={acceptedCookies}
action={
<Button className="mx-5" onClick={() => onAcceptCookies()}>
Accept cookies
</Button>
}
/>
</>
}
</div>
</CommerceProvider>
)
}
export default Layout

View File

@ -53,6 +53,7 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-fast-marquee": "^1.1.3",
"react-icons": "^4.2.0",
"react-merge-refs": "^1.1.0",
"react-use-measure": "^2.0.4",
"shopify-buy": "^2.11.0",

9
pages/api/exitPreview.js Normal file
View File

@ -0,0 +1,9 @@
export default async (req, res) => {
// Clears the preview mode cookies.
// This function accepts no arguments.
res.clearPreviewData()
// Redirect to the slug
res.writeHead(307, { Location: req.query.slug })
res.end()
}

View File

@ -0,0 +1,12 @@
import { generatePreviewKey } from "@agility/nextjs/node"
export default async (req, res) => {
//TODO: Only generate the preview link if you are already in Preview!
//how can I check if i'm in preview mode already?
const previewKey = generatePreviewKey();
//Return a valid preview key
res.end(previewKey)
}

35
pages/api/preview.js Normal file
View File

@ -0,0 +1,35 @@
import { validatePreview, getDynamicPageURL } from '@agility/nextjs/node'
// A simple example for testing it manually from your browser.
// If this is located at pages/api/preview.js, then
// open /api/preview from your browser.
export default async (req, res) => {
//validate our preview key, also validate the requested page to preview exists
const validationResp = await validatePreview({
agilityPreviewKey: req.query.agilitypreviewkey,
slug: req.query.slug
});
if (validationResp.error) {
return res.status(401).end(`${validationResp.message}`)
}
let previewUrl = req.query.slug;
//TODO: these kinds of dynamic links should work by default (even outside of preview)
if(req.query.ContentID) {
const dynamicPath = await getDynamicPageURL({contentID: req.query.ContentID, preview: true, slug: req.query.slug});
if(dynamicPath) {
previewUrl = dynamicPath;
}
}
//enable preview mode
res.setPreviewData({})
// Redirect to the slug
res.writeHead(307, { Location: previewUrl })
res.end()
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 247.19 63.55"><defs><style>.cls-1{fill:#717171;}.cls-1,.cls-2{fill-rule:evenodd;}.cls-2{fill:#ffcb28;}</style></defs><title>Asset 1</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><g id="Layer_1-2-2" data-name="Layer 1-2"><path class="cls-1" d="M99.51,48.14a21.07,21.07,0,0,0,6.91-1.08V40.51A17.66,17.66,0,0,0,98.94,39c-3.71,0-6.34,1.2-6.34,4.27,0,2.91,2.28,4.84,6.91,4.84M110.93,34.3V49.63a27.11,27.11,0,0,1-11.47,2.62c-8.23,0-11.6-3.76-11.6-8.72,0-5.47,4.8-8.54,11.08-8.54a19.91,19.91,0,0,1,7.48,1.36V34.3c0-4-2.62-6.2-7.36-6.2a13,13,0,0,0-7.66,2.45,4.25,4.25,0,0,1-2.34-3.08c1.71-1.71,5.65-3.65,10.22-3.65,6.46,0,11.65,3,11.65,10.48m28.38,10.48v-15A10.07,10.07,0,0,0,133.25,28c-5.71,0-9.65,3.93-9.65,9.57s3.94,9.17,9.65,9.17a9.17,9.17,0,0,0,6.06-2m4.62-17.48v23.5c0,6.72-5.19,11.85-12.85,11.85-4.74,0-9-1.48-11.76-4.67a5.41,5.41,0,0,1,3-3.13,11.06,11.06,0,0,0,8.79,3.7c5.71,0,8.23-3.42,8.23-7.75V49.23a14.25,14.25,0,0,1-6.46,1.59c-7.65,0-14-5-14-13.21,0-8,6-13.79,14.39-13.79A17.84,17.84,0,0,1,144,27.3m9.9,24.51V24.93a11.46,11.46,0,0,1,2.34-.23,10.35,10.35,0,0,1,2.29.23V51.82a12.43,12.43,0,0,1-4.63,0m-1-34.75a3.26,3.26,0,1,1,3.31,3.25,3.26,3.26,0,0,1-3.31-3.25v0m16,34.4V14.05a11.64,11.64,0,0,1,4.63,0V51.48a11.55,11.55,0,0,1-2.35.22,10.88,10.88,0,0,1-2.28-.22m15,.34V24.93a11.46,11.46,0,0,1,2.34-.23,10.35,10.35,0,0,1,2.29.23V51.82a12.43,12.43,0,0,1-4.63,0m-1-34.75a3.26,3.26,0,1,1,3.31,3.25,3.26,3.26,0,0,1-3.31-3.25v0m34.76,32.71a11.62,11.62,0,0,1-7.54,2.85c-5.42,0-9.37-2.57-9.37-9V29h-4.62a7,7,0,0,1-.23-1.88,6.66,6.66,0,0,1,.23-1.83h4.62V18.05a10.35,10.35,0,0,1,2.29-.23,9.82,9.82,0,0,1,2.23.23v7.24H215.9a6.58,6.58,0,0,1,.22,1.82A7,7,0,0,1,215.9,29H205.23V42.71c0,4.84,2.28,5.87,5.19,5.87a8.81,8.81,0,0,0,5.14-2,5.16,5.16,0,0,1,2.06,3.25m29.57-24.39c-4.45,17-9.54,27.23-19.53,38.11a4.55,4.55,0,0,1-3.26-2.79,63,63,0,0,0,7.26-9.4,98.66,98.66,0,0,1-10.8-26.09,9.55,9.55,0,0,1,2.86-.4,12.79,12.79,0,0,1,2.05.17A103.05,103.05,0,0,0,234,46.58l.45.86c.12-.29.29-.52.4-.8A91.25,91.25,0,0,0,242.51,25a11.84,11.84,0,0,1,1.88-.17,7.91,7.91,0,0,1,2.8.57"/><path class="cls-2" d="M42.92,53.29H17.28L36.61,19.9,55.94,53.29l5.64,9.94H73.22L36.61,0,0,63.23H47.42Z"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 247.19 63.55"><defs><style>.cls-1{fill:#fff;}.cls-1,.cls-2{fill-rule:evenodd;}.cls-2{fill:#ffcb28;}</style></defs><title>Asset 1</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><g id="Layer_1-2-2" data-name="Layer 1-2"><path class="cls-1" d="M99.51,48.14a21.07,21.07,0,0,0,6.91-1.08V40.51A17.66,17.66,0,0,0,98.94,39c-3.71,0-6.34,1.2-6.34,4.27,0,2.91,2.28,4.84,6.91,4.84M110.93,34.3V49.63a27.11,27.11,0,0,1-11.47,2.62c-8.23,0-11.6-3.76-11.6-8.72,0-5.47,4.8-8.54,11.08-8.54a19.91,19.91,0,0,1,7.48,1.36V34.3c0-4-2.62-6.2-7.36-6.2a13,13,0,0,0-7.66,2.45,4.25,4.25,0,0,1-2.34-3.08c1.71-1.71,5.65-3.65,10.22-3.65,6.46,0,11.65,3,11.65,10.48m28.38,10.48v-15A10.07,10.07,0,0,0,133.25,28c-5.71,0-9.65,3.93-9.65,9.57s3.94,9.17,9.65,9.17a9.17,9.17,0,0,0,6.06-2m4.62-17.48v23.5c0,6.72-5.19,11.85-12.85,11.85-4.74,0-9-1.48-11.76-4.67a5.41,5.41,0,0,1,3-3.13,11.06,11.06,0,0,0,8.79,3.7c5.71,0,8.23-3.42,8.23-7.75V49.23a14.25,14.25,0,0,1-6.46,1.59c-7.65,0-14-5-14-13.21,0-8,6-13.79,14.39-13.79A17.84,17.84,0,0,1,144,27.3m9.9,24.51V24.93a11.46,11.46,0,0,1,2.34-.23,10.35,10.35,0,0,1,2.29.23V51.82a12.43,12.43,0,0,1-4.63,0m-1-34.75a3.26,3.26,0,1,1,3.31,3.25,3.26,3.26,0,0,1-3.31-3.25v0m16,34.4V14.05a11.64,11.64,0,0,1,4.63,0V51.48a11.55,11.55,0,0,1-2.35.22,10.88,10.88,0,0,1-2.28-.22m15,.34V24.93a11.46,11.46,0,0,1,2.34-.23,10.35,10.35,0,0,1,2.29.23V51.82a12.43,12.43,0,0,1-4.63,0m-1-34.75a3.26,3.26,0,1,1,3.31,3.25,3.26,3.26,0,0,1-3.31-3.25v0m34.76,32.71a11.62,11.62,0,0,1-7.54,2.85c-5.42,0-9.37-2.57-9.37-9V29h-4.62a7,7,0,0,1-.23-1.88,6.66,6.66,0,0,1,.23-1.83h4.62V18.05a10.35,10.35,0,0,1,2.29-.23,9.82,9.82,0,0,1,2.23.23v7.24H215.9a6.58,6.58,0,0,1,.22,1.82A7,7,0,0,1,215.9,29H205.23V42.71c0,4.84,2.28,5.87,5.19,5.87a8.81,8.81,0,0,0,5.14-2,5.16,5.16,0,0,1,2.06,3.25m29.57-24.39c-4.45,17-9.54,27.23-19.53,38.11a4.55,4.55,0,0,1-3.26-2.79,63,63,0,0,0,7.26-9.4,98.66,98.66,0,0,1-10.8-26.09,9.55,9.55,0,0,1,2.86-.4,12.79,12.79,0,0,1,2.05.17A103.05,103.05,0,0,0,234,46.58l.45.86c.12-.29.29-.52.4-.8A91.25,91.25,0,0,0,242.51,25a11.84,11.84,0,0,1,1.88-.17,7.91,7.91,0,0,1,2.8.57"/><path class="cls-2" d="M42.92,53.29H17.28L36.61,19.9,55.94,53.29l5.64,9.94H73.22L36.61,0,0,63.23H47.42Z"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,71 +1,78 @@
module.exports = {
future: {
purgeLayersByDefault: true,
applyComplexClasses: true,
},
purge: {
content: [
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
],
options: {
safelist: {
standard: ['outline-none'],
},
},
},
theme: {
extend: {
maxWidth: {
'8xl': '1920px',
},
colors: {
primary: 'var(--primary)',
'primary-2': 'var(--primary-2)',
secondary: 'var(--secondary)',
'secondary-2': 'var(--secondary-2)',
hover: 'var(--hover)',
'hover-1': 'var(--hover-1)',
'hover-2': 'var(--hover-2)',
'accent-0': 'var(--accent-0)',
'accent-1': 'var(--accent-1)',
'accent-2': 'var(--accent-2)',
'accent-3': 'var(--accent-3)',
'accent-4': 'var(--accent-4)',
'accent-5': 'var(--accent-5)',
'accent-6': 'var(--accent-6)',
'accent-7': 'var(--accent-7)',
'accent-8': 'var(--accent-8)',
'accent-9': 'var(--accent-9)',
violet: 'var(--violet)',
'violet-light': 'var(--violet-light)',
'violet-dark': 'var(--violet-dark)',
pink: 'var(--pink)',
'pink-light': 'var(--pink-light)',
cyan: 'var(--cyan)',
blue: 'var(--blue)',
green: 'var(--green)',
red: 'var(--red)',
},
textColor: {
base: 'var(--text-base)',
primary: 'var(--text-primary)',
secondary: 'var(--text-secondary)',
},
boxShadow: {
'outline-normal': '0 0 0 2px var(--accent-2)',
magical:
'rgba(0, 0, 0, 0.02) 0px 30px 30px, rgba(0, 0, 0, 0.03) 0px 0px 8px, rgba(0, 0, 0, 0.05) 0px 1px 0px',
},
lineHeight: {
'extra-loose': '2.2',
},
scale: {
120: '1.2',
},
},
},
plugins: [
require('@tailwindcss/typography'),
],
future: {
purgeLayersByDefault: true,
applyComplexClasses: true,
},
purge: {
content: [
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
],
options: {
safelist: {
standard: ['outline-none'],
},
},
},
theme: {
extend: {
maxWidth: {
'8xl': '1920px',
},
colors: {
transparent: "transparent",
black: "#000",
white: "#fff",
agility: "#222",
primary: 'var(--primary)',
'primary-2': 'var(--primary-2)',
secondary: 'var(--secondary)',
'secondary-2': 'var(--secondary-2)',
hover: 'var(--hover)',
'hover-1': 'var(--hover-1)',
'hover-2': 'var(--hover-2)',
'accent-0': 'var(--accent-0)',
'accent-1': 'var(--accent-1)',
'accent-2': 'var(--accent-2)',
'accent-3': 'var(--accent-3)',
'accent-4': 'var(--accent-4)',
'accent-5': 'var(--accent-5)',
'accent-6': 'var(--accent-6)',
'accent-7': 'var(--accent-7)',
'accent-8': 'var(--accent-8)',
'accent-9': 'var(--accent-9)',
violet: 'var(--violet)',
'violet-light': 'var(--violet-light)',
'violet-dark': 'var(--violet-dark)',
pink: 'var(--pink)',
'pink-light': 'var(--pink-light)',
cyan: 'var(--cyan)',
blue: 'var(--blue)',
green: 'var(--green)',
red: 'var(--red)',
},
textColor: {
base: 'var(--text-base)',
primary: 'var(--text-primary)',
secondary: 'var(--text-secondary)',
},
boxShadow: {
'outline-normal': '0 0 0 2px var(--accent-2)',
magical:
'rgba(0, 0, 0, 0.02) 0px 30px 30px, rgba(0, 0, 0, 0.03) 0px 0px 8px, rgba(0, 0, 0, 0.05) 0px 1px 0px',
},
lineHeight: {
'extra-loose': '2.2',
},
scale: {
120: '1.2',
},
},
},
plugins: [
require('@tailwindcss/typography'),
],
}

View File

@ -5744,6 +5744,11 @@ react-fast-marquee@^1.1.3:
resolved "https://registry.yarnpkg.com/react-fast-marquee/-/react-fast-marquee-1.1.3.tgz#8f1f397c64258bdee0e915147d503828ab74d695"
integrity sha512-DIfrpWMgIHEoEPWKYzs5dnV5ZSMuu0+4ddRG4qB6Ee2zDi5LuPAGc1gnOceG8j8tvnuSrdkaqYYQwLZ61VzU5w==
react-icons@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.2.0.tgz#6dda80c8a8f338ff96a1851424d63083282630d0"
integrity sha512-rmzEDFt+AVXRzD7zDE21gcxyBizD/3NqjbX6cmViAgdqfJ2UiLer8927/QhhrXQV7dEj/1EGuOTPp7JnLYVJKQ==
react-is@16.13.1, react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"