docs: refactor to use TypeScript, ESLint, and Tailwind CSS (#4136)
* docs(refactoring): configured eslint and typescript (#3511) * docs: configured eslint and typescript * fixed yarn.lock * docs(refactoring): migrate components directory to typescript (#3517) * docs: migrate components directory to typescript * removed vscode settings * fix following merge * docs: refactored QueryNote component (#3576) * docs: refactored first batch of theme components (#3579) * docs: refactored second batch of theme components (#3580) * added missing badge styles * fix after merge * docs(refactoring): migrated remaining component to TypeScript (#3770) * docs(refactoring): configured eslint and typescript (#3511) * docs: configured eslint and typescript * fixed yarn.lock * docs(refactoring): migrate components directory to typescript (#3517) * docs: migrate components directory to typescript * removed vscode settings * fix following merge * docs: refactored QueryNote component (#3576) * docs: refactored first batch of theme components (#3579) * docs: refactored second batch of theme components (#3580) * added missing badge styles * docs: refactoring second batch of theme components * fix after merge * refactored icons and other components * docs: refactored all components * docs(refactoring): set up and configured Tailwind Css (#3841) * docs: added tailwind config * docs: added more tailwind configurations * add includes option * added more tailwind configurations * fix to configurations * docs(refactoring): use tailwind css (#4134) * docs: added tailwind config * docs: added more tailwind configurations * add includes option * added more tailwind configurations * fix to configurations * docs(refactoring): refactored all styles to use tailwind css (#4132) * refactored Badge component to use tailwind css * refactored Bordered component to use tailwind css * updated to latest docusaurus * refactored BorderedIcon component to use tailwind css * refactored Feedback component to use tailwind css * refactored icons and footersociallinks to tailwind css * start refactoring of large card * refactored large card styling * refactored until admonitions * refactored until codeblock * refactored until Tabs * refactored Tabs (without testing * finished refactoring styles to tailwind css * upgraded to version 2.4.1 * general fixes * adjusted eslint configurations * fixed ignore files * fixes to large card * fix search styling * fix npx command * updated tabs to use isCodeTabs prop * fixed os tabs * removed os-tabs class in favor of general styling * improvements to buttons * fix for searchbar * fixed redocly download button * chore: added eslint code action (#4135) * small change in commerce modules page
This commit is contained in:
@@ -1,20 +0,0 @@
|
||||
import React from "react"
|
||||
import styles from "./styles.module.css"
|
||||
import clsx from "clsx"
|
||||
|
||||
export default function Badge({ className, variant, children }) {
|
||||
return (
|
||||
<span
|
||||
className={clsx(
|
||||
styles.badge,
|
||||
className,
|
||||
variant === "purple" && styles.purpleBadge,
|
||||
variant === "orange" && styles.orangeBadge,
|
||||
variant === "green" && styles.greenBadge,
|
||||
variant === "blue" && styles.blueBadge
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
30
www/docs/src/components/Badge/index.tsx
Normal file
30
www/docs/src/components/Badge/index.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import React from "react"
|
||||
import clsx from "clsx"
|
||||
|
||||
export type BadgeProps = {
|
||||
className?: string
|
||||
variant: string
|
||||
} & React.HTMLAttributes<HTMLSpanElement>
|
||||
|
||||
const Badge: React.FC<BadgeProps> = ({ className, variant, children }) => {
|
||||
return (
|
||||
<span
|
||||
className={clsx(
|
||||
"tw-text-label-x-small-plus tw-py-px tw-px-0.4 tw-rounded tw-border tw-border-solid tw-text-center",
|
||||
variant === "purple" &&
|
||||
"tw-bg-medusa-tag-purple-bg dark:tw-bg-medusa-tag-purple-bg-dark tw-text-medusa-tag-purple-text dark:tw-text-medusa-tag-purple-text-dark tw-border-medusa-tag-purple-border dark:tw-border-medusa-tag-purple-border-dark",
|
||||
variant === "orange" &&
|
||||
"tw-bg-medusa-tag-orange-bg dark:tw-bg-medusa-tag-orange-bg-dark tw-text-medusa-tag-orange-text dark:tw-text-medusa-tag-orange-text-dark tw-border-medusa-tag-orange-border dark:tw-border-medusa-tag-orange-border-dark",
|
||||
variant === "green" &&
|
||||
"tw-bg-medusa-tag-green-bg dark:tw-bg-medusa-tag-green-bg-dark tw-text-medusa-tag-green-text dark:tw-text-medusa-tag-green-text-dark tw-border-medusa-tag-green-border dark:tw-border-medusa-tag-green-border-dark",
|
||||
variant === "blue" &&
|
||||
"tw-bg-medusa-tag-blue-bg dark:tw-bg-medusa-tag-blue-bg-dark tw-text-medusa-tag-blue-text dark:tw-text-medusa-tag-blue-text-dark tw-border-medusa-tag-blue-border dark:tw-border-medusa-tag-blue-border-dark",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
export default Badge
|
||||
@@ -1,33 +0,0 @@
|
||||
.badge {
|
||||
font-size: var(--medusa-label-x-small-plus-size);
|
||||
line-height: var(--medusa-label-x-small-plus-line-height);
|
||||
font-weight: var(--medusa-label-x-small-plus-font-weight);
|
||||
padding: 1px 7px;
|
||||
border-radius: var(--ifm-global-radius);
|
||||
border: 1px solid;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.purpleBadge {
|
||||
background-color: var(--medusa-tag-purple-bg);
|
||||
border-color: var(--medusa-tag-purple-border);
|
||||
color: var(--medusa-tag-purple-text);
|
||||
}
|
||||
|
||||
.orangeBadge {
|
||||
background-color: var(--medusa-tag-orange-bg);
|
||||
border-color: var(--medusa-tag-orange-border);
|
||||
color: var(--medusa-tag-orange-text);
|
||||
}
|
||||
|
||||
.greenBadge {
|
||||
background-color: var(--medusa-tag-green-bg);
|
||||
border-color: var(--medusa-tag-green-border);
|
||||
color: var(--medusa-tag-green-text);
|
||||
}
|
||||
|
||||
.blueBadge {
|
||||
background-color: var(--medusa-tag-blue-bg);
|
||||
border-color: var(--medusa-tag-blue-border);
|
||||
color: var(--medusa-tag-blue-text);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import React from "react"
|
||||
import clsx from 'clsx'
|
||||
import styles from './styles.module.css'
|
||||
|
||||
export default function Bordered ({ wrapperClassName, children }) {
|
||||
return (
|
||||
<span className={clsx(styles.elementWrapper, 'no-zoom-img', wrapperClassName)}>
|
||||
{children}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
22
www/docs/src/components/Bordered/index.tsx
Normal file
22
www/docs/src/components/Bordered/index.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import React from "react"
|
||||
import clsx from "clsx"
|
||||
|
||||
type BorderedProps = {
|
||||
wrapperClassName?: string
|
||||
} & React.HTMLAttributes<HTMLSpanElement>
|
||||
|
||||
const Bordered: React.FC<BorderedProps> = ({ wrapperClassName, children }) => {
|
||||
return (
|
||||
<span
|
||||
className={clsx(
|
||||
"tw-inline-flex tw-justify-center tw-items-center tw-rounded tw-p-[3px] tw-border tw-border-solid tw-border-medusa-border-strong dark:tw-border-medusa-border-strong-dark tw-mr-1 tw-w-fit tw-bg-docs-bg dark:tw-bg-docs-bg-dark",
|
||||
"no-zoom-img",
|
||||
wrapperClassName
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
export default Bordered
|
||||
@@ -1,11 +0,0 @@
|
||||
.elementWrapper {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: var(--ifm-global-radius);
|
||||
padding: var(--bordered-padding);
|
||||
border: 1px solid var(--bordered-border-color);
|
||||
margin-right: var(--bordered-margin-right);
|
||||
width: fit-content;
|
||||
background-color: var(--ifm-background-color);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import React from "react"
|
||||
import ThemedImage from '@theme/ThemedImage'
|
||||
import clsx from 'clsx'
|
||||
import styles from './styles.module.css'
|
||||
import Bordered from "../Bordered"
|
||||
|
||||
export default function BorderedIcon ({ icon = null, IconComponent = null, wrapperClassName, iconWrapperClassName, iconClassName }) {
|
||||
return (
|
||||
<Bordered wrapperClassName={wrapperClassName}>
|
||||
<span className={clsx(styles.borderedIconWrapper, iconWrapperClassName)}>
|
||||
{!IconComponent && (
|
||||
<ThemedImage sources={{
|
||||
light: icon.light,
|
||||
dark: icon.dark || icon.light
|
||||
}} className={clsx(styles.icon, iconClassName, 'bordered-icon')} />
|
||||
)}
|
||||
{IconComponent && <IconComponent className={clsx(styles.icon, iconClassName, 'bordered-icon')} />}
|
||||
</span>
|
||||
</Bordered>
|
||||
)
|
||||
}
|
||||
55
www/docs/src/components/BorderedIcon/index.tsx
Normal file
55
www/docs/src/components/BorderedIcon/index.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import React from "react"
|
||||
import ThemedImage from "@theme/ThemedImage"
|
||||
import clsx from "clsx"
|
||||
import Bordered from "../Bordered/index"
|
||||
import { IconProps } from "@site/src/theme/Icon/index"
|
||||
|
||||
type BorderedIconProp = {
|
||||
icon?: {
|
||||
light: string
|
||||
dark?: string
|
||||
}
|
||||
IconComponent?: React.FC<IconProps>
|
||||
wrapperClassName?: string
|
||||
iconWrapperClassName?: string
|
||||
iconClassName?: string
|
||||
iconColorClassName?: string
|
||||
} & React.HTMLAttributes<HTMLSpanElement>
|
||||
|
||||
const BorderedIcon: React.FC<BorderedIconProp> = ({
|
||||
icon = null,
|
||||
IconComponent = null,
|
||||
wrapperClassName,
|
||||
iconWrapperClassName,
|
||||
iconClassName,
|
||||
iconColorClassName = "",
|
||||
}) => {
|
||||
return (
|
||||
<Bordered wrapperClassName={wrapperClassName}>
|
||||
<span
|
||||
className={clsx(
|
||||
"tw-inline-flex tw-justify-center tw-items-center tw-rounded-sm tw-p-[2px] tw-bg-medusa-bg-component dark:tw-bg-medusa-bg-component-dark",
|
||||
iconWrapperClassName
|
||||
)}
|
||||
>
|
||||
{!IconComponent && (
|
||||
<ThemedImage
|
||||
sources={{
|
||||
light: icon.light,
|
||||
dark: icon.dark || icon.light,
|
||||
}}
|
||||
className={clsx(iconClassName, "bordered-icon")}
|
||||
/>
|
||||
)}
|
||||
{IconComponent && (
|
||||
<IconComponent
|
||||
className={clsx(iconClassName, "bordered-icon")}
|
||||
iconColorClassName={iconColorClassName}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
</Bordered>
|
||||
)
|
||||
}
|
||||
|
||||
export default BorderedIcon
|
||||
@@ -1,8 +0,0 @@
|
||||
.borderedIconWrapper {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: calc(var(--ifm-global-radius) / 2);
|
||||
padding: var(--bordered-inside-padding);
|
||||
background-color: var(--medusa-bg-component);
|
||||
}
|
||||
27
www/docs/src/components/Button/index.tsx
Normal file
27
www/docs/src/components/Button/index.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from "react"
|
||||
import clsx from "clsx"
|
||||
|
||||
type ButtonProps = {
|
||||
className?: string
|
||||
onClick?: React.MouseEventHandler<HTMLButtonElement>
|
||||
disabled?: boolean
|
||||
} & React.HTMLAttributes<HTMLButtonElement>
|
||||
|
||||
const Button: React.FC<ButtonProps> = ({
|
||||
className = "",
|
||||
onClick,
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<button
|
||||
className={clsx("btn-primary", className)}
|
||||
onClick={onClick}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
export default Button
|
||||
@@ -1,78 +0,0 @@
|
||||
import React from "react"
|
||||
import { useThemeConfig } from '@docusaurus/theme-common'
|
||||
import { Cloudinary } from "@cloudinary/url-gen";
|
||||
import MDXImg from '@theme/MDXComponents/Img';
|
||||
import { pad, imaggaScale, imaggaCrop, crop, fit, minimumPad, fill, scale, limitFit, thumbnail, limitFill, minimumFit, limitPad, fillPad } from "@cloudinary/url-gen/actions/resize";
|
||||
import { byRadius } from "@cloudinary/url-gen/actions/roundCorners";
|
||||
|
||||
const resizeActions = {
|
||||
'pad': pad,
|
||||
'imaggaScale': imaggaScale,
|
||||
'imaggaCrop': imaggaCrop,
|
||||
'crop': crop,
|
||||
'fit': fit,
|
||||
'minimumPad': minimumPad,
|
||||
'fill': fill,
|
||||
'scale': scale,
|
||||
'limitFit': limitFit,
|
||||
'thumbnail': thumbnail,
|
||||
'limitFill': limitFill,
|
||||
'minimumFit': minimumFit,
|
||||
'limitPad': limitPad,
|
||||
'fillPad': fillPad
|
||||
}
|
||||
|
||||
const imageRegex = /^https:\/\/res.cloudinary.com\/.*\/upload\/v[0-9]+\/(?<imageId>.*)$/
|
||||
|
||||
export default function CloudinaryImage ({ src, ...props }) {
|
||||
const { cloudinaryConfig } = useThemeConfig();
|
||||
const matchingRegex = src.match(imageRegex)
|
||||
if (!cloudinaryConfig || !cloudinaryConfig.cloudName || !matchingRegex?.groups || !matchingRegex.groups.imageId) {
|
||||
// either cloudinary isn't configured or
|
||||
// could not match url to a cloudinary url
|
||||
// default to docusaurus's image component
|
||||
return <MDXImg src={src} {...props} />
|
||||
}
|
||||
|
||||
const cloudinary = new Cloudinary({
|
||||
cloud: {
|
||||
cloudName: cloudinaryConfig.cloudName
|
||||
}
|
||||
});
|
||||
let image = cloudinary.image(matchingRegex.groups.imageId.replaceAll('%20', ' '))
|
||||
|
||||
cloudinaryConfig.flags?.forEach((flag) => image.addTransformation(flag))
|
||||
|
||||
if (cloudinaryConfig.roundCorners) {
|
||||
image.roundCorners(byRadius(cloudinaryConfig.roundCorners))
|
||||
}
|
||||
if (cloudinaryConfig.resize) {
|
||||
const action = resizeActions[cloudinaryConfig.resize.action]
|
||||
let resizeAction = action()
|
||||
if (props.width || props.height) {
|
||||
if (props.width) {
|
||||
resizeAction = resizeAction.width(props.width)
|
||||
}
|
||||
|
||||
if (props.height) {
|
||||
resizeAction = resizeAction.height(props.height)
|
||||
}
|
||||
} else if (cloudinaryConfig.resize.aspectRatio) {
|
||||
resizeAction = resizeAction.aspectRatio(cloudinaryConfig.resize.aspectRatio)
|
||||
} else {
|
||||
if (cloudinaryConfig.resize.width) {
|
||||
resizeAction = resizeAction.width(cloudinaryConfig.resize.width)
|
||||
}
|
||||
|
||||
if (cloudinaryConfig.resize.height) {
|
||||
resizeAction = resizeAction.height(cloudinaryConfig.resize.height)
|
||||
}
|
||||
}
|
||||
|
||||
image.resize(resizeAction)
|
||||
}
|
||||
|
||||
return (
|
||||
<MDXImg {...props} src={image.toURL()} />
|
||||
)
|
||||
}
|
||||
106
www/docs/src/components/CloudinaryImage/index.tsx
Normal file
106
www/docs/src/components/CloudinaryImage/index.tsx
Normal file
@@ -0,0 +1,106 @@
|
||||
import React from "react"
|
||||
import { useThemeConfig } from "@docusaurus/theme-common"
|
||||
// @ts-expect-error: wait until docusaurus uses type: module
|
||||
import { Cloudinary } from "@cloudinary/url-gen"
|
||||
import MDXImg, { Props as MDXImgProps } from "@theme/MDXComponents/Img"
|
||||
import {
|
||||
pad,
|
||||
imaggaScale,
|
||||
imaggaCrop,
|
||||
crop,
|
||||
fit,
|
||||
minimumPad,
|
||||
fill,
|
||||
scale,
|
||||
limitFit,
|
||||
thumbnail,
|
||||
limitFill,
|
||||
minimumFit,
|
||||
limitPad,
|
||||
fillPad,
|
||||
} from "@cloudinary/url-gen/actions/resize"
|
||||
import { byRadius } from "@cloudinary/url-gen/actions/roundCorners"
|
||||
import { ThemeConfig } from "@medusajs/docs"
|
||||
|
||||
const resizeActions = {
|
||||
pad: pad,
|
||||
imaggaScale: imaggaScale,
|
||||
imaggaCrop: imaggaCrop,
|
||||
crop: crop,
|
||||
fit: fit,
|
||||
minimumPad: minimumPad,
|
||||
fill: fill,
|
||||
scale: scale,
|
||||
limitFit: limitFit,
|
||||
thumbnail: thumbnail,
|
||||
limitFill: limitFill,
|
||||
minimumFit: minimumFit,
|
||||
limitPad: limitPad,
|
||||
fillPad: fillPad,
|
||||
}
|
||||
|
||||
const imageRegex =
|
||||
/^https:\/\/res.cloudinary.com\/.*\/upload\/v[0-9]+\/(?<imageId>.*)$/
|
||||
|
||||
type CloudinaryImageProps = MDXImgProps
|
||||
|
||||
const CloudinaryImage: React.FC<CloudinaryImageProps> = ({ src, ...props }) => {
|
||||
const { cloudinaryConfig } = useThemeConfig() as ThemeConfig
|
||||
const matchingRegex = src.match(imageRegex)
|
||||
if (
|
||||
!cloudinaryConfig ||
|
||||
!matchingRegex?.groups ||
|
||||
!matchingRegex.groups.imageId
|
||||
) {
|
||||
// either cloudinary isn't configured or
|
||||
// could not match url to a cloudinary url
|
||||
// default to docusaurus's image component
|
||||
return <MDXImg src={src} {...props} />
|
||||
}
|
||||
|
||||
const cloudinary = new Cloudinary({
|
||||
cloud: {
|
||||
cloudName: cloudinaryConfig.cloudName,
|
||||
},
|
||||
})
|
||||
const image = cloudinary.image(
|
||||
matchingRegex.groups.imageId.replaceAll("%20", " ")
|
||||
)
|
||||
|
||||
cloudinaryConfig.flags?.forEach((flag) => image.addTransformation(flag))
|
||||
|
||||
if (cloudinaryConfig.roundCorners) {
|
||||
image.roundCorners(byRadius(cloudinaryConfig.roundCorners))
|
||||
}
|
||||
if (cloudinaryConfig.resize) {
|
||||
const action = resizeActions[cloudinaryConfig.resize.action]
|
||||
let resizeAction = action()
|
||||
if (props.width || props.height) {
|
||||
if (props.width) {
|
||||
resizeAction = resizeAction.width(props.width)
|
||||
}
|
||||
|
||||
if (props.height) {
|
||||
resizeAction = resizeAction.height(props.height)
|
||||
}
|
||||
} else if (cloudinaryConfig.resize.aspectRatio) {
|
||||
resizeAction = resizeAction.aspectRatio(
|
||||
cloudinaryConfig.resize.aspectRatio
|
||||
)
|
||||
} else {
|
||||
if (cloudinaryConfig.resize.width) {
|
||||
resizeAction = resizeAction.width(cloudinaryConfig.resize.width)
|
||||
}
|
||||
|
||||
if (cloudinaryConfig.resize.height) {
|
||||
resizeAction = resizeAction.height(cloudinaryConfig.resize.height)
|
||||
}
|
||||
}
|
||||
|
||||
image.resize(resizeAction)
|
||||
}
|
||||
|
||||
return <MDXImg {...props} src={image.toURL()} />
|
||||
}
|
||||
|
||||
export default CloudinaryImage
|
||||
47
www/docs/src/components/CopyButton/index.tsx
Normal file
47
www/docs/src/components/CopyButton/index.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import React, { useState, useEffect, useRef, useCallback } from "react"
|
||||
// @ts-expect-error: wait until docusaurus uses type: module
|
||||
import copy from "copy-text-to-clipboard"
|
||||
import Tooltip from "@site/src/components/Tooltip"
|
||||
import clsx from "clsx"
|
||||
|
||||
type CopyButtonProps = {
|
||||
text: string
|
||||
buttonClassName?: string
|
||||
tooltipClassName?: string
|
||||
} & React.HTMLAttributes<HTMLDivElement>
|
||||
|
||||
const CopyButton: React.FC<CopyButtonProps> = ({
|
||||
text,
|
||||
buttonClassName = "",
|
||||
tooltipClassName = "",
|
||||
children,
|
||||
}) => {
|
||||
const [isCopied, setIsCopied] = useState(false)
|
||||
const copyTimeout = useRef(undefined)
|
||||
|
||||
const handleCopy = useCallback(() => {
|
||||
copy(text)
|
||||
setIsCopied(true)
|
||||
copyTimeout.current = window.setTimeout(() => {
|
||||
setIsCopied(false)
|
||||
}, 1000)
|
||||
}, [text])
|
||||
|
||||
useEffect(() => () => window.clearTimeout(copyTimeout.current), [])
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
text={isCopied ? `Copied!` : `Copy to Clipboard`}
|
||||
tooltipClassName={tooltipClassName}
|
||||
>
|
||||
<span
|
||||
className={clsx("tw-cursor-pointer", buttonClassName)}
|
||||
onClick={handleCopy}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
||||
export default CopyButton
|
||||
45
www/docs/src/components/DocSidebarItemIcon/index.tsx
Normal file
45
www/docs/src/components/DocSidebarItemIcon/index.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import React from "react"
|
||||
import icons from "@site/src/theme/Icon"
|
||||
import BorderedIcon from "@site/src/components/BorderedIcon"
|
||||
import clsx from "clsx"
|
||||
|
||||
type DocSidebarItemIconProps = {
|
||||
icon?: string
|
||||
is_title?: boolean
|
||||
is_disabled?: boolean
|
||||
} & React.HTMLAttributes<HTMLSpanElement>
|
||||
|
||||
const DocSidebarItemIcon: React.FC<DocSidebarItemIconProps> = ({
|
||||
icon,
|
||||
is_title,
|
||||
is_disabled,
|
||||
}) => {
|
||||
const IconComponent = icons[icon]
|
||||
|
||||
return (
|
||||
<>
|
||||
{is_title && (
|
||||
<BorderedIcon
|
||||
icon={null}
|
||||
IconComponent={IconComponent}
|
||||
iconClassName={clsx("sidebar-item-icon")}
|
||||
iconColorClassName={clsx(
|
||||
is_disabled &&
|
||||
"tw-stroke-medusa-icon-disabled dark:tw-stroke-medusa-icon-disabled-dark"
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{!is_title && (
|
||||
<IconComponent
|
||||
className={clsx("sidebar-item-icon")}
|
||||
iconColorClassName={
|
||||
is_disabled &&
|
||||
"tw-stroke-medusa-icon-disabled dark:tw-stroke-medusa-icon-disabled-dark"
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default DocSidebarItemIcon
|
||||
92
www/docs/src/components/Feedback/Solutions/index.tsx
Normal file
92
www/docs/src/components/Feedback/Solutions/index.tsx
Normal file
@@ -0,0 +1,92 @@
|
||||
import React, { useEffect, useState } from "react"
|
||||
import { request } from "@octokit/request"
|
||||
// import "./index.css"
|
||||
|
||||
type SolutionsProps = {
|
||||
feedback: boolean
|
||||
message?: string
|
||||
}
|
||||
|
||||
type GitHubSearchItem = {
|
||||
url: string
|
||||
html_url: string
|
||||
title: string
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
const Solutions: React.FC<SolutionsProps> = ({ feedback, message }) => {
|
||||
const [possibleSolutionsQuery, setPossibleSolutionsQuery] =
|
||||
useState<string>("")
|
||||
const [possibleSolutions, setPossibleSolutions] = useState<
|
||||
GitHubSearchItem[]
|
||||
>([])
|
||||
|
||||
function constructQuery(searchQuery: string) {
|
||||
return `${searchQuery} repo:medusajs/medusa is:closed is:issue`
|
||||
}
|
||||
|
||||
async function searchGitHub(query) {
|
||||
return request(`GET /search/issues`, {
|
||||
q: query,
|
||||
sort: "updated",
|
||||
per_page: 3,
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!feedback) {
|
||||
let query = constructQuery(
|
||||
// Github does not allow queries longer than 256 characters
|
||||
message ? message.substring(0, 256) : document.title
|
||||
)
|
||||
searchGitHub(query)
|
||||
.then(async (result) => {
|
||||
if (!result.data.items.length && message) {
|
||||
query = constructQuery(document.title)
|
||||
result = await searchGitHub(query)
|
||||
}
|
||||
|
||||
setPossibleSolutionsQuery(query)
|
||||
setPossibleSolutions(result.data.items)
|
||||
})
|
||||
.catch((err) => console.error(err))
|
||||
} else {
|
||||
setPossibleSolutionsQuery("")
|
||||
setPossibleSolutions([])
|
||||
}
|
||||
}, [feedback])
|
||||
|
||||
return (
|
||||
<>
|
||||
{possibleSolutions.length > 0 && (
|
||||
<div className="tw-text-label-large-plus tw-font-normal">
|
||||
<span className="tw-inline-block tw-my-1 tw-mx-0">
|
||||
If you faced a problem, here are some possible solutions from
|
||||
GitHub:
|
||||
</span>
|
||||
<ul>
|
||||
{possibleSolutions.map((solution) => (
|
||||
<li key={solution.url} className="tw-mb-0.5 last:tw-mb-0">
|
||||
<a href={solution.html_url} target="_blank" rel="noreferrer">
|
||||
{solution.title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<span>
|
||||
Explore more issues in{" "}
|
||||
<a
|
||||
href={`https://github.com/medusajs/medusa/issues?q=${possibleSolutionsQuery}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
the GitHub repository
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Solutions
|
||||
@@ -1,139 +0,0 @@
|
||||
.feedback-container {
|
||||
padding-top: var(--ifm-base-margin-vertical);
|
||||
padding-bottom: var(--ifm-base-margin-vertical);
|
||||
}
|
||||
|
||||
.doc-footer .feedback-container {
|
||||
border-top: 1px solid var(--ifm-doc-footer-border-color);
|
||||
}
|
||||
|
||||
.inline-feedback {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.inline-question,
|
||||
.feedback-message {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.inline-feedback span {
|
||||
margin-right: 24px;
|
||||
font-size: var(--medusa-body-regular-size);
|
||||
line-height: var(--medusa-body-regular-line-height);
|
||||
font-weight: var(--medusa-body-regular-font-weight);
|
||||
}
|
||||
|
||||
.inline-question span {
|
||||
margin-bottom: calc(var(--ifm-base-margin-vertical) / 2);
|
||||
}
|
||||
|
||||
.feedback-btn {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 6px 12px;
|
||||
border-radius: var(--ifm-global-radius);
|
||||
cursor: pointer;
|
||||
background-color: var(--ifm-secondary-btn-background-color);
|
||||
border: 1px solid var(--ifm-secondary-btn-border-color);
|
||||
color: var(--ifm-secondary-btn-color);
|
||||
font-size: var(--medusa-label-small-plus-size);
|
||||
line-height: var(--medusa-label-small-plus-line-height);
|
||||
font-weight: var(--medusa-label-small-plus-font-weight);
|
||||
}
|
||||
|
||||
.feedback-btn:hover {
|
||||
background-color: var(--ifm-secondary-btn-hover-background-color);
|
||||
}
|
||||
|
||||
.feedback-btn:focus {
|
||||
box-shadow: var(--ifm-secondary-btn-focused-shadow);
|
||||
}
|
||||
|
||||
.feedback-btn:not(:last-child) {
|
||||
margin-right: calc(var(--ifm-base-spacing) / 2);
|
||||
}
|
||||
|
||||
.inline-question .feedback-btn {
|
||||
margin-top: calc(var(--ifm-base-margin-vertical) / 2);
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.inline-question textarea {
|
||||
border-radius: 4px;
|
||||
background-color: transparent;
|
||||
border: 1px solid var(--ifm-base-border-color);
|
||||
padding: 8px;
|
||||
font-family: var(--ifm-font-family-base);
|
||||
}
|
||||
|
||||
.feedback-message,
|
||||
.solutions-wrapper {
|
||||
font-size: var(--medusa-label-large-plus-size);
|
||||
line-height: var(--medusa-label-large-plus-line-height);
|
||||
}
|
||||
|
||||
.feedback-message {
|
||||
font-weight: var(--medusa-label-large-plus-font-weight);
|
||||
}
|
||||
|
||||
.solutions-wrapper {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.solutions-message {
|
||||
display: inline-block;
|
||||
margin: calc(var(--ifm-base-margin-vertical) / 2) 0;
|
||||
}
|
||||
|
||||
.solutions-wrapper li:not(:last-child) {
|
||||
margin-bottom: calc(var(--ifm-base-margin-vertical) / 4);
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
import React, { useRef, useState, useEffect } from 'react';
|
||||
import { CSSTransition, SwitchTransition } from 'react-transition-group';
|
||||
import './index.css';
|
||||
|
||||
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||
import {useLocation} from '@docusaurus/router';
|
||||
import uuid from 'react-uuid';
|
||||
import { request } from "@octokit/request";
|
||||
|
||||
export default function Feedback ({
|
||||
event,
|
||||
question = 'Was this page helpful?',
|
||||
positiveBtn = 'Yes',
|
||||
negativeBtn = 'No',
|
||||
positiveQuestion = 'What was most helpful?',
|
||||
negativeQuestion = 'What can we improve?',
|
||||
submitBtn = 'Submit',
|
||||
submitMessage = 'Thank you for helping improve our documentation!',
|
||||
showPossibleSolutions = true
|
||||
}) {
|
||||
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, setPositiveFeedback] = useState(false);
|
||||
const [message, setMessage] = useState("");
|
||||
const [id, setId] = useState(null);
|
||||
const [possibleSolutionsQuery, setPossibleSolutionsQuery] = useState('')
|
||||
const [possibleSolutions, setPossibleSolutions] = useState([]);
|
||||
const nodeRef = submittedFeedback ? inlineMessageRef : (showForm ? inlineQuestionRef : inlineFeedbackRef);
|
||||
|
||||
const isBrowser = useIsBrowser();
|
||||
const location = useLocation();
|
||||
|
||||
function handleFeedback (e) {
|
||||
const feedback = e.target.classList.contains('positive');
|
||||
submitFeedback(e, feedback)
|
||||
setPositiveFeedback(feedback);
|
||||
setShowForm(true);
|
||||
}
|
||||
|
||||
function submitFeedback (e, feedback = null) {
|
||||
if (isBrowser) {
|
||||
if (window.analytics) {
|
||||
if (showForm) {
|
||||
setLoading(true);
|
||||
}
|
||||
window.analytics.track(event, {
|
||||
url: location.pathname,
|
||||
label: document.title,
|
||||
feedback: (feedback !== null && feedback) || (feedback === null && positiveFeedback) ? 'yes' : 'no',
|
||||
message: message?.length ? message : null,
|
||||
uuid: id
|
||||
}, function () {
|
||||
if (showForm) {
|
||||
setLoading(false);
|
||||
checkAvailableSolutions(positiveFeedback, message);
|
||||
resetForm();
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if (showForm) {
|
||||
resetForm();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resetForm () {
|
||||
setShowForm(false);
|
||||
setSubmittedFeedback(true);
|
||||
if (message) {
|
||||
setId(null);
|
||||
}
|
||||
}
|
||||
|
||||
function constructQuery (searchQuery) {
|
||||
return `${searchQuery} repo:medusajs/medusa is:closed is:issue`; //Github does not allow queries longer than 256 characters
|
||||
}
|
||||
|
||||
function searchGitHub (query) {
|
||||
return request(`GET /search/issues`, {
|
||||
q: query,
|
||||
sort: 'updated',
|
||||
per_page: 3,
|
||||
})
|
||||
}
|
||||
|
||||
async function checkAvailableSolutions (feedback, message) {
|
||||
if (showPossibleSolutions && !feedback) {
|
||||
//fetch some possible solutions related to the answer.
|
||||
let query = constructQuery(message ? message.substring(0, 256) : document.title)
|
||||
let result = await searchGitHub(query);
|
||||
|
||||
if (!result.data.items.length && message) {
|
||||
query = constructQuery(document.title)
|
||||
result = await searchGitHub(query)
|
||||
}
|
||||
|
||||
setPossibleSolutionsQuery(query);
|
||||
setPossibleSolutions(result.data.items);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!id) {
|
||||
setId(uuid())
|
||||
}
|
||||
}, [id])
|
||||
|
||||
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>{question}</span>
|
||||
<button className='positive feedback-btn' onClick={handleFeedback}>{positiveBtn}</button>
|
||||
<button className='negative feedback-btn' onClick={handleFeedback}>{negativeBtn}</button>
|
||||
</div>
|
||||
)}
|
||||
{(showForm && !submittedFeedback) && (
|
||||
<div className='inline-question' ref={inlineQuestionRef}>
|
||||
<span>{positiveFeedback ? positiveQuestion : negativeQuestion}</span>
|
||||
<textarea rows={4} value={message} onChange={(e) => setMessage(e.target.value)}></textarea>
|
||||
<button className='feedback-btn' onClick={submitFeedback} disabled={loading}>{submitBtn}</button>
|
||||
</div>
|
||||
)}
|
||||
{submittedFeedback && (
|
||||
<div className='feedback-message-wrapper'>
|
||||
<div className='feedback-message' ref={inlineMessageRef}>
|
||||
<span>{submitMessage}</span>
|
||||
{possibleSolutions.length > 0 && (
|
||||
<div className='solutions-wrapper'>
|
||||
<span className='solutions-message'>If you faced a problem, here are some possible solutions from GitHub:</span>
|
||||
<ul>
|
||||
{possibleSolutions.map((solution) => (
|
||||
<li key={solution.url}>
|
||||
<a href={solution.html_url} target="_blank">{solution.title}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<span>Explore more issues in <a
|
||||
href={`https://github.com/medusajs/medusa/issues?q=${possibleSolutionsQuery}`}
|
||||
target="_blank"
|
||||
>
|
||||
the GitHub repository
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</CSSTransition>
|
||||
</SwitchTransition>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
187
www/docs/src/components/Feedback/index.tsx
Normal file
187
www/docs/src/components/Feedback/index.tsx
Normal file
@@ -0,0 +1,187 @@
|
||||
import React, { useRef, useState, useEffect } from "react"
|
||||
import { CSSTransition, SwitchTransition } from "react-transition-group"
|
||||
// import "./index.css"
|
||||
|
||||
import useIsBrowser from "@docusaurus/useIsBrowser"
|
||||
import { useLocation } from "@docusaurus/router"
|
||||
import uuid from "react-uuid"
|
||||
import Solutions from "./Solutions/index"
|
||||
import Button from "../Button"
|
||||
|
||||
type FeedbackProps = {
|
||||
event?: string
|
||||
question?: string
|
||||
positiveBtn?: string
|
||||
negativeBtn?: string
|
||||
positiveQuestion?: string
|
||||
negativeQuestion?: string
|
||||
submitBtn?: string
|
||||
submitMessage?: string
|
||||
showPossibleSolutions?: boolean
|
||||
className?: string
|
||||
} & React.HTMLAttributes<HTMLDivElement>
|
||||
|
||||
const Feedback: React.FC<FeedbackProps> = ({
|
||||
event,
|
||||
question = "Was this page helpful?",
|
||||
positiveBtn = "Yes",
|
||||
negativeBtn = "No",
|
||||
positiveQuestion = "What was most helpful?",
|
||||
negativeQuestion = "What can we improve?",
|
||||
submitBtn = "Submit",
|
||||
submitMessage = "Thank you for helping improve our documentation!",
|
||||
showPossibleSolutions = true,
|
||||
className = "",
|
||||
}) => {
|
||||
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, setPositiveFeedback] = useState(false)
|
||||
const [message, setMessage] = useState("")
|
||||
const [id, setId] = useState(null)
|
||||
const nodeRef = submittedFeedback
|
||||
? inlineMessageRef
|
||||
: showForm
|
||||
? inlineQuestionRef
|
||||
: inlineFeedbackRef
|
||||
|
||||
const isBrowser = useIsBrowser()
|
||||
const location = useLocation()
|
||||
|
||||
function handleFeedback(e) {
|
||||
const feedback = e.target.classList.contains("positive")
|
||||
submitFeedback(e, feedback)
|
||||
setPositiveFeedback(feedback)
|
||||
setShowForm(true)
|
||||
}
|
||||
|
||||
function submitFeedback(e, feedback = null) {
|
||||
if (isBrowser) {
|
||||
if (window.analytics) {
|
||||
if (showForm) {
|
||||
setLoading(true)
|
||||
}
|
||||
window.analytics.track(
|
||||
event,
|
||||
{
|
||||
url: location.pathname,
|
||||
label: document.title,
|
||||
feedback:
|
||||
(feedback !== null && feedback) ||
|
||||
(feedback === null && positiveFeedback)
|
||||
? "yes"
|
||||
: "no",
|
||||
message: message?.length ? message : null,
|
||||
uuid: id,
|
||||
},
|
||||
function () {
|
||||
if (showForm) {
|
||||
setLoading(false)
|
||||
resetForm()
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
if (showForm) {
|
||||
resetForm()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
setShowForm(false)
|
||||
setSubmittedFeedback(true)
|
||||
if (message) {
|
||||
setId(null)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!id) {
|
||||
setId(uuid())
|
||||
}
|
||||
}, [id])
|
||||
|
||||
return (
|
||||
<div className={`tw-py-2 ${className}`}>
|
||||
<SwitchTransition mode="out-in">
|
||||
<CSSTransition
|
||||
key={showForm}
|
||||
nodeRef={nodeRef}
|
||||
timeout={300}
|
||||
addEndListener={(done) => {
|
||||
nodeRef.current.addEventListener("transitionend", done, false)
|
||||
}}
|
||||
classNames={{
|
||||
enter: "animate__animated animate__fadeIn",
|
||||
exit: "animate__animated animate__fadeOut",
|
||||
}}
|
||||
>
|
||||
<>
|
||||
{!showForm && !submittedFeedback && (
|
||||
<div
|
||||
className="tw-flex tw-flex-row tw-items-center"
|
||||
ref={inlineFeedbackRef}
|
||||
>
|
||||
<span className="tw-mr-1.5 tw-text-body-regular">
|
||||
{question}
|
||||
</span>
|
||||
<Button
|
||||
onClick={handleFeedback}
|
||||
className="tw-w-fit tw-mr-0.5 last:tw-mr-0"
|
||||
>
|
||||
{positiveBtn}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleFeedback}
|
||||
className="tw-w-fit tw-mr-0.5 last:tw-mr-0"
|
||||
>
|
||||
{negativeBtn}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{showForm && !submittedFeedback && (
|
||||
<div className="tw-flex tw-flex-col" ref={inlineQuestionRef}>
|
||||
<span className="tw-mb-1">
|
||||
{positiveFeedback ? positiveQuestion : negativeQuestion}
|
||||
</span>
|
||||
<textarea
|
||||
rows={4}
|
||||
value={message}
|
||||
onChange={(e) => setMessage(e.target.value)}
|
||||
className="tw-rounded-sm tw-bg-transparent tw-border tw-border-medusa-border-base dark:tw-border-medusa-border-base-dark tw-p-1 tw-font-base"
|
||||
></textarea>
|
||||
<Button
|
||||
onClick={submitFeedback}
|
||||
disabled={loading}
|
||||
className="tw-mt-1 tw-w-fit"
|
||||
>
|
||||
{submitBtn}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{submittedFeedback && (
|
||||
<div>
|
||||
<div
|
||||
className="tw-flex tw-flex-col tw-text-label-large-plus"
|
||||
ref={inlineMessageRef}
|
||||
>
|
||||
<span>{submitMessage}</span>
|
||||
{showPossibleSolutions && (
|
||||
<Solutions message={message} feedback={positiveFeedback} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</CSSTransition>
|
||||
</SwitchTransition>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Feedback
|
||||
43
www/docs/src/components/Footer/SocialLinks/index.tsx
Normal file
43
www/docs/src/components/Footer/SocialLinks/index.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import React from "react"
|
||||
import IconTwitter from "@site/src/theme/Icon/Twitter"
|
||||
import IconGitHub from "@site/src/theme/Icon/GitHub"
|
||||
import IconDiscord from "@site/src/theme/Icon/Discord"
|
||||
import IconLinkedIn from "@site/src/theme/Icon/LinkedIn"
|
||||
import { SocialLink } from "@medusajs/docs"
|
||||
|
||||
type SocialLinksProps = {
|
||||
links?: SocialLink[]
|
||||
} & React.HTMLAttributes<HTMLDivElement>
|
||||
|
||||
const SocialLinks: React.FC<SocialLinksProps> = ({ links = [] }) => {
|
||||
const socialIcons = {
|
||||
twitter: (
|
||||
<IconTwitter iconColorClassName="tw-fill-medusa-icon-placeholder dark:tw-fill-medusa-icon-placeholder-dark group-hover:tw-fill-medusa-icon-secondary dark:group-hover:tw-fill-medusa-icon-secondary-dark" />
|
||||
),
|
||||
github: (
|
||||
<IconGitHub iconColorClassName="tw-fill-medusa-icon-placeholder dark:tw-fill-medusa-icon-placeholder-dark group-hover:tw-fill-medusa-icon-secondary dark:group-hover:tw-fill-medusa-icon-secondary-dark" />
|
||||
),
|
||||
discord: (
|
||||
<IconDiscord iconColorClassName="tw-fill-medusa-icon-placeholder dark:tw-fill-medusa-icon-placeholder-dark group-hover:tw-fill-medusa-icon-secondary dark:group-hover:tw-fill-medusa-icon-secondary-dark" />
|
||||
),
|
||||
linkedin: (
|
||||
<IconLinkedIn iconColorClassName="tw-fill-medusa-icon-placeholder dark:tw-fill-medusa-icon-placeholder-dark group-hover:tw-fill-medusa-icon-secondary dark:group-hover:tw-fill-medusa-icon-secondary-dark" />
|
||||
),
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="tw-flex tw-items-center">
|
||||
{links.map((link) => (
|
||||
<a
|
||||
className="tw-group tw-ml-1 first:tw-ml-0"
|
||||
href={link.href}
|
||||
key={link.type}
|
||||
>
|
||||
{socialIcons[link.type]}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SocialLinks
|
||||
@@ -1,130 +0,0 @@
|
||||
.large-card {
|
||||
background-color: var(--large-card-bg);
|
||||
border: 1px solid var(--large-card-border-color);
|
||||
border-radius: var(--ifm-global-radius);
|
||||
padding: calc(var(--ifm-base-margin-vertical) * 3) var(--ifm-base-spacing) calc(var(--ifm-base-margin-vertical) / 2);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
margin-bottom: var(--ifm-base-margin-vertical);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.large-card:not(.large-card-soon):hover,
|
||||
.large-card:not(.large-card-soon):hover:before {
|
||||
background-color: var(--large-card-bg-hover);
|
||||
}
|
||||
|
||||
.large-card-soon:hover a {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.large-card-soon:hover .large-card-title,
|
||||
.large-card-soon:hover .large-card-content {
|
||||
color: var(--medusa-text-disabled);
|
||||
}
|
||||
|
||||
.large-card:before,
|
||||
.large-card:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
border-radius: var(--ifm-global-radius);
|
||||
}
|
||||
|
||||
.large-card:before {
|
||||
z-index: 1;
|
||||
height: calc(var(--ifm-base-margin-vertical) * 4);
|
||||
top: 0;
|
||||
background-image: var(--large-card-bg-image);
|
||||
background-color: var(--large-card-bg);
|
||||
}
|
||||
|
||||
.large-card:nth-child(3n+1):before {
|
||||
background-position-x: 2%;
|
||||
background-position-y: 52%;
|
||||
}
|
||||
|
||||
.large-card:nth-child(3n + 2):before {
|
||||
background-position-x: 19%;
|
||||
background-position-y: 16%;
|
||||
}
|
||||
|
||||
.large-card:nth-child(3n + 3):before {
|
||||
background-position-x: 17%;
|
||||
background-position-y: 50%;
|
||||
}
|
||||
|
||||
.large-card:after {
|
||||
z-index: 2;
|
||||
left: 0;
|
||||
top: calc(var(--ifm-base-margin-vertical) * 2);
|
||||
height: calc(var(--ifm-base-margin-vertical) * 2);
|
||||
background: var(--large-card-fade-effect);
|
||||
}
|
||||
|
||||
.large-card:not(.large-card-soon):hover:after {
|
||||
background: var(--large-card-fade-effect-hover);
|
||||
}
|
||||
|
||||
.large-card > * {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.large-card-bordered-icon-wrapper {
|
||||
--bordered-padding: var(--large-card-icon-wrapper-padding);
|
||||
|
||||
margin-bottom: calc(var(--ifm-base-margin-vertical) / 2);
|
||||
}
|
||||
|
||||
.large-card-icon-wrapper {
|
||||
--bordered-inside-padding: var(--large-card-icon-inside-padding);
|
||||
}
|
||||
|
||||
.large-card-icon {
|
||||
width: var(--large-card-icon-size);
|
||||
height: var(--large-card-icon-size);
|
||||
}
|
||||
|
||||
.large-card-heading {
|
||||
margin-bottom: calc(var(--ifm-base-margin-vertical) / 4);
|
||||
}
|
||||
|
||||
.large-card-title {
|
||||
color: var(--ifm-color-primary);
|
||||
font-size: var(--medusa-label-regular-plus-size);
|
||||
line-height: var(--medusa-label-regular-plus-line-height);
|
||||
font-weight: var(--medusa-label-regular-plus-font-weight);
|
||||
}
|
||||
|
||||
.large-card-content {
|
||||
font-size: var(--medusa-body-regular-size);
|
||||
line-height: var(--medusa-body-regular-line-height);
|
||||
font-weight: var(--medusa-body-regular-font-weight);
|
||||
}
|
||||
|
||||
.large-card-title,
|
||||
.large-card-content {
|
||||
transition: all var(--ifm-transition-fast) ease;
|
||||
}
|
||||
|
||||
.large-card-content ul {
|
||||
padding-left: var(--ifm-base-spacing);
|
||||
}
|
||||
|
||||
.large-card-link {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 4;
|
||||
border-radius: var(--ifm-global-radius);
|
||||
}
|
||||
|
||||
.large-card-badge {
|
||||
position: absolute;
|
||||
top: calc(var(--ifm-base-margin-vertical) / 2);
|
||||
right: var(--ifm-base-spacing);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
import React from "react"
|
||||
import './index.css'
|
||||
import BorderedIcon from "../BorderedIcon"
|
||||
import clsx from 'clsx';
|
||||
import Badge from "../Badge";
|
||||
|
||||
export default function LargeCard ({
|
||||
Icon,
|
||||
image,
|
||||
title,
|
||||
action: {
|
||||
href
|
||||
},
|
||||
isSoon = false,
|
||||
children
|
||||
}) {
|
||||
return (
|
||||
<article className={clsx(
|
||||
'large-card',
|
||||
isSoon && 'large-card-soon'
|
||||
)}>
|
||||
<div>
|
||||
{isSoon && <Badge variant={'purple'} className={'large-card-badge'}>Guide coming soon</Badge>}
|
||||
{(Icon || image) && (
|
||||
<BorderedIcon
|
||||
IconComponent={Icon}
|
||||
icon={image}
|
||||
iconClassName='large-card-icon'
|
||||
wrapperClassName='large-card-bordered-icon-wrapper'
|
||||
iconWrapperClassName='large-card-icon-wrapper'
|
||||
/>
|
||||
)}
|
||||
<div className="large-card-heading">
|
||||
<span className="large-card-title">{title}</span>
|
||||
</div>
|
||||
<div className="large-card-content">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
<a href={href} className="large-card-link"></a>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
96
www/docs/src/components/LargeCard/index.tsx
Normal file
96
www/docs/src/components/LargeCard/index.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import React from "react"
|
||||
import BorderedIcon from "../BorderedIcon"
|
||||
import clsx from "clsx"
|
||||
import Badge from "../Badge"
|
||||
import { IconProps } from "@site/src/theme/Icon/index"
|
||||
|
||||
type LargeCardProps = {
|
||||
Icon: React.FC<IconProps>
|
||||
image: {
|
||||
light: string
|
||||
dark?: string
|
||||
}
|
||||
title: string
|
||||
action: {
|
||||
href: string
|
||||
}
|
||||
isSoon?: boolean
|
||||
} & React.HTMLAttributes<HTMLDivElement>
|
||||
|
||||
const LargeCard: React.FC<LargeCardProps> = ({
|
||||
Icon,
|
||||
image,
|
||||
title,
|
||||
action: { href },
|
||||
isSoon = false,
|
||||
children,
|
||||
}) => {
|
||||
return (
|
||||
<article
|
||||
className={clsx(
|
||||
"tw-group tw-bg-docs-bg-surface dark:tw-bg-docs-bg-surface-dark",
|
||||
"tw-border tw-border-solid tw-border-medusa-border-base dark:tw-border-medusa-border-base-dark tw-rounded",
|
||||
"tw-pt-6 tw-pb-1 tw-px-1 tw-mb-2",
|
||||
"tw-flex tw-flex-col tw-justify-between tw-relative",
|
||||
"before:tw-content-[''] before:tw-absolute before:tw-left-0 before:tw-w-full before:tw-rounded before:tw-z-[1] before:tw-h-8 before:tw-top-0",
|
||||
"before:tw-bg-large-card dark:before:tw-bg-large-card-dark before:tw-bg-docs-bg-surface dark:before:tw-bg-docs-bg-surface-dark",
|
||||
"[&:nth-child(3n+1):before]:tw-bg-[2%_52%] [&:nth-child(3n+2):before]:tw-bg-[19%_16%] [&:nth-child(3n+3):before]:tw-bg-[17%_50%]",
|
||||
"after:tw-content-[''] after:tw-absolute after:tw-left-0 after:tw-w-full after:tw-rounded",
|
||||
"after:tw-z-[2] after:tw-left-0 after:tw-top-4 after:tw-height-4 after:tw-bg-large-card-fade dark:after:tw-bg-large-card-fade-dark",
|
||||
!isSoon &&
|
||||
"hover:after:tw-bg-large-card-fade-hover dark:hover:after:tw-bg-large-card-fade-hover",
|
||||
!isSoon &&
|
||||
"hover:tw-bg-medusa-bg-subtle-hover dark:hover:tw-bg-medusa-bg-base-hover-dark",
|
||||
!isSoon &&
|
||||
"hover:before:tw-bg-medusa-bg-subtle-hover dark:hover:before:tw-bg-medusa-bg-base-hover-dark"
|
||||
)}
|
||||
>
|
||||
<div className={clsx("tw-z-[3]")}>
|
||||
{isSoon && (
|
||||
<Badge variant={"purple"} className="tw-absolute tw-top-1 tw-right-1">
|
||||
Guide coming soon
|
||||
</Badge>
|
||||
)}
|
||||
{(Icon || image) && (
|
||||
<BorderedIcon
|
||||
IconComponent={Icon}
|
||||
icon={image}
|
||||
iconClassName="tw-w-[20px] tw-h-[20px]"
|
||||
wrapperClassName="tw-mb-1"
|
||||
iconWrapperClassName="tw-p-[6px]"
|
||||
/>
|
||||
)}
|
||||
<div className="tw-mb-0.5">
|
||||
<span
|
||||
className={clsx(
|
||||
isSoon &&
|
||||
"group-hover:tw-text-medusa-text-disabled dark:group-hover:tw-text-medusa-text-disabled-dark",
|
||||
"tw-text-medusa-text-base dark:tw-text-medusa-text-base-dark tw-text-label-regular-plus",
|
||||
"tw-transition-all tw-duration-200 tw-ease-ease"
|
||||
)}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
isSoon &&
|
||||
"group-hover:tw-text-medusa-text-disabled dark:group-hover:tw-text-medusa-text-disabled-dark",
|
||||
"tw-transition-all tw-duration-200 tw-ease-ease tw-text-body-regular"
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
href={href}
|
||||
className={clsx(
|
||||
"tw-absolute tw-top-0 tw-left-0 tw-w-full tw-h-full tw-z-[4] tw-rounded",
|
||||
isSoon && "group-hover:tw-pointer-events-none"
|
||||
)}
|
||||
></a>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
export default LargeCard
|
||||
@@ -1,10 +0,0 @@
|
||||
import React from "react"
|
||||
import clsx from 'clsx'
|
||||
|
||||
export default function LargeCardList ({ colSize, className, children }) {
|
||||
return (
|
||||
<section className={clsx('cards-grid', `grid-${colSize || '4'}`, className)}>
|
||||
{children}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
21
www/docs/src/components/LargeCardList/index.tsx
Normal file
21
www/docs/src/components/LargeCardList/index.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from "react"
|
||||
import clsx from "clsx"
|
||||
|
||||
type LargeCardListProps = {
|
||||
colSize?: string
|
||||
className?: string
|
||||
} & React.HTMLAttributes<HTMLDivElement>
|
||||
|
||||
const LargeCardList: React.FC<LargeCardListProps> = ({
|
||||
colSize = "4",
|
||||
className,
|
||||
children,
|
||||
}) => {
|
||||
return (
|
||||
<section className={clsx("cards-grid", `grid-${colSize}`, className)}>
|
||||
{children}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export default LargeCardList
|
||||
28
www/docs/src/components/MDXComponents/InlineCode.tsx
Normal file
28
www/docs/src/components/MDXComponents/InlineCode.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import React from "react"
|
||||
import CopyButton from "@site/src/components/CopyButton"
|
||||
import type { Props } from "@theme/MDXComponents/Code"
|
||||
import clsx from "clsx"
|
||||
|
||||
const MDXInlineCode: React.FC<Props> = (props) => {
|
||||
return (
|
||||
<CopyButton
|
||||
text={props.children as string}
|
||||
buttonClassName={clsx(
|
||||
"tw-bg-transparent tw-border-0 tw-p-0 tw-inline tw-text-medusa-text-subtle dark:tw-text-medusa-text-subtle-dark",
|
||||
"active:[&>code]:tw-bg-medusa-bg-subtle-pressed dark:active:[&>code]:tw-bg-medusa-bg-subtle-pressed-dark",
|
||||
"focus:[&>code]:tw-bg-medusa-bg-subtle-pressed dark:focus:[&>code]:tw-bg-medusa-bg-subtle-pressed-dark",
|
||||
"hover:[&>code]:tw-bg-medusa-bg-subtle-hover dark:hover:[&>code]:tw-bg-medusa-bg-base-hover-dark"
|
||||
)}
|
||||
>
|
||||
<code
|
||||
{...props}
|
||||
className={clsx(
|
||||
"tw-border tw-border-solid tw-border-medusa-border-base dark:tw-border-medusa-border-base-dark",
|
||||
"tw-text-medusa-text-subtle dark:tw-text-medusa-text-subtle-dark tw-leading-6"
|
||||
)}
|
||||
/>
|
||||
</CopyButton>
|
||||
)
|
||||
}
|
||||
|
||||
export default MDXInlineCode
|
||||
46
www/docs/src/components/Navbar/Actions/index.tsx
Normal file
46
www/docs/src/components/Navbar/Actions/index.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import React from "react"
|
||||
import Tooltip from "@site/src/components/Tooltip"
|
||||
import { NavbarAction } from "@medusajs/docs"
|
||||
import Icon from "@site/src/theme/Icon"
|
||||
import clsx from "clsx"
|
||||
|
||||
type NavbarActionsProps = {
|
||||
items: NavbarAction[]
|
||||
} & React.HTMLAttributes<HTMLDivElement>
|
||||
|
||||
const NavbarActions: React.FC<NavbarActionsProps> = ({ items = [] }) => {
|
||||
return (
|
||||
<div className="lg:tw-block tw-hidden">
|
||||
{items.map((item, index) => {
|
||||
switch (item.type) {
|
||||
case "link":
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
const ItemIcon = item.icon ? Icon[item.icon] : null
|
||||
return (
|
||||
<Tooltip text={item.title} key={index}>
|
||||
<a
|
||||
href={item.href}
|
||||
title={item.title}
|
||||
// className={`${ItemIcon ? "navbar-link-icon" : ""} ${
|
||||
// item.className || ""
|
||||
// }`}
|
||||
className={clsx(
|
||||
ItemIcon &&
|
||||
"tw-bg-medusa-button-secondary dark:tw-bg-medusa-button-secondary-dark tw-border tw-border-solid tw-border-medusa-border-base dark:tw-border-medusa-border-base-dark tw-rounded tw-w-2 tw-h-2 tw-flex tw-justify-center tw-items-center hover:tw-bg-medusa-button-secondary-hover dark:hover:tw-bg-medusa-button-secondary-hover-dark",
|
||||
item.className
|
||||
)}
|
||||
>
|
||||
{item.label}
|
||||
{ItemIcon && <ItemIcon />}
|
||||
</a>
|
||||
</Tooltip>
|
||||
)
|
||||
default:
|
||||
return <></>
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default NavbarActions
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from "react";
|
||||
import { useQueryStringValue } from "@docusaurus/theme-common/internal"
|
||||
import Admonition from "@theme/Admonition"
|
||||
|
||||
export default function QueryNote ({
|
||||
query: {
|
||||
key,
|
||||
value = ''
|
||||
},
|
||||
//admonition props
|
||||
admonition,
|
||||
children
|
||||
}) {
|
||||
const queryValue = useQueryStringValue(key)
|
||||
|
||||
return (
|
||||
<>
|
||||
{queryValue === value && (
|
||||
<Admonition {...admonition}>
|
||||
{children}
|
||||
</Admonition>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
29
www/docs/src/components/QueryNote/index.tsx
Normal file
29
www/docs/src/components/QueryNote/index.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import Admonition, { Props as AdmonitionProps } from "@theme/Admonition"
|
||||
import { useQueryStringValue } from "@docusaurus/theme-common/internal"
|
||||
import React from "react"
|
||||
|
||||
type QueryNoteProps = {
|
||||
query: {
|
||||
key: string
|
||||
value?: string
|
||||
}
|
||||
admonition: AdmonitionProps
|
||||
} & React.HTMLAttributes<HTMLDivElement>
|
||||
|
||||
const QueryNote: React.FC<QueryNoteProps> = ({
|
||||
query: { key, value = "" },
|
||||
admonition,
|
||||
children,
|
||||
}) => {
|
||||
const queryValue = useQueryStringValue(key)
|
||||
|
||||
return (
|
||||
<>
|
||||
{queryValue === value && (
|
||||
<Admonition {...admonition}>{children}</Admonition>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default QueryNote
|
||||
44
www/docs/src/components/StructuredData/HowTo/index.tsx
Normal file
44
www/docs/src/components/StructuredData/HowTo/index.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import React from "react"
|
||||
import Head from "@docusaurus/Head"
|
||||
import { useLocation } from "@docusaurus/router"
|
||||
import useDocusaurusContext from "@docusaurus/useDocusaurusContext"
|
||||
import type { TOCItem } from "@docusaurus/mdx-loader"
|
||||
|
||||
type StructuredDataHowToProps = {
|
||||
toc: readonly TOCItem[]
|
||||
title: string
|
||||
}
|
||||
|
||||
const StructuredDataHowTo: React.FC<StructuredDataHowToProps> = ({
|
||||
toc,
|
||||
title,
|
||||
}) => {
|
||||
const location = useLocation()
|
||||
const {
|
||||
siteConfig: { url },
|
||||
} = useDocusaurusContext()
|
||||
const mainUrl = `${url}/${location.pathname}`
|
||||
|
||||
return (
|
||||
<Head>
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "HowTo",
|
||||
name: title,
|
||||
step: [
|
||||
toc
|
||||
.filter((item) => item.level === 2)
|
||||
.map((item) => ({
|
||||
"@type": "HowToStep",
|
||||
text: item.value,
|
||||
url: `${mainUrl}#${item.id}`,
|
||||
})),
|
||||
],
|
||||
})}
|
||||
</script>
|
||||
</Head>
|
||||
)
|
||||
}
|
||||
|
||||
export default StructuredDataHowTo
|
||||
33
www/docs/src/components/StructuredData/Searchbox/index.tsx
Normal file
33
www/docs/src/components/StructuredData/Searchbox/index.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import React from "react"
|
||||
import useDocusaurusContext from "@docusaurus/useDocusaurusContext"
|
||||
import Head from "@docusaurus/Head"
|
||||
|
||||
type StructuredDataSearchboxProps = React.HTMLAttributes<HTMLScriptElement>
|
||||
|
||||
const StructuredDataSearchbox: React.FC<StructuredDataSearchboxProps> = () => {
|
||||
const {
|
||||
siteConfig: { url },
|
||||
} = useDocusaurusContext()
|
||||
|
||||
return (
|
||||
<Head>
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebSite",
|
||||
url,
|
||||
potentialAction: {
|
||||
"@type": "SearchAction",
|
||||
target: {
|
||||
"@type": "EntryPoint",
|
||||
urlTemplate: `${url}/search?q={search_term_string}`,
|
||||
},
|
||||
"query-input": "required name=search_term_string",
|
||||
},
|
||||
})}
|
||||
</script>
|
||||
</Head>
|
||||
)
|
||||
}
|
||||
|
||||
export default StructuredDataSearchbox
|
||||
40
www/docs/src/components/Tooltip/index.tsx
Normal file
40
www/docs/src/components/Tooltip/index.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import React, { useState, useEffect } from "react"
|
||||
import { Tooltip as ReactTooltip } from "react-tooltip"
|
||||
import type { ITooltip } from "react-tooltip"
|
||||
import uuid from "react-uuid"
|
||||
import "react-tooltip/dist/react-tooltip.css"
|
||||
|
||||
type TooltipProps = {
|
||||
text: string
|
||||
tooltipClassName?: string
|
||||
} & React.HTMLAttributes<HTMLSpanElement> &
|
||||
ITooltip
|
||||
|
||||
const Tooltip: React.FC<TooltipProps> = ({
|
||||
text,
|
||||
tooltipClassName = "",
|
||||
children,
|
||||
}) => {
|
||||
const [elementId, setElementId] = useState(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (!elementId) {
|
||||
setElementId(uuid())
|
||||
}
|
||||
}, [elementId])
|
||||
|
||||
return (
|
||||
<>
|
||||
<span id={elementId} data-tooltip-content={text}>
|
||||
{children}
|
||||
</span>
|
||||
<ReactTooltip
|
||||
anchorId={elementId}
|
||||
className={tooltipClassName}
|
||||
wrapper="span"
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Tooltip
|
||||
@@ -1,12 +0,0 @@
|
||||
import React from 'react';
|
||||
import ThemedImage from '@theme/ThemedImage';
|
||||
|
||||
export default function UiIcon ({ lightIcon, darkIcon = '', alt = '' }) {
|
||||
|
||||
return (
|
||||
<ThemedImage alt={alt} sources={{
|
||||
light: lightIcon,
|
||||
dark: darkIcon || lightIcon
|
||||
}} className="ui-icon" />
|
||||
)
|
||||
}
|
||||
27
www/docs/src/components/UiIcon/index.tsx
Normal file
27
www/docs/src/components/UiIcon/index.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from "react"
|
||||
import ThemedImage from "@theme/ThemedImage"
|
||||
|
||||
type UiIconProps = {
|
||||
lightIcon: string
|
||||
darkIcon?: string
|
||||
alt?: string
|
||||
}
|
||||
|
||||
const UiIcon: React.FC<UiIconProps> = ({
|
||||
lightIcon,
|
||||
darkIcon = "",
|
||||
alt = "",
|
||||
}) => {
|
||||
return (
|
||||
<ThemedImage
|
||||
alt={alt}
|
||||
sources={{
|
||||
light: lightIcon,
|
||||
dark: darkIcon || lightIcon,
|
||||
}}
|
||||
className="tw-align-sub tw-w-[20px] tw-h-[20px]"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default UiIcon
|
||||
@@ -1,18 +0,0 @@
|
||||
import React from "react"
|
||||
|
||||
const CloseIcon = ({ fill = "black" }) => (
|
||||
<svg
|
||||
width="15"
|
||||
height="15"
|
||||
viewBox="0 0 9 8"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1.05 7.76L0.51 7.22L3.79 3.92L0.51 0.62L1.05 0.0799997L4.33 3.38L7.59 0.0799997L8.13 0.62L4.85 3.92L8.13 7.22L7.59 7.76L4.33 4.48L1.05 7.76Z"
|
||||
fill={fill}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default CloseIcon
|
||||
@@ -1,48 +0,0 @@
|
||||
import React from "react"
|
||||
|
||||
const ConfLogo = ({ fill }) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 371.2226 96">
|
||||
<title>medusa-logo-one-colour-rgb</title>
|
||||
<g id="black-rgb">
|
||||
<path
|
||||
id="logoMark"
|
||||
d="M77.8271,15.6225,56.08,3.0664a22.8877,22.8877,0,0,0-22.8877,0L11.4438,15.6225A22.8877,22.8877,0,0,0,0,35.4438V60.5562A22.8877,22.8877,0,0,0,11.4438,80.3775L33.1919,92.9336a22.8877,22.8877,0,0,0,22.8877,0L77.8271,80.3775A22.8876,22.8876,0,0,0,89.271,60.5562V35.4438A22.8876,22.8876,0,0,0,77.8271,15.6225ZM44.6357,70.3178A22.3178,22.3178,0,1,1,66.9531,48,22.3176,22.3176,0,0,1,44.6357,70.3178Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
<g id="type">
|
||||
<path
|
||||
id="type_CompoundPathItem_"
|
||||
d="M163.5361,22.6571h14.1416V71.662H169.206V30.078L155.625,71.662h-8.8907l-13.581-41.0948V71.662h-8.4707V22.6571h14.2109l12.3906,39.2734Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
<path
|
||||
id="type_CompoundPathItem_2"
|
||||
d="M220.4453,60.6c-2.03,7.3516-8.2608,12.042-17.0118,12.042-10.9209,0-17.8525-7.3515-17.8525-18.4824s7.001-18.4814,18.0625-18.4814c12.3213,0,18.6914,9.24,15.332,20.7216H194.0517c.7012,5.8106,3.9209,9.2413,9.5215,9.2413,3.92,0,7.001-1.82,8.1914-5.0411Zm-26.253-9.871H211.414c.49-5.04-2.38-8.33-7.9111-8.33C198.2529,42.3993,195.0322,45.34,194.1923,50.7294Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
<path
|
||||
id="type_CompoundPathItem_3"
|
||||
d="M252.5742,22.6571h7.9814V71.662h-7.9814V66.4813a13.8489,13.8489,0,0,1-11.9014,6.1611c-9.24,0-15.752-7.3515-15.752-18.4824,0-11.06,6.4415-18.4814,15.752-18.4814a13.85,13.85,0,0,1,11.9014,6.16Zm.3506,31.5029c0-6.9306-3.9209-11.4814-9.8018-11.4814-5.95,0-9.87,4.5508-9.87,11.4814s3.92,11.4815,9.87,11.4815C249.0039,65.6415,252.9248,61.0907,252.9248,54.16Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
<path
|
||||
id="type_CompoundPathItem_4"
|
||||
d="M290.2333,36.6581h7.9805V71.662h-7.9805V65.3612c-2.4511,4.69-6.4414,7.1406-11.3417,7.1406-9.7305,0-11.2715-9.6611-11.2715-15.8916V36.6581h7.98V56.5409c0,4.62,1.0508,9.03,6.0918,9.03,5.18,0,8.541-4.62,8.541-11.0605Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
<path
|
||||
id="type_CompoundPathItem_5"
|
||||
d="M304.0888,59.1307H311.79c-.49,4.3408,2.7305,7.07,8.1914,7.07,4.2695,0,7.1406-1.68,7.1406-4.2,0-7.0009-22.5429-1.96-22.5429-15.0517,0-7,6.5107-11.27,14.9824-11.27,9.3808,0,16.1709,5.25,14.7011,13.1611h-7.7714c.98-3.99-2.17-6.7207-7-6.7207-4.0606,0-6.7207,1.82-6.7207,4.34,0,7.0713,22.6123,1.6807,22.6123,14.9825,0,7.07-6.3711,11.2011-15.4717,11.2011C310.04,72.6424,303.5292,67.6014,304.0888,59.1307Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
<path
|
||||
id="type_CompoundPathItem_6"
|
||||
d="M371.2226,51.78V71.662H363.872V65.5711a13.7856,13.7856,0,0,1-12.6015,7.0713c-7.42,0-12.0411-4.3408-12.0411-10.4316,0-7.07,6.16-11.3408,16.0313-11.3408a36.6377,36.6377,0,0,1,7.9814.91c0-5.3213-1.8906-9.1709-7.4912-9.1709-4.2,0-6.791,2.1-5.95,6.02H341.749c-1.89-7.77,4.9707-12.9511,14.0722-12.9511C366.0419,35.6786,371.2226,42.0487,371.2226,51.78Zm-7.7,6.0909a25.2,25.2,0,0,0-7.6308-1.19c-5.7413,0-8.5411,2.1006-8.5411,5.32,0,2.8008,2.1,4.27,5.53,4.27A10.8339,10.8339,0,0,0,363.5224,57.871Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default ConfLogo
|
||||
Reference in New Issue
Block a user