Monorepo with Turborepo (#651)

* Moved everything

* Figuring out how to make imports work

* Updated exports

* Added missing exports

* Added @vercel/commerce-local to `site`

* Updated commerce config

* Updated exports and commerce config

* Updated commerce hoc

* Fixed exports in local

* Added publish config

* Updated imports in site

* It's actually working

* Don't use debugger in dev for better speeds

* Improved DX when editing packages

* Set up eslint with husky

* Updated prettier config

* Added prettier setup to every package

* Moved bigcommerce

* Moved Bigcommerce to src and package updates

* Updated setup of bigcommerce

* Moved definitions script

* Moved commercejs

* Move to src

* Fixed types in commercejs

* Moved kibocommerce

* Moved kibocommerce to src

* Added package/tsconfig to kibocommerce

* Fixed imports and other things

* Moved ordercloud

* Moved ordercloud to src

* Fixed imports

* Added missing prettier files

* Moved Saleor

* Moved Saleor to src

* Fixed imports

* Replaced all imports to @commerce

* Added prettierignore/rc to all providers

* Moved shopify to src

* Build shopify in packages

* Moved Spree

* Moved spree to src

* Updated spree

* Moved swell

* Moved swell to src

* Fixed type imports in swell

* Moved Vendure to packages

* Moved vendure to src

* Fixed imports in vendure

* Added codegen to saleor

* Updated codegen setup for shopify

* Added codegen to vendure

* Added codegen to kibocommerce

* Added all packages to site's deps

* Updated codegen setup in bigcommerce

* Minor fixes

* Updated providers' names in site

* Updated packages based on Bel's changes

* Updated turbo to latest

* Fixed ts complains

* Set npm engine in root

* New lockfile install

* remove engines

* Regen lockfile

* Switched from npm to yarn

* Updated typesVersions in all packages

* Moved dep

* Updated SWR to the just released 1.2.0

* Removed "isolatedModules" from packages

* Updated list of providers and default

* Updated swell declaration

* Removed next import from kibocommerce

* Added COMMERCE_PROVIDER log

* Added another log

* Updated turbo config

* Updated docs

* Removed test logs

Co-authored-by: Jared Palmer <jared@jaredpalmer.com>
This commit is contained in:
Luis Alvarez D
2022-02-01 14:14:05 -05:00
committed by GitHub
parent d0ef346189
commit 0afe686fe9
1326 changed files with 9109 additions and 19494 deletions

View File

@@ -1,57 +0,0 @@
.root {
@apply bg-accent-9 text-accent-0 cursor-pointer inline-flex
px-10 py-5 leading-6 transition ease-in-out duration-150
shadow-sm text-center justify-center uppercase
border border-transparent items-center text-sm font-semibold
tracking-wide;
max-height: 64px;
}
.root:hover {
@apply border-accent-9 bg-accent-6;
}
.root:focus {
@apply shadow-outline-normal outline-none;
}
.root[data-active] {
@apply bg-accent-6;
}
.loading {
@apply bg-accent-1 text-accent-3 border-accent-2 cursor-not-allowed;
}
.slim {
@apply py-2 transform-none normal-case;
}
.ghost {
@apply border border-accent-2 bg-accent-0 text-accent-9 text-sm;
}
.ghost:hover {
@apply border-accent-9 bg-accent-9 text-accent-0;
}
.naked {
@apply bg-transparent font-semibold border-none shadow-none outline-none py-0 px-0;
}
.naked:hover,
.naked:focus {
@apply bg-transparent border-none;
}
.disabled,
.disabled:hover {
@apply text-accent-4 border-accent-2 bg-accent-1 cursor-not-allowed;
filter: grayscale(1);
-webkit-transform: translateZ(0);
-webkit-perspective: 1000;
-webkit-backface-visibility: hidden;
}
.progress {
}

View File

@@ -1,75 +0,0 @@
import cn from 'classnames'
import React, {
forwardRef,
ButtonHTMLAttributes,
JSXElementConstructor,
useRef,
} from 'react'
import mergeRefs from 'react-merge-refs'
import s from './Button.module.css'
import { LoadingDots } from '@components/ui'
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
href?: string
className?: string
variant?: 'flat' | 'slim' | 'ghost' | 'naked'
active?: boolean
type?: 'submit' | 'reset' | 'button'
Component?: string | JSXElementConstructor<any>
width?: string | number
loading?: boolean
disabled?: boolean
}
// eslint-disable-next-line react/display-name
const Button: React.FC<ButtonProps> = forwardRef((props, buttonRef) => {
const {
className,
variant = 'flat',
children,
active,
width,
loading = false,
disabled = false,
style = {},
Component = 'button',
...rest
} = props
const ref = useRef<typeof Component>(null)
const rootClassName = cn(
s.root,
{
[s.ghost]: variant === 'ghost',
[s.slim]: variant === 'slim',
[s.naked]: variant === 'naked',
[s.loading]: loading,
[s.disabled]: disabled,
},
className
)
return (
<Component
aria-pressed={active}
data-variant={variant}
ref={mergeRefs([ref, buttonRef])}
className={rootClassName}
disabled={disabled}
style={{
width,
...style,
}}
{...rest}
>
{children}
{loading && (
<i className="pl-2 m-0 flex">
<LoadingDots />
</i>
)}
</Component>
)
})
export default Button

View File

@@ -1,2 +0,0 @@
export { default } from './Button'
export * from './Button'

View File

@@ -1,25 +0,0 @@
.root {
@apply border-b border-accent-2 py-4 flex flex-col outline-none;
}
.header {
@apply flex flex-row items-center;
}
.header .label {
@apply text-base font-medium;
}
.content {
@apply pt-3 overflow-hidden pl-8;
}
.icon {
@apply mr-3 text-accent-6;
margin-left: -6px;
transition: transform 0.2s ease;
}
.icon.open {
transform: rotate(90deg);
}

View File

@@ -1,46 +0,0 @@
import cn from 'classnames'
import React, { FC, ReactNode, useState } from 'react'
import s from './Collapse.module.css'
import { ChevronRight } from '@components/icons'
import { useSpring, a } from '@react-spring/web'
import useMeasure from 'react-use-measure'
export interface CollapseProps {
title: string
children: ReactNode
}
const Collapse: FC<CollapseProps> = ({ title, children }) => {
const [isActive, setActive] = useState(false)
const [ref, { height: viewHeight }] = useMeasure()
const animProps = useSpring({
height: isActive ? viewHeight : 0,
config: { tension: 250, friction: 32, clamp: true, duration: 150 },
opacity: isActive ? 1 : 0,
})
const toggle = () => setActive((x) => !x)
return (
<div
className={s.root}
role="button"
tabIndex={0}
aria-expanded={isActive}
onClick={toggle}
>
<div className={s.header}>
<ChevronRight className={cn(s.icon, { [s.open]: isActive })} />
<span className={s.label}>{title}</span>
</div>
<a.div style={{ overflow: 'hidden', ...animProps }}>
<div ref={ref} className={s.content}>
{children}
</div>
</a.div>
</div>
)
}
export default React.memo(Collapse)

View File

@@ -1,2 +0,0 @@
export { default } from './Collapse'
export * from './Collapse'

View File

@@ -1,27 +0,0 @@
import cn from 'classnames'
import React, { FC } from 'react'
interface ContainerProps {
className?: string
children?: any
el?: HTMLElement
clean?: boolean
}
const Container: FC<ContainerProps> = ({
children,
className,
el = 'div',
clean,
}) => {
const rootClassName = cn(className, {
'mx-auto max-w-8xl px-6': !clean,
})
let Component: React.ComponentType<React.HTMLAttributes<HTMLDivElement>> =
el as any
return <Component className={rootClassName}>{children}</Component>
}
export default Container

View File

@@ -1 +0,0 @@
export { default } from './Container'

View File

@@ -1,135 +0,0 @@
.root {
@apply grid grid-cols-1 gap-0;
}
.root > * {
@apply row-span-1 bg-transparent box-border overflow-hidden;
height: 500px;
max-height: 800px;
}
.default > * {
@apply bg-transparent;
}
.layoutNormal {
@apply gap-3;
}
.layoutA {
& > *:nth-child(6n + 1),
& > *:nth-child(6n + 5) {
@apply row-span-2 lg:col-span-2;
height: var(--row-height);
}
&.filled {
& > *:nth-child(6n + 1) {
@apply bg-violet;
}
& > *:nth-child(6n + 2) {
@apply bg-accent-8;
}
& > *:nth-child(6n + 3) {
@apply bg-pink;
}
& > *:nth-child(6n + 6) {
@apply bg-cyan;
}
}
}
.layoutB {
& > *:nth-child(6n + 2),
& > *:nth-child(6n + 4) {
@apply row-span-2 lg:col-span-2;
height: var(--row-height);
}
&.filled {
& > *:nth-child(6n + 1) {
@apply bg-violet;
}
& > *:nth-child(6n + 2) {
@apply bg-accent-8;
}
& > *:nth-child(6n + 3) {
@apply bg-pink;
}
& > *:nth-child(6n + 6) {
@apply bg-cyan;
}
}
}
.layoutC {
& > *:nth-child(12n + 1),
& > *:nth-child(12n + 8) {
@apply row-span-2 lg:col-span-2;
height: var(--row-height);
}
&.filled {
& > *:nth-child(12n + 1) {
@apply bg-violet;
height: var(--row-height);
}
& > *:nth-child(12n + 8) {
@apply bg-cyan;
height: var(--row-height);
}
& > *:nth-child(6n + 3) {
@apply bg-pink;
}
}
}
.layoutD {
& > *:nth-child(12n + 2),
& > *:nth-child(12n + 7) {
@apply row-span-2 lg:col-span-2;
height: var(--row-height);
}
&.filled {
& > *:nth-child(12n + 2) {
@apply bg-violet;
}
& > *:nth-child(12n + 7) {
@apply bg-cyan;
}
& > *:nth-child(6n + 3) {
@apply bg-pink;
}
}
}
@screen md {
.layoutNormal > * {
max-height: min-content !important;
}
}
@screen lg {
.root {
@apply grid-cols-3 grid-rows-2;
}
.root > * {
@apply col-span-1;
height: inherit;
}
.layoutNormal > * {
max-height: 400px;
}
}

View File

@@ -1,34 +0,0 @@
import cn from 'classnames'
import { FC, ReactNode, Component } from 'react'
import s from './Grid.module.css'
interface GridProps {
className?: string
children?: ReactNode[] | Component[] | any[]
layout?: 'A' | 'B' | 'C' | 'D' | 'normal'
variant?: 'default' | 'filled'
}
const Grid: FC<GridProps> = ({
className,
layout = 'A',
children,
variant = 'default',
}) => {
const rootClassName = cn(
s.root,
{
[s.layoutA]: layout === 'A',
[s.layoutB]: layout === 'B',
[s.layoutC]: layout === 'C',
[s.layoutD]: layout === 'D',
[s.layoutNormal]: layout === 'normal',
[s.default]: variant === 'default',
[s.filled]: variant === 'filled',
},
className
)
return <div className={rootClassName}>{children}</div>
}
export default Grid

View File

@@ -1 +0,0 @@
export { default } from './Grid'

View File

@@ -1,30 +0,0 @@
.root {
@apply flex flex-col py-16 mx-auto;
}
.title {
@apply text-accent-0 font-extrabold text-4xl leading-none tracking-tight;
}
.description {
@apply mt-4 text-xl leading-8 text-accent-2 mb-1 lg:max-w-4xl;
}
@screen lg {
.root {
@apply flex-row items-start justify-center py-32;
}
.title {
@apply text-5xl max-w-xl text-right leading-10 -mt-3;
line-height: 3.5rem;
}
.description {
@apply mt-0 ml-6;
}
}
@screen xl {
.title {
@apply text-6xl;
}
}

View File

@@ -1,33 +0,0 @@
import React, { FC } from 'react'
import { Container } from '@components/ui'
import { ArrowRight } from '@components/icons'
import s from './Hero.module.css'
import Link from 'next/link'
interface HeroProps {
className?: string
headline: string
description: string
}
const Hero: FC<HeroProps> = ({ headline, description }) => {
return (
<div className="bg-accent-9 border-b border-t border-accent-2">
<Container>
<div className={s.root}>
<h2 className={s.title}>{headline}</h2>
<div className={s.description}>
<p>{description}</p>
<Link href="/">
<a className="flex items-center text-accent-0 pt-3 font-bold hover:underline cursor-pointer w-max-content">
Read it here
<ArrowRight width="20" heigh="20" className="ml-1" />
</a>
</Link>
</div>
</div>
</Container>
</div>
)
}
export default Hero

View File

@@ -1 +0,0 @@
export { default } from './Hero'

View File

@@ -1,7 +0,0 @@
.root {
@apply bg-primary py-2 px-6 w-full appearance-none transition duration-150 ease-in-out pr-10 border border-accent-3 text-accent-6;
}
.root:focus {
@apply outline-none shadow-outline-normal;
}

View File

@@ -1,37 +0,0 @@
import cn from 'classnames'
import s from './Input.module.css'
import React, { InputHTMLAttributes } from 'react'
export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
className?: string
onChange?: (...args: any[]) => any
}
const Input: React.FC<InputProps> = (props) => {
const { className, children, onChange, ...rest } = props
const rootClassName = cn(s.root, {}, className)
const handleOnChange = (e: any) => {
if (onChange) {
onChange(e.target.value)
}
return null
}
return (
<label>
<input
className={rootClassName}
onChange={handleOnChange}
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
{...rest}
/>
</label>
)
}
export default Input

View File

@@ -1 +0,0 @@
export { default } from './Input'

View File

@@ -1,11 +0,0 @@
import NextLink, { LinkProps as NextLinkProps } from 'next/link'
const Link: React.FC<NextLinkProps> = ({ href, children, ...props }) => {
return (
<NextLink href={href}>
<a {...props}>{children}</a>
</NextLink>
)
}
export default Link

View File

@@ -1 +0,0 @@
export { default } from './Link'

View File

@@ -1,33 +0,0 @@
.root {
@apply inline-flex text-center items-center leading-7;
}
.root .dot {
@apply rounded-full h-2 w-2;
background-color: currentColor;
animation-name: blink;
animation-duration: 1.4s;
animation-iteration-count: infinite;
animation-fill-mode: both;
margin: 0 2px;
}
.root .dot:nth-of-type(2) {
animation-delay: 0.2s;
}
.root .dot::nth-of-type(3) {
animation-delay: 0.4s;
}
@keyframes blink {
0% {
opacity: 0.2;
}
20% {
opacity: 1;
}
100% {
opacity: 0.2;
}
}

View File

@@ -1,13 +0,0 @@
import s from './LoadingDots.module.css'
const LoadingDots: React.FC = () => {
return (
<span className={s.root}>
<span className={s.dot} key={`dot_1`} />
<span className={s.dot} key={`dot_2`} />
<span className={s.dot} key={`dot_3`} />
</span>
)
}
export default LoadingDots

View File

@@ -1 +0,0 @@
export { default } from './LoadingDots'

View File

@@ -1,21 +0,0 @@
const Logo = ({ className = '', ...props }) => (
<svg
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
{...props}
>
<rect width="100%" height="100%" rx="16" fill="var(--secondary)" />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M17.6482 10.1305L15.8785 7.02583L7.02979 22.5499H10.5278L17.6482 10.1305ZM19.8798 14.0457L18.11 17.1983L19.394 19.4511H16.8453L15.1056 22.5499H24.7272L19.8798 14.0457Z"
fill="var(--primary)"
/>
</svg>
)
export default Logo

View File

@@ -1 +0,0 @@
export { default } from './Logo'

View File

@@ -1,22 +0,0 @@
.root {
@apply w-full min-w-full relative flex flex-row items-center overflow-hidden py-0;
max-height: 320px;
}
.root > div {
max-height: 320px;
padding: 0;
margin: 0;
}
.root > div > * > *:nth-child(2) * {
max-height: 100%;
}
.primary {
@apply bg-accent-0;
}
.secondary {
@apply bg-accent-9;
}

View File

@@ -1,39 +0,0 @@
import cn from 'classnames'
import s from './Marquee.module.css'
import { FC, ReactNode, Component, Children } from 'react'
import { default as FastMarquee } from 'react-fast-marquee'
interface MarqueeProps {
className?: string
children?: ReactNode[] | Component[] | any[]
variant?: 'primary' | 'secondary'
}
const Marquee: FC<MarqueeProps> = ({
className = '',
children,
variant = 'primary',
}) => {
const rootClassName = cn(
s.root,
{
[s.primary]: variant === 'primary',
[s.secondary]: variant === 'secondary',
},
className
)
return (
<FastMarquee gradient={false} className={rootClassName}>
{Children.map(children, (child) => ({
...child,
props: {
...child.props,
className: cn(child.props.className, `${variant}`),
},
}))}
</FastMarquee>
)
}
export default Marquee

View File

@@ -1 +0,0 @@
export { default } from './Marquee'

View File

@@ -1,17 +0,0 @@
.root {
@apply fixed bg-black bg-opacity-40 flex items-center inset-0 z-50 justify-center;
backdrop-filter: blur(0.8px);
-webkit-backdrop-filter: blur(0.8px);
}
.modal {
@apply bg-primary p-12 border border-accent-2 relative;
}
.modal:focus {
@apply outline-none;
}
.close {
@apply hover:text-accent-5 transition ease-in-out duration-150 focus:outline-none absolute right-0 top-0 m-6;
}

View File

@@ -1,55 +0,0 @@
import { FC, useRef, useEffect, useCallback } from 'react'
import s from './Modal.module.css'
import FocusTrap from '@lib/focus-trap'
import { Cross } from '@components/icons'
import { disableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock'
interface ModalProps {
className?: string
children?: any
onClose: () => void
onEnter?: () => void | null
}
const Modal: FC<ModalProps> = ({ children, onClose }) => {
const ref = useRef() as React.MutableRefObject<HTMLDivElement>
const handleKey = useCallback(
(e: KeyboardEvent) => {
if (e.key === 'Escape') {
return onClose()
}
},
[onClose]
)
useEffect(() => {
const modal = ref.current
if (modal) {
disableBodyScroll(modal, { reserveScrollBarGap: true })
window.addEventListener('keydown', handleKey)
}
return () => {
clearAllBodyScrollLocks()
window.removeEventListener('keydown', handleKey)
}
}, [handleKey])
return (
<div className={s.root}>
<div className={s.modal} role="dialog" ref={ref}>
<button
onClick={() => onClose()}
aria-label="Close panel"
className={s.close}
>
<Cross className="h-6 w-6" />
</button>
<FocusTrap focusFirst>{children}</FocusTrap>
</div>
</div>
)
}
export default Modal

View File

@@ -1 +0,0 @@
export { default } from './Modal'

View File

@@ -1,27 +0,0 @@
.actions {
@apply flex p-1 border-accent-2 border items-center justify-center
w-12 text-accent-7;
transition-property: border-color, background, color, transform, box-shadow;
transition-duration: 0.15s;
transition-timing-function: ease;
user-select: none;
}
.actions:hover {
@apply border bg-accent-1 border-accent-3 text-accent-9;
transition: border-color;
z-index: 10;
}
.actions:focus {
@apply outline-none;
}
.actions:disabled {
@apply cursor-not-allowed;
}
.input {
@apply bg-transparent px-4 w-full h-full focus:outline-none select-none pointer-events-auto;
}

View File

@@ -1,62 +0,0 @@
import React, { FC } from 'react'
import s from './Quantity.module.css'
import { Cross, Plus, Minus } from '@components/icons'
import cn from 'classnames'
export interface QuantityProps {
value: number
increase: () => any
decrease: () => any
handleRemove: React.MouseEventHandler<HTMLButtonElement>
handleChange: React.ChangeEventHandler<HTMLInputElement>
max?: number
}
const Quantity: FC<QuantityProps> = ({
value,
increase,
decrease,
handleChange,
handleRemove,
max = 6,
}) => {
return (
<div className="flex flex-row h-9">
<button className={s.actions} onClick={handleRemove}>
<Cross width={20} height={20} />
</button>
<label className="w-full border-accent-2 border ml-2">
<input
className={s.input}
onChange={(e) =>
Number(e.target.value) < max + 1 ? handleChange(e) : () => {}
}
value={value}
type="number"
max={max}
min="0"
readOnly
/>
</label>
<button
type="button"
onClick={decrease}
className={s.actions}
style={{ marginLeft: '-1px' }}
disabled={value <= 1}
>
<Minus width={18} height={18} />
</button>
<button
type="button"
onClick={increase}
className={cn(s.actions)}
style={{ marginLeft: '-1px' }}
disabled={value < 1 || value >= max}
>
<Plus width={18} height={18} />
</button>
</div>
)
}
export default Quantity

View File

@@ -1,2 +0,0 @@
export { default } from './Quantity'
export * from './Quantity'

View File

@@ -1,3 +0,0 @@
# UI
Building blocks to build a rich graphical interfaces. Components should be atomic and pure. Serve one purpose.

View File

@@ -1,25 +0,0 @@
import { FC, memo } from 'react'
import rangeMap from '@lib/range-map'
import { Star } from '@components/icons'
import cn from 'classnames'
export interface RatingProps {
value: number
}
const Quantity: FC<RatingProps> = ({ value = 5 }) => (
<div className="flex flex-row py-6 text-accent-9">
{rangeMap(5, (i) => (
<span
key={`star_${i}`}
className={cn('inline-block ml-1 ', {
'text-accent-5': i >= Math.floor(value),
})}
>
<Star />
</span>
))}
</div>
)
export default memo(Quantity)

View File

@@ -1,2 +0,0 @@
export { default } from './Rating'
export * from './Rating'

View File

@@ -1,14 +0,0 @@
.root {
@apply fixed inset-0 h-full z-50 box-border outline-none;
}
.sidebar {
@apply h-full flex flex-col text-base bg-accent-0 shadow-xl overflow-y-auto overflow-x-hidden;
-webkit-overflow-scrolling: touch !important;
}
.backdrop {
@apply absolute inset-0 bg-black bg-opacity-40 duration-100 ease-linear;
backdrop-filter: blur(0.8px);
-webkit-backdrop-filter: blur(0.8px);
}

View File

@@ -1,58 +0,0 @@
import { FC, useEffect, useRef } from 'react'
import s from './Sidebar.module.css'
import cn from 'classnames'
import { disableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock'
interface SidebarProps {
children: any
onClose: () => void
}
const Sidebar: FC<SidebarProps> = ({ children, onClose }) => {
const sidebarRef = useRef() as React.MutableRefObject<HTMLDivElement>
const contentRef = useRef() as React.MutableRefObject<HTMLDivElement>
const onKeyDownSidebar = (event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.code === 'Escape') {
onClose()
}
}
useEffect(() => {
if (sidebarRef.current) {
sidebarRef.current.focus()
}
const contentElement = contentRef.current
if (contentElement) {
disableBodyScroll(contentElement, { reserveScrollBarGap: true })
}
return () => {
clearAllBodyScrollLocks()
}
}, [])
return (
<div
className={cn(s.root)}
ref={sidebarRef}
onKeyDown={onKeyDownSidebar}
tabIndex={1}
>
<div className="absolute inset-0 overflow-hidden">
<div className={s.backdrop} onClick={onClose} />
<section className="absolute inset-y-0 right-0 w-full md:w-auto max-w-full flex outline-none md:pl-10">
<div className="h-full w-full md:w-screen md:max-w-md">
<div className={s.sidebar} ref={contentRef}>
{children}
</div>
</div>
</section>
</div>
</div>
)
}
export default Sidebar

View File

@@ -1 +0,0 @@
export { default } from './Sidebar'

View File

@@ -1,48 +0,0 @@
.skeleton {
@apply block;
background-image: linear-gradient(
270deg,
var(--accent-0),
var(--accent-2),
var(--accent-0),
var(--accent-1)
);
background-size: 400% 100%;
animation: loading 8s ease-in-out infinite;
}
.wrapper {
@apply block relative;
&:not(.show)::before {
content: none;
}
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 100;
background-image: linear-gradient(
270deg,
var(--accent-0),
var(--accent-2),
var(--accent-0),
var(--accent-1)
);
background-size: 400% 100%;
animation: loading 8s ease-in-out infinite;
}
}
@keyframes loading {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}

View File

@@ -1,57 +0,0 @@
import React, { CSSProperties } from 'react'
import cn from 'classnames'
import px from '@lib/to-pixels'
import s from './Skeleton.module.css'
interface SkeletonProps {
show?: boolean
block?: boolean
className?: string
style?: CSSProperties
width?: string | number
height?: string | number
boxHeight?: string | number
}
const Skeleton: React.FC<SkeletonProps> = ({
style,
width,
height,
children,
className,
show = true,
boxHeight = height,
}) => {
// Automatically calculate the size if there are children
// and no fixed sizes are specified
const shouldAutoSize = !!children && !(width || height)
// Defaults
width = width || 24
height = height || 24
boxHeight = boxHeight || height
return (
<span
className={cn(s.skeleton, className, {
[s.show]: show,
[s.wrapper]: shouldAutoSize,
[s.loaded]: !shouldAutoSize && !!children,
})}
style={
shouldAutoSize
? {}
: {
minWidth: px(width),
minHeight: px(height),
marginBottom: `calc(${px(boxHeight)} - ${px(height)})`,
...style,
}
}
>
{children}
</span>
)
}
export default Skeleton

View File

@@ -1 +0,0 @@
export { default } from './Skeleton'

View File

@@ -1,75 +0,0 @@
.body {
@apply text-base leading-7 max-w-6xl mx-auto;
}
.heading {
@apply text-5xl pt-1 pb-2 font-semibold tracking-wide cursor-pointer mb-2;
}
.pageHeading {
@apply pt-1 pb-4 text-2xl leading-7 font-bold tracking-wide;
}
.sectionHeading {
@apply pt-1 pb-2 text-2xl font-bold tracking-wide cursor-pointer mb-2;
}
/* Apply base font sizes and styles for typography markup (h2, h2, ul, p, etc.).
A helpful addition for whenn page content is consumed from a source managed through a wysiwyg editor. */
.body :is(h1, h2, h3, h4, h5, h6, p, ul, ol) {
@apply mb-4;
}
.body :is(h1, h2, h3, h4, h5, h6):not(:first-child) {
@apply mt-8;
}
.body :is(h1, h2, h3, h4, h5, h6) {
@apply font-semibold tracking-wide;
}
.body h1 {
@apply text-5xl;
}
.body h2 {
@apply text-4xl;
}
.body h3 {
@apply text-3xl;
}
.body h4 {
@apply text-2xl;
}
.body h5 {
@apply text-xl;
}
.body h6 {
@apply text-lg;
}
.body ul,
.body ol {
@apply pl-6;
}
.body ul {
@apply list-disc;
}
.body ol {
@apply list-decimal;
}
.body a {
@apply underline;
}
.body a:hover {
@apply no-underline;
}

View File

@@ -1,70 +0,0 @@
import React, {
FunctionComponent,
JSXElementConstructor,
CSSProperties,
} from 'react'
import cn from 'classnames'
import s from './Text.module.css'
interface TextProps {
variant?: Variant
className?: string
style?: CSSProperties
children?: React.ReactNode | any
html?: string
onClick?: () => any
}
type Variant = 'heading' | 'body' | 'pageHeading' | 'sectionHeading'
const Text: FunctionComponent<TextProps> = ({
style,
className = '',
variant = 'body',
children,
html,
onClick,
}) => {
const componentsMap: {
[P in Variant]: React.ComponentType<any> | string
} = {
body: 'div',
heading: 'h1',
pageHeading: 'h1',
sectionHeading: 'h2',
}
const Component:
| JSXElementConstructor<any>
| React.ReactElement<any>
| React.ComponentType<any>
| string = componentsMap![variant!]
const htmlContentProps = html
? {
dangerouslySetInnerHTML: { __html: html },
}
: {}
return (
<Component
className={cn(
s.root,
{
[s.body]: variant === 'body',
[s.heading]: variant === 'heading',
[s.pageHeading]: variant === 'pageHeading',
[s.sectionHeading]: variant === 'sectionHeading',
},
className
)}
onClick={onClick}
style={style}
{...htmlContentProps}
>
{children}
</Component>
)
}
export default Text

View File

@@ -1 +0,0 @@
export { default } from './Text'

View File

@@ -1,216 +0,0 @@
import React, { FC, useCallback, useMemo } from 'react'
import { ThemeProvider } from 'next-themes'
export interface State {
displaySidebar: boolean
displayDropdown: boolean
displayModal: boolean
sidebarView: string
modalView: string
userAvatar: string
}
const initialState = {
displaySidebar: false,
displayDropdown: false,
displayModal: false,
modalView: 'LOGIN_VIEW',
sidebarView: 'CART_VIEW',
userAvatar: '',
}
type Action =
| {
type: 'OPEN_SIDEBAR'
}
| {
type: 'CLOSE_SIDEBAR'
}
| {
type: 'OPEN_DROPDOWN'
}
| {
type: 'CLOSE_DROPDOWN'
}
| {
type: 'OPEN_MODAL'
}
| {
type: 'CLOSE_MODAL'
}
| {
type: 'SET_MODAL_VIEW'
view: MODAL_VIEWS
}
| {
type: 'SET_SIDEBAR_VIEW'
view: SIDEBAR_VIEWS
}
| {
type: 'SET_USER_AVATAR'
value: string
}
type MODAL_VIEWS =
| 'SIGNUP_VIEW'
| 'LOGIN_VIEW'
| 'FORGOT_VIEW'
| 'NEW_SHIPPING_ADDRESS'
| 'NEW_PAYMENT_METHOD'
type SIDEBAR_VIEWS = 'CART_VIEW' | 'CHECKOUT_VIEW' | 'PAYMENT_METHOD_VIEW'
export const UIContext = React.createContext<State | any>(initialState)
UIContext.displayName = 'UIContext'
function uiReducer(state: State, action: Action) {
switch (action.type) {
case 'OPEN_SIDEBAR': {
return {
...state,
displaySidebar: true,
}
}
case 'CLOSE_SIDEBAR': {
return {
...state,
displaySidebar: false,
}
}
case 'OPEN_DROPDOWN': {
return {
...state,
displayDropdown: true,
}
}
case 'CLOSE_DROPDOWN': {
return {
...state,
displayDropdown: false,
}
}
case 'OPEN_MODAL': {
return {
...state,
displayModal: true,
displaySidebar: false,
}
}
case 'CLOSE_MODAL': {
return {
...state,
displayModal: false,
}
}
case 'SET_MODAL_VIEW': {
return {
...state,
modalView: action.view,
}
}
case 'SET_SIDEBAR_VIEW': {
return {
...state,
sidebarView: action.view,
}
}
case 'SET_USER_AVATAR': {
return {
...state,
userAvatar: action.value,
}
}
}
}
export const UIProvider: FC = (props) => {
const [state, dispatch] = React.useReducer(uiReducer, initialState)
const openSidebar = useCallback(
() => dispatch({ type: 'OPEN_SIDEBAR' }),
[dispatch]
)
const closeSidebar = useCallback(
() => dispatch({ type: 'CLOSE_SIDEBAR' }),
[dispatch]
)
const toggleSidebar = useCallback(
() =>
state.displaySidebar
? dispatch({ type: 'CLOSE_SIDEBAR' })
: dispatch({ type: 'OPEN_SIDEBAR' }),
[dispatch, state.displaySidebar]
)
const closeSidebarIfPresent = useCallback(
() => state.displaySidebar && dispatch({ type: 'CLOSE_SIDEBAR' }),
[dispatch, state.displaySidebar]
)
const openDropdown = useCallback(
() => dispatch({ type: 'OPEN_DROPDOWN' }),
[dispatch]
)
const closeDropdown = useCallback(
() => dispatch({ type: 'CLOSE_DROPDOWN' }),
[dispatch]
)
const openModal = useCallback(
() => dispatch({ type: 'OPEN_MODAL' }),
[dispatch]
)
const closeModal = useCallback(
() => dispatch({ type: 'CLOSE_MODAL' }),
[dispatch]
)
const setUserAvatar = useCallback(
(value: string) => dispatch({ type: 'SET_USER_AVATAR', value }),
[dispatch]
)
const setModalView = useCallback(
(view: MODAL_VIEWS) => dispatch({ type: 'SET_MODAL_VIEW', view }),
[dispatch]
)
const setSidebarView = useCallback(
(view: SIDEBAR_VIEWS) => dispatch({ type: 'SET_SIDEBAR_VIEW', view }),
[dispatch]
)
const value = useMemo(
() => ({
...state,
openSidebar,
closeSidebar,
toggleSidebar,
closeSidebarIfPresent,
openDropdown,
closeDropdown,
openModal,
closeModal,
setModalView,
setSidebarView,
setUserAvatar,
}),
[state]
)
return <UIContext.Provider value={value} {...props} />
}
export const useUI = () => {
const context = React.useContext(UIContext)
if (context === undefined) {
throw new Error(`useUI must be used within a UIProvider`)
}
return context
}
export const ManagedUIContext: FC = ({ children }) => (
<UIProvider>
<ThemeProvider>{children}</ThemeProvider>
</UIProvider>
)

View File

@@ -1,16 +0,0 @@
export { default as Hero } from './Hero'
export { default as Logo } from './Logo'
export { default as Grid } from './Grid'
export { default as Button } from './Button'
export { default as Sidebar } from './Sidebar'
export { default as Marquee } from './Marquee'
export { default as Container } from './Container'
export { default as LoadingDots } from './LoadingDots'
export { default as Skeleton } from './Skeleton'
export { default as Modal } from './Modal'
export { default as Text } from './Text'
export { default as Input } from './Input'
export { default as Collapse } from './Collapse'
export { default as Quantity } from './Quantity'
export { default as Rating } from './Rating'
export { useUI } from './context'