diff --git a/docs/content/homepage.mdx b/docs/content/homepage.mdx index 401031b488..141111a14b 100644 --- a/docs/content/homepage.mdx +++ b/docs/content/homepage.mdx @@ -69,7 +69,7 @@ Medusa provides the essential building blocks that developers can put together t label: 'Medusa Backend', customProps: { icon: Icons['circle-stack-solid'], - html: 'A Medusa Backend is any Node.js project with @medusajs/medusa installed. The core Medusa package orchestrates Medusa\'s Commerce Modules to expose a powerful and customizable REST API.', + html: 'A Medusa Backend is any Node.js project with @medusajs/medusa installed. The core Medusa package orchestrates Medusa\'s Commerce Modules to expose powerful and customizable REST APIs.', } }, { @@ -78,7 +78,7 @@ Medusa provides the essential building blocks that developers can put together t label: 'Admin Dashboard', customProps: { icon: Icons['computer-desktop-solid'], - description: 'An intuitive admin dashboard along with the Medusa backend and commerce modules. Merchants can use it to perform data management and processes such as manage orders, products, customers, and much more.' + description: 'An admin dashboard used along with the Medusa backend and commerce modules. Merchants can use it to manage orders, products, customers, and much more.' } }, ]} /> diff --git a/docs/content/modules/overview.mdx b/docs/content/modules/overview.mdx index 95f876884a..fb7297b656 100644 --- a/docs/content/modules/overview.mdx +++ b/docs/content/modules/overview.mdx @@ -22,7 +22,7 @@ This section gives an overview of the features available in Medusa. You can lear Medusa provides the necessary features to build a customizable shopping experience for your customers. Medusa also offers features optimized for business operations to manage their orders effeciently. - + + - - - - Create discounts and deals with advanced conditions and rules such as minimum cart quantity or specific products. - - Offer free shipping, fixed discount, or percentage discount. - - Override product prices using price lists and set special conditions such as specific customer groups. - - Import prices into a price list from a CSV file. - - + + + +- Create discounts and deals with advanced conditions and rules such as minimum cart quantity or specific products. +- Offer free shipping, fixed discount, or percentage discount. +- Override product prices using price lists and set special conditions such as specific customer groups. +- Import prices into a price list from a CSV file. + + + + ### Ready Configurations for International Selling Medusa's multi-region setup and sales channels allow businesses to sell internationally and sell across platforms. Medusa allows configuring regions differently to cater for different markets across the globe. - + - - - - Create sales channels for your different platforms such as web, mobile, or marketplaces. - - Specify the availability of products for each sales channel. - - Associate orders with each sales channel for better handling and logistics. - - Associate API keys with sales channels for easier development. - - + + +- Create sales channels for your different platforms such as web, mobile, or marketplaces. +- Specify the availability of products for each sales channel. +- Associate orders with each sales channel for better handling and logistics. +- Associate API keys with sales channels for easier development. + + + + ## Get Additional Help If you have any questions about Medusa, its features, and development with it, feel free to reach out to the core team and the community behind Medusa on [Discord](https://discord.gg/medusajs). diff --git a/www/docs/docusaurus.config.js b/www/docs/docusaurus.config.js index 24c8b451dc..7afb32d11c 100644 --- a/www/docs/docusaurus.config.js +++ b/www/docs/docusaurus.config.js @@ -141,6 +141,7 @@ const config = { }, docs: { sidebar: { + hideable: true, autoCollapseCategories: true, }, }, diff --git a/www/docs/src/components/LargeCard/index.tsx b/www/docs/src/components/LargeCard/index.tsx index 9ab80d0882..5731dc35af 100644 --- a/www/docs/src/components/LargeCard/index.tsx +++ b/www/docs/src/components/LargeCard/index.tsx @@ -15,6 +15,7 @@ type LargeCardProps = { href: string } isSoon?: boolean + className?: string } & React.HTMLAttributes const LargeCard: React.FC = ({ @@ -23,26 +24,21 @@ const LargeCard: React.FC = ({ title, action: { href }, isSoon = false, + className = "", children, }) => { return (
@@ -60,7 +56,7 @@ const LargeCard: React.FC = ({ iconWrapperClassName="tw-p-[6px]" /> )} -
+
= ({ children, }) => { return ( -
+
{children}
) diff --git a/www/docs/src/components/Navbar/Actions/index.tsx b/www/docs/src/components/Navbar/Actions/index.tsx index 18bedd8802..46f4dcfee1 100644 --- a/www/docs/src/components/Navbar/Actions/index.tsx +++ b/www/docs/src/components/Navbar/Actions/index.tsx @@ -6,27 +6,32 @@ import clsx from "clsx" type NavbarActionsProps = { items: NavbarAction[] + className?: string } & React.HTMLAttributes -const NavbarActions: React.FC = ({ items = [] }) => { +const NavbarActions: React.FC = ({ + items = [], + className = "", +}) => { return ( -
+
{items.map((item, index) => { + // eslint-disable-next-line no-case-declarations + const ItemIcon = item.icon ? Icon[item.icon] : null switch (item.type) { case "link": - // eslint-disable-next-line no-case-declarations - const ItemIcon = item.icon ? Icon[item.icon] : null return ( - + @@ -35,6 +40,26 @@ const NavbarActions: React.FC = ({ items = [] }) => { ) + case "button": + return ( + + + + ) default: return <> } diff --git a/www/docs/src/components/Tooltip/index.tsx b/www/docs/src/components/Tooltip/index.tsx index 428de6eef1..c42cfeb448 100644 --- a/www/docs/src/components/Tooltip/index.tsx +++ b/www/docs/src/components/Tooltip/index.tsx @@ -5,15 +5,17 @@ import uuid from "react-uuid" import "react-tooltip/dist/react-tooltip.css" type TooltipProps = { - text: string + text?: string tooltipClassName?: string + html?: string } & React.HTMLAttributes & ITooltip const Tooltip: React.FC = ({ - text, + text = "", tooltipClassName = "", children, + html = "", }) => { const [elementId, setElementId] = useState(null) @@ -25,7 +27,7 @@ const Tooltip: React.FC = ({ return ( <> - + {children} void + hiddenSidebarContainer: boolean + setHiddenSidebarContainer: (value: boolean) => void + floatingSidebar: boolean + setFloatingSidebar: (value: boolean) => void + onCollapse: () => void +} + +export const SidebarContext = createContext(null) diff --git a/www/docs/src/css/_docusaurus.css b/www/docs/src/css/_docusaurus.css index 4cf6b88147..b6e60ea455 100644 --- a/www/docs/src/css/_docusaurus.css +++ b/www/docs/src/css/_docusaurus.css @@ -170,7 +170,7 @@ details summary { } .container { - @apply !tw-pt-[38px] !tw-max-w-full; + @apply !tw-pt-3 !tw-max-w-full; } .pagination-nav { @@ -234,7 +234,7 @@ html:not(.plugin-redoc) .navbar:not(.navbar-sidebar--show) { } .navbar__brand { - @apply tw-mr-2; + @apply tw-mr-1.5; } .navbar__logo { diff --git a/www/docs/src/css/components/sidebar.css b/www/docs/src/css/components/sidebar.css index 847b234758..d0c47bae0f 100644 --- a/www/docs/src/css/components/sidebar.css +++ b/www/docs/src/css/components/sidebar.css @@ -1,7 +1,5 @@ .theme-doc-sidebar-container { --animate-duration: 0.2s; - - clip-path: inset(0); } .sidebar-desktop nav { diff --git a/www/docs/src/css/custom.css b/www/docs/src/css/custom.css index 83b8db3ea3..ff997968a1 100644 --- a/www/docs/src/css/custom.css +++ b/www/docs/src/css/custom.css @@ -115,12 +115,28 @@ .btn-primary { @apply tw-inline-flex tw-flex-row tw-justify-center tw-items-center; @apply tw-py-[6px] tw-px-[12px] tw-rounded tw-cursor-pointer; - @apply tw-bg-medusa-button-secondary dark:tw-bg-medusa-button-secondary-dark; - @apply hover:tw-bg-medusa-button-secondary-hover dark:hover:tw-bg-medusa-button-secondary-hover-dark hover:tw-no-underline; - @apply tw-border tw-border-solid tw-border-medusa-border-base dark:tw-border-medusa-border-base-dark; + @apply tw-bg-button-neutral dark:tw-bg-button-neutral-dark; + @apply hover:!tw-bg-no-image hover:tw-bg-medusa-button-neutral-hover dark:hover:tw-bg-medusa-button-neutral-hover-dark hover:tw-no-underline; + @apply active:!tw-bg-no-image active:tw-bg-medusa-button-neutral-pressed dark:active:tw-bg-medusa-button-neutral-pressed; + @apply focus:tw-shadow-neutral-button-focused dark:focus:tw-shadow-neutral-button-focused-dark; + @apply disabled:!tw-bg-no-image disabled:tw-bg-medusa-button-disabled dark:disabled:tw-bg-medusa-button-disabled-dark; + @apply tw-border tw-border-solid tw-border-medusa-border-neutral-buttons dark:tw-border-medusa-border-neutral-buttons-dark; @apply tw-text-label-small-plus tw-text-medusa-text-base dark:tw-text-medusa-text-base-dark; @apply hover:tw-text-medusa-text-base dark:hover:tw-text-medusa-text-base-dark; - @apply focus:tw-shadow-button-focused dark:focus:tw-shadow-button-focused-dark; + } + + .navbar-action-icon-item { + @apply tw-bg-button-neutral dark:tw-bg-button-neutral-dark hover:!tw-bg-no-image active:!tw-bg-no-image hover:tw-bg-medusa-button-neutral-hover dark:hover:tw-bg-medusa-button-neutral-hover-dark; + @apply active:tw-bg-medusa-button-neutral-pressed dark:active:tw-bg-medusa-button-neutral-pressed-dark; + @apply focus:tw-shadow-neutral-button-focused dark:focus:tw-shadow-neutral-button-focused-dark; + @apply tw-border tw-border-solid tw-border-medusa-border-neutral-buttons dark:tw-border-medusa-border-neutral-buttons-dark tw-rounded; + @apply tw-w-2 tw-h-2 tw-flex tw-justify-center tw-items-center tw-cursor-pointer; + } +} + +@layer utilities { + .clip { + clip-path: inset(0); } } diff --git a/www/docs/src/theme/AnnouncementBar/index.tsx b/www/docs/src/theme/AnnouncementBar/index.tsx index 0fb428cc14..313c648e3a 100644 --- a/www/docs/src/theme/AnnouncementBar/index.tsx +++ b/www/docs/src/theme/AnnouncementBar/index.tsx @@ -19,7 +19,7 @@ export default function AnnouncementBar(): JSX.Element | null {
- +
diff --git a/www/docs/src/theme/DocCard/index.tsx b/www/docs/src/theme/DocCard/index.tsx index 15b5c80ae9..0b832e945f 100644 --- a/www/docs/src/theme/DocCard/index.tsx +++ b/www/docs/src/theme/DocCard/index.tsx @@ -8,16 +8,17 @@ import { import isInternalUrl from "@docusaurus/isInternalUrl" import { translate } from "@docusaurus/Translate" import BorderedIcon from "@site/src/components/BorderedIcon" -import Badge, { BadgeProps } from "@site/src/components/Badge" +import Badge from "@site/src/components/Badge" import Icons from "@site/src/theme/Icon" import { - ModifiedPropSidebarItemCategory, - ModifiedPropSidebarItemLink, + ModifiedDocCard, + ModifiedDocCardItemCategory, + ModifiedDocCardItemLink, ModifiedSidebarItem, } from "@medusajs/docs" type ModifiedProps = { - item: ModifiedSidebarItem + item: ModifiedDocCard } function CardContainer({ @@ -36,9 +37,9 @@ function CardContainer({ className={clsx( "card", "tw-bg-medusa-bg-subtle dark:tw-bg-medusa-bg-base-dark", - "tw-rounded tw-border tw-border-solid tw-border-medusa-bg-subtle-hover dark:tw-border-medusa-bg-base-hover-dark", - "tw-shadow-none tw-transition-all tw-duration-200 tw-ease-ease", - "tw-flex tw-p-1 tw-h-full", + "tw-rounded tw-shadow-card-rest dark:tw-shadow-card-rest-dark", + "tw-transition-all tw-duration-200 tw-ease-ease", + "tw-flex tw-p-1 !tw-pb-1.5 tw-h-full", className )} > @@ -57,16 +58,7 @@ function CardLayout({ containerClassName, isSoon = false, badge, -}: { - href: string - icon: ReactNode - title: string - description?: string - html?: string - containerClassName?: string - isSoon?: boolean - badge?: BadgeProps -}): JSX.Element { +}: ModifiedDocCard): JSX.Element { const isHighlighted = containerClassName?.includes("card-highlighted") return (
) @@ -158,14 +145,7 @@ function getCardIcon(item: ModifiedSidebarItem): JSX.Element { icon={{ light: item.customProps.image, }} - wrapperClassName={ - clsx() - // "card-icon-wrapper", - } - iconWrapperClassName={clsx( - item.customProps?.className?.includes("card-highlighted") && - "tw-p-[6px]" - )} + iconWrapperClassName={clsx("tw-p-[6px]")} iconClassName={clsx("tw-h-[20px] tw-w-[20px]")} /> ) @@ -173,14 +153,7 @@ function getCardIcon(item: ModifiedSidebarItem): JSX.Element { return ( ) @@ -191,14 +164,7 @@ function getCardIcon(item: ModifiedSidebarItem): JSX.Element { return ( ) @@ -223,7 +189,7 @@ function getCardIcon(item: ModifiedSidebarItem): JSX.Element { function CardCategory({ item, }: { - item: ModifiedPropSidebarItemCategory + item: ModifiedDocCardItemCategory }): JSX.Element | null { const href = findFirstCategoryLink(item) const icon = getCardIcon(item) @@ -233,6 +199,7 @@ function CardCategory({ } return (
diff --git a/www/docs/src/theme/DocPage/Layout/Main/index.tsx b/www/docs/src/theme/DocPage/Layout/Main/index.tsx index 9c300c917b..937ab9f13f 100644 --- a/www/docs/src/theme/DocPage/Layout/Main/index.tsx +++ b/www/docs/src/theme/DocPage/Layout/Main/index.tsx @@ -1,24 +1,27 @@ -import React from "react" +import React, { useContext } from "react" import clsx from "clsx" import { useDocsSidebar } from "@docusaurus/theme-common/internal" import type { Props } from "@theme/DocPage/Layout/Main" +import { SidebarContext } from "@site/src/context/sidebar" -export default function DocPageLayoutMain({ - hiddenSidebarContainer, - children, -}: Props): JSX.Element { +export default function DocPageLayoutMain({ children }: Props): JSX.Element { const sidebar = useDocsSidebar() + const sidebarContext = useContext(SidebarContext) return (
{children} diff --git a/www/docs/src/theme/DocPage/Layout/Sidebar/index.tsx b/www/docs/src/theme/DocPage/Layout/Sidebar/index.tsx index a7447fd041..90dbd5540b 100644 --- a/www/docs/src/theme/DocPage/Layout/Sidebar/index.tsx +++ b/www/docs/src/theme/DocPage/Layout/Sidebar/index.tsx @@ -1,12 +1,12 @@ -import React, { type ReactNode, useState, useCallback, useRef } from "react" +import React, { type ReactNode, useRef, useContext } from "react" import clsx from "clsx" import { ThemeClassNames } from "@docusaurus/theme-common" import { useDocsSidebar } from "@docusaurus/theme-common/internal" import { useLocation } from "@docusaurus/router" import DocSidebar from "@theme/DocSidebar" -import ExpandButton from "@theme/DocPage/Layout/Sidebar/ExpandButton" import type { Props } from "@theme/DocPage/Layout/Sidebar" import { SwitchTransition, CSSTransition } from "react-transition-group" +import { SidebarContext } from "@site/src/context/sidebar" // Reset sidebar state when sidebar changes // Use React key to unmount/remount the children @@ -23,18 +23,9 @@ function ResetOnSidebarChange({ children }: { children: ReactNode }) { export default function DocPageLayoutSidebar({ sidebar, hiddenSidebarContainer, - setHiddenSidebarContainer, }: Props): JSX.Element { const { pathname } = useLocation() - - const [hiddenSidebar, setHiddenSidebar] = useState(false) - const toggleSidebar = useCallback(() => { - if (hiddenSidebar) { - setHiddenSidebar(false) - } - setHiddenSidebarContainer((value) => !value) - }, [setHiddenSidebarContainer, hiddenSidebar]) - + const sidebarContext = useContext(SidebarContext) const { name } = useDocsSidebar() const sidebarRef = useRef(null) @@ -42,8 +33,13 @@ export default function DocPageLayoutSidebar({
diff --git a/www/docs/src/theme/DocPage/Layout/index.tsx b/www/docs/src/theme/DocPage/Layout/index.tsx new file mode 100644 index 0000000000..5a163c7244 --- /dev/null +++ b/www/docs/src/theme/DocPage/Layout/index.tsx @@ -0,0 +1,35 @@ +import React, { useContext } from "react" +import { useDocsSidebar } from "@docusaurus/theme-common/internal" +import Layout from "@theme/Layout" +import BackToTopButton from "@theme/BackToTopButton" +import DocPageLayoutSidebar from "@theme/DocPage/Layout/Sidebar" +import DocPageLayoutMain from "@theme/DocPage/Layout/Main" +import type { Props } from "@theme/DocPage/Layout" +import { SidebarContext } from "@site/src/context/sidebar" +import clsx from "clsx" + +export default function DocPageLayout({ children }: Props): JSX.Element { + const sidebar = useDocsSidebar() + const sidebarContext = useContext(SidebarContext) + return ( + + +
+ {sidebar && ( + + )} + + {children} + +
+
+ ) +} diff --git a/www/docs/src/theme/DocPage/index.tsx b/www/docs/src/theme/DocPage/index.tsx index da69eb683d..0faf996568 100644 --- a/www/docs/src/theme/DocPage/index.tsx +++ b/www/docs/src/theme/DocPage/index.tsx @@ -1,9 +1,10 @@ -import React from "react" +import React, { useCallback, useEffect, useState } from "react" import clsx from "clsx" import { HtmlClassNameProvider, ThemeClassNames, PageMetadata, + prefersReducedMotion, } from "@docusaurus/theme-common" import { docVersionSearchTag, @@ -15,6 +16,7 @@ import DocPageLayout from "@theme/DocPage/Layout" import NotFound from "@theme/NotFound" import SearchMetadata from "@theme/SearchMetadata" import type { Props } from "@theme/DocPage" +import { SidebarContext } from "@site/src/context/sidebar" function DocPageMetadata(props: Props): JSX.Element { const { versionMetadata } = props @@ -43,6 +45,52 @@ export default function DocPage(props: Props): JSX.Element { return } const { docElement, sidebarName, sidebarItems } = currentDocRouteMetadata + + const [hiddenSidebar, setHiddenSidebar] = useState(false) + const [hiddenSidebarContainer, setHiddenSidebarContainer] = useState(false) + const [floatingSidebar, setFloatingSidebar] = useState(false) + const toggleSidebar = useCallback(() => { + if (hiddenSidebar) { + setHiddenSidebar(false) + } + // onTransitionEnd won't fire when sidebar animation is disabled + // fixes https://github.com/facebook/docusaurus/issues/8918 + if (!hiddenSidebar && prefersReducedMotion()) { + setHiddenSidebar(true) + } + setHiddenSidebarContainer((value) => !value) + }, [setHiddenSidebarContainer, hiddenSidebar]) + + useEffect(() => { + function isEditingContent(event: KeyboardEvent) { + const element = event.target as HTMLElement + const tagName = element.tagName + return ( + element.isContentEditable || + tagName === "INPUT" || + tagName === "SELECT" || + tagName === "TEXTAREA" + ) + } + + function sidebarShortcut(e: KeyboardEvent) { + if ( + (e.metaKey || e.ctrlKey) && + e.key.toLowerCase() === "i" && + !isEditingContent(e) + ) { + e.preventDefault() + toggleSidebar() + } + } + + window.addEventListener("keydown", sidebarShortcut) + + return () => { + window.removeEventListener("keydown", sidebarShortcut) + } + }) + return ( <> @@ -57,7 +105,19 @@ export default function DocPage(props: Props): JSX.Element { > - {docElement} + + {docElement} + diff --git a/www/docs/src/theme/DocSidebar/Desktop/index.tsx b/www/docs/src/theme/DocSidebar/Desktop/index.tsx index a29b5aea82..d3dd77b414 100644 --- a/www/docs/src/theme/DocSidebar/Desktop/index.tsx +++ b/www/docs/src/theme/DocSidebar/Desktop/index.tsx @@ -1,19 +1,15 @@ import React, { useEffect, useRef } from "react" import clsx from "clsx" import { useThemeConfig } from "@docusaurus/theme-common" -import CollapseButton from "@theme/DocSidebar/Desktop/CollapseButton" import Content from "@theme/DocSidebar/Desktop/Content" import type { Props } from "@theme/DocSidebar/Desktop" import useIsBrowser from "@docusaurus/useIsBrowser" import { useLocation } from "@docusaurus/router" import AnnouncementBar from "../../AnnouncementBar/index" -function DocSidebarDesktop({ path, sidebar, onCollapse, isHidden }: Props) { +function DocSidebarDesktop({ path, sidebar, isHidden }: Props) { const { navbar: { hideOnScroll }, - docs: { - sidebar: { hideable }, - }, } = useThemeConfig() const isBrowser = useIsBrowser() const sidebarRef = useRef(null) @@ -82,9 +78,7 @@ function DocSidebarDesktop({ path, sidebar, onCollapse, isHidden }: Props) { className={clsx( "lg:tw-flex lg:tw-flex-col lg:tw-max-h-screen lg:tw-h-full lg:tw-sticky lg:tw-top-0 lg:tw-transition-opacity lg:tw-duration-[50ms] lg:tw-ease-ease lg:tw-pt-1.5", "sidebar-desktop", - hideOnScroll && "lg:tw-pt-0", - isHidden && - "lg:tw-opacity-0 lg:tw-h-0 lg:tw-overflow-hidden lg:tw-invisible" + hideOnScroll && "lg:tw-pt-0" )} ref={sidebarRef} > @@ -97,7 +91,6 @@ function DocSidebarDesktop({ path, sidebar, onCollapse, isHidden }: Props) { "!tw-mt-0 !tw-pt-0 !tw-px-1.5 !tw-pb-4" )} /> - {hideable && }
) } diff --git a/www/docs/src/theme/DocSidebarItem/Category/index.tsx b/www/docs/src/theme/DocSidebarItem/Category/index.tsx index a6cc39c4d0..e2068af911 100644 --- a/www/docs/src/theme/DocSidebarItem/Category/index.tsx +++ b/www/docs/src/theme/DocSidebarItem/Category/index.tsx @@ -165,7 +165,7 @@ export default function DocSidebarItemCategory({ "[&_.sidebar-item-icon]:tw-w-[20px] [&_.sidebar-item-icon]:tw-h-[20px]", !customProps?.sidebar_is_title && !customProps?.sidebar_is_back_link && - "[&_.sidebar-item-icon]:tw-mr-1" + "[&_.sidebar-item-icon]:tw-mr-[12px]" )} >
diff --git a/www/docs/src/theme/DocSidebarItem/Link/index.tsx b/www/docs/src/theme/DocSidebarItem/Link/index.tsx index 65d9da5562..1d839eeaf3 100644 --- a/www/docs/src/theme/DocSidebarItem/Link/index.tsx +++ b/www/docs/src/theme/DocSidebarItem/Link/index.tsx @@ -42,7 +42,7 @@ export default function DocSidebarItemLink({ "[&_.sidebar-item-icon]:tw-w-[20px] [&_.sidebar-item-icon]:tw-h-[20px]", !customProps?.sidebar_is_title && !customProps?.sidebar_is_back_link && - "[&_.sidebar-item-icon]:tw-mr-1" + "[&_.sidebar-item-icon]:tw-mr-[12px]" )} key={label} > diff --git a/www/docs/src/theme/Icon/BarsThree/index.tsx b/www/docs/src/theme/Icon/BarsThree/index.tsx new file mode 100644 index 0000000000..0336d8d79f --- /dev/null +++ b/www/docs/src/theme/Icon/BarsThree/index.tsx @@ -0,0 +1,31 @@ +import React from "react" +import { IconProps } from ".." + +const IconBarsThree: React.FC = ({ + iconColorClassName, + ...props +}) => { + return ( + + + + ) +} + +export default IconBarsThree diff --git a/www/docs/src/theme/Icon/ChevronDoubleLeftMiniSolid/index.tsx b/www/docs/src/theme/Icon/ChevronDoubleLeftMiniSolid/index.tsx new file mode 100644 index 0000000000..8e5b1c2b69 --- /dev/null +++ b/www/docs/src/theme/Icon/ChevronDoubleLeftMiniSolid/index.tsx @@ -0,0 +1,30 @@ +import React from "react" +import { IconProps } from ".." + +const IconChevronDoubleLeftMiniSolid: React.FC = ({ + iconColorClassName, + ...props +}) => { + return ( + + + + ) +} + +export default IconChevronDoubleLeftMiniSolid diff --git a/www/docs/src/theme/Icon/index.ts b/www/docs/src/theme/Icon/index.ts index 8bc48add91..7bdac3e906 100644 --- a/www/docs/src/theme/Icon/index.ts +++ b/www/docs/src/theme/Icon/index.ts @@ -3,6 +3,7 @@ import IconAdjustments from "./Adjustments" import IconAlert from "./Alert" import IconArrowDownTray from "./ArrowDownTray" import IconBackArrow from "./BackArrow" +import IconBarsThree from "./BarsThree" import IconBell from "./Bell" import IconBellAlertSolid from "./BellAlertSolid" import IconBolt from "./Bolt" @@ -18,6 +19,7 @@ import IconCashSolid from "./CashSolid" import IconChannels from "./Channels" import IconChannelsSolid from "./ChannelsSolid" import IconCheckCircleSolid from "./CheckCircleSolid" +import IconChevronDoubleLeftMiniSolid from "./ChevronDoubleLeftMiniSolid" import IconCircleStack from "./CircleStack" import IconCircleStackSolid from "./CircleStackSolid" import IconClockSolidMini from "./ClockSolidMini" @@ -95,6 +97,7 @@ export default { alert: IconAlert, "arrow-down-tray": IconArrowDownTray, "back-arrow": IconBackArrow, + "bars-three": IconBarsThree, bell: IconBell, "bell-alert-solid": IconBellAlertSolid, bolt: IconBolt, @@ -110,6 +113,7 @@ export default { "channels-solid": IconChannelsSolid, channels: IconChannels, "check-circle-solid": IconCheckCircleSolid, + "chevron-double-left-mini-solid": IconChevronDoubleLeftMiniSolid, "circle-stack": IconCircleStack, "circle-stack-solid": IconCircleStackSolid, "clock-solid-mini": IconClockSolidMini, diff --git a/www/docs/src/theme/Navbar/ColorModeToggle/index.tsx b/www/docs/src/theme/Navbar/ColorModeToggle/index.tsx new file mode 100644 index 0000000000..e654394432 --- /dev/null +++ b/www/docs/src/theme/Navbar/ColorModeToggle/index.tsx @@ -0,0 +1,26 @@ +import React from "react" +import { useColorMode, useThemeConfig } from "@docusaurus/theme-common" +import ColorModeToggle from "@theme/ColorModeToggle" +import type { Props } from "@theme/Navbar/ColorModeToggle" + +export default function NavbarColorModeToggle({ + className, +}: Props): JSX.Element | null { + const disabled = useThemeConfig().colorMode.disableSwitch + const { colorMode, setColorMode } = useColorMode() + + if (disabled) { + return null + } + + return ( + + ) +} diff --git a/www/docs/src/theme/Navbar/Content/index.tsx b/www/docs/src/theme/Navbar/Content/index.tsx index 3cb3f57cf0..844a44c7cb 100644 --- a/www/docs/src/theme/Navbar/Content/index.tsx +++ b/www/docs/src/theme/Navbar/Content/index.tsx @@ -1,4 +1,4 @@ -import React, { type ReactNode } from "react" +import React, { useContext, type ReactNode } from "react" import { useThemeConfig } from "@docusaurus/theme-common" import { splitNavbarItems, @@ -11,7 +11,9 @@ import NavbarLogo from "@theme/Navbar/Logo" import NavbarActions from "@site/src/components/Navbar/Actions" import Tooltip from "@site/src/components/Tooltip" import { ThemeConfig } from "@medusajs/docs" +import useIsBrowser from "@docusaurus/useIsBrowser" import clsx from "clsx" +import { SidebarContext } from "@site/src/context/sidebar" function useNavbarItems() { // TODO temporary casting until ThemeConfig type is improved @@ -62,7 +64,18 @@ export default function NavbarContent(): JSX.Element { const items = useNavbarItems() const [leftItems, rightItems] = splitNavbarItems(items) - const { navbarActions } = useThemeConfig() as ThemeConfig + const { + navbarActions, + docs: { + sidebar: { hideable }, + }, + } = useThemeConfig() as ThemeConfig + const sidebarContext = useContext(SidebarContext) + const isBrowser = useIsBrowser() + + const isApple = isBrowser + ? navigator.userAgent.toLowerCase().indexOf("mac") !== 0 + : true return ( {!mobileSidebar.disabled && } + {hideable && ( + Close sidebar ${isApple ? "⌘" : "Ctrl"} + I` + : `Lock sidebar open ${isApple ? "⌘" : "Ctrl"} + I`, + events: { + onClick: sidebarContext?.onCollapse, + onMouseEnter: () => { + if (!sidebarContext?.hiddenSidebarContainer) { + sidebarContext?.setFloatingSidebar(false) + } else { + sidebarContext?.setFloatingSidebar(true) + } + }, + onMouseLeave: () => { + setTimeout(() => { + if ( + !document.querySelector( + ".theme-doc-sidebar-container:hover" + ) + ) { + sidebarContext?.setFloatingSidebar(false) + } + }, 100) + }, + }, + icon: !sidebarContext?.hiddenSidebarContainer + ? "bars-three" + : "chevron-double-left-mini-solid", + }, + ]} + className="tw-mr-0.5 sidebar-toggler" + /> + )} } @@ -88,9 +160,7 @@ export default function NavbarContent(): JSX.Element { button]:!tw-rounded" + "navbar-action-icon-item !tw-w-2 !tw-h-2 tw-ml-1 tw-mr-[12px] [&>button]:!tw-rounded" )} /> diff --git a/www/docs/src/types/index.d.ts b/www/docs/src/types/index.d.ts index 61a406a3c3..7b52979da7 100644 --- a/www/docs/src/types/index.d.ts +++ b/www/docs/src/types/index.d.ts @@ -30,6 +30,7 @@ declare module "@medusajs/docs" { import { BadgeProps } from "../components/Badge/index" import { IconProps } from "../theme/Icon/index" import { DocContextValue as DocusaurusDocContextValue } from "@docusaurus/theme-common/internal" + import { ReactNode } from "react" type ItemCustomProps = { customProps?: { @@ -69,20 +70,64 @@ declare module "@medusajs/docs" { | ModifiedPropSidebarItemLink | ModifiedPropSidebarItemHtml + export declare type ModifiedDocCardBase = { + type: string + href: string + icon: ReactNode | string + title: string + description?: string + html?: string + containerClassName?: string + isSoon?: boolean + badge?: BadgeProps + children?: React.ReactNode + } + + export declare type ModifiedDocCardItemLink = { + type: "link" + } & ModifiedDocCardBase & + ModifiedPropSidebarItemLink + + export declare type ModifiedDocCardItemCategory = { + type: "category" + } & ModifiedDocCardBase & + ModifiedPropSidebarItemCategory + + export declare type ModifiedDocCard = + | ModifiedDocCardItemLink + | ModifiedDocCardItemCategory + export declare type SocialLink = { href: string type: string } - export declare type NavbarAction = { - type: "link" - href: string + export declare type NavbarActionBase = { + type: string title?: string icon?: string className?: string label?: string + html?: string } + export declare type NavbarActionLink = NavbarActionBase & { + type: "link" + href: string + } + + export declare type NavbarActionButton = NavbarActionBase & { + type: "button" + events?: { + onClick?: (e: any) => any + onMouseEnter?: (e: any) => any + onMouseLeave?: (e: any) => any + onMouseOver?: (e: any) => any + } + } + + export declare type NavbarAction = NavbarActionLink | NavbarActionButton + export declare type ThemeConfig = { reportCodeLinkPrefix?: string footerFeedback: { diff --git a/www/docs/tailwind.config.js b/www/docs/tailwind.config.js index 826e5060e6..c0dbb6c6cb 100644 --- a/www/docs/tailwind.config.js +++ b/www/docs/tailwind.config.js @@ -179,6 +179,10 @@ module.exports = { DEFAULT: "#6E56CF", dark: "#6E56CF", }, + "neutral-buttons": { + DEFAULT: "#11181C1A", + dark: "#FFFFFF1F", + }, }, text: { base: { @@ -255,6 +259,20 @@ module.exports = { DEFAULT: "#30A46C", dark: "#30A46C", }, + neutral: { + hover: { + DEFAULT: "#F8F9FA", + dark: "#2E2E32", + }, + pressed: { + DEFAULT: "#F1F3F5", + dark: "#34343A", + }, + }, + disabled: { + DEFAULT: "#ECEEF0", + dark: "#28282C", + }, }, icon: { primary: { @@ -289,6 +307,10 @@ module.exports = { DEFAULT: "#E5484D", dark: "#E5484D", }, + subtle: { + DEFAULT: "#687076", + dark: "#7E7D86", + }, }, support: { error: { @@ -418,6 +440,28 @@ module.exports = { dark: "#0D3868", }, }, + neutral: { + bg: { + DEFAULT: "#F1F3F5", + dark: "#28282C", + hover: { + DEFAULT: "#ECEEF0", + dark: "#2E2E32", + }, + }, + text: { + DEFAULT: "#687076", + dark: "#A09FA6", + }, + icon: { + DEFAULT: "#889096", + dark: "#706F78", + }, + border: { + DEFAULT: "#DFE3E6", + dark: "#3E3E44", + }, + }, }, }, /* docs defaults */ @@ -442,6 +486,22 @@ module.exports = { "0px 0px 0px 2px #1C1C1F, 0px 0px 0px 4px #6E56CF", navbar: "0px 1px 0px 0px #E6E8EB", "navbar-dark": "0px 1px 0px 0px #2E2E32", + flyout: + "0px 0px 0px 1px rgba(17, 24, 28, 0.08), 0px 8px 16px rgba(17, 24, 28, 0.08)", + "flyout-dark": + "0px 0px 0px 1px rgba(255, 255, 255, 0.1), 0px 8px 16px rgba(0, 0, 0, 0.32)", + "neutral-button-focused": + "0px 0px 0px 2px #FFFFFF, 0px 0px 0px 4px #6E56CF", + "neutral-button-focused-dark": + "0px 0px 0px 2px #1C1C1F, 0px 0px 0px 4px #6E56CF", + "card-rest": + "0px 0px 0px 1px rgba(17, 24, 28, 0.08), 0px 1px 2px -1px rgba(17, 24, 28, 0.08), 0px 2px 4px rgba(17, 24, 28, 0.04)", + "card-rest-dark": + "0px 0px 0px 1px rgba(255, 255, 255, 0.1), 0px 1px 2px -1px rgba(255, 255, 255, 0.16), 0px 2px 4px rgba(0, 0, 0, 0.32)", + "card-hover": + "0px 0px 0px 1px rgba(17, 24, 28, 0.08), 0px 1px 2px -1px rgba(17, 24, 28, 0.08), 0px 2px 8px rgba(17, 24, 28, 0.1)", + "card-hover-dark": + "0px 0px 0px 1px rgba(255, 255, 255, 0.1), 0px 1px 2px -1px rgba(255, 255, 255, 0.16), 0px 2px 8px rgba(0, 0, 0, 0.32)", }, borderRadius: { DEFAULT: "8px", @@ -454,6 +514,11 @@ module.exports = { "primary-gradient": "linear-gradient(90deg, rgba(146, 144, 254, 0) 0%, rgba(163, 219, 254, 0.4) 26.04%, #9290FE 53.65%, rgba(197, 145, 255, 0.4) 78.65%, rgba(201, 138, 255, 0) 100%)", "code-fade": "linear-gradient(90deg, #1C1C1F00, #1C1C1F 24px)", + "button-neutral": + "linear-gradient(180deg, #FFFFFF 30.1%, #F8F9FA 100%)", + "button-neutral-dark": + "linear-gradient(180deg, #2E2E32 0%, #28282C 32.67%)", + "no-image": "none", }, screens: { xs: "576px", @@ -465,8 +530,8 @@ module.exports = { ease: "ease", }, width: { - sidebar: "320px", - "sidebar-hidden": "30px", + sidebar: "321px", + "sidebar-hidden": "0px", "main-content": "1140px", "main-content-hidden-sidebar": "1440px", },