feat(dashboard): support RTL in dashboard (#11252)
* fix: add direction attribute to components and adjust styles for RTL support * fix(data-grid): comment it out * Added useDocumentDirection hook * refactor: Integrate useDocumentDirection hook * refactor: Standardize direction prop usage across components * resolve * fix: resolve build errors * fix : remove unused useDocument * Apply RTL styles for some components * Create smooth-gorillas-hide.md * refactor: update some styles for RTL support --------- Co-authored-by: William Bouchard <46496014+willbouch@users.noreply.github.com>
This commit is contained in:
@@ -29,6 +29,7 @@ import { queryClient } from "../../../lib/query-client"
|
||||
import { useExtension } from "../../../providers/extension-provider"
|
||||
import { useSearch } from "../../../providers/search-provider"
|
||||
import { UserMenu } from "../user-menu"
|
||||
import { useDocumentDirection } from "../../../hooks/use-document-direction"
|
||||
|
||||
export const MainLayout = () => {
|
||||
return (
|
||||
@@ -94,7 +95,7 @@ const Logout = () => {
|
||||
const Header = () => {
|
||||
const { t } = useTranslation()
|
||||
const { store, isPending, isError, error } = useStore()
|
||||
|
||||
const direction = useDocumentDirection()
|
||||
const name = store?.name
|
||||
const fallback = store?.name?.slice(0, 1).toUpperCase()
|
||||
|
||||
@@ -106,11 +107,12 @@ const Header = () => {
|
||||
|
||||
return (
|
||||
<div className="w-full p-3">
|
||||
<DropdownMenu>
|
||||
<DropdownMenu
|
||||
dir={direction}>
|
||||
<DropdownMenu.Trigger
|
||||
disabled={!isLoaded}
|
||||
className={clx(
|
||||
"bg-ui-bg-subtle transition-fg grid w-full grid-cols-[24px_1fr_15px] items-center gap-x-3 rounded-md p-0.5 pr-2 outline-none",
|
||||
"bg-ui-bg-subtle transition-fg grid w-full grid-cols-[24px_1fr_15px] items-center gap-x-3 rounded-md p-0.5 pe-2 outline-none",
|
||||
"hover:bg-ui-bg-subtle-hover",
|
||||
"data-[state=open]:bg-ui-bg-subtle-hover",
|
||||
"focus-visible:shadow-borders-focus"
|
||||
@@ -121,7 +123,7 @@ const Header = () => {
|
||||
) : (
|
||||
<Skeleton className="h-6 w-6 rounded-md" />
|
||||
)}
|
||||
<div className="block overflow-hidden text-left">
|
||||
<div className="block overflow-hidden text-start">
|
||||
{name ? (
|
||||
<Text
|
||||
size="small"
|
||||
@@ -267,7 +269,7 @@ const Searchbar = () => {
|
||||
)}
|
||||
>
|
||||
<MagnifyingGlass />
|
||||
<div className="flex-1 text-left">
|
||||
<div className="flex-1 text-start">
|
||||
<Text size="small" leading="compact" weight="plus">
|
||||
{t("app.search.label")}
|
||||
</Text>
|
||||
|
||||
@@ -156,7 +156,7 @@ const Breadcrumbs = () => {
|
||||
)}
|
||||
{!isLast && (
|
||||
<span className="mx-2">
|
||||
<TriangleRightMini />
|
||||
<TriangleRightMini className="rtl:rotate-180" />
|
||||
</span>
|
||||
)}
|
||||
</li>
|
||||
@@ -177,7 +177,7 @@ const ToggleSidebar = () => {
|
||||
onClick={() => toggle("desktop")}
|
||||
size="small"
|
||||
>
|
||||
<SidebarLeft className="text-ui-fg-muted" />
|
||||
<SidebarLeft className="text-ui-fg-muted rtl:rotate-180" />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
className="hidden max-lg:flex"
|
||||
@@ -185,7 +185,7 @@ const ToggleSidebar = () => {
|
||||
onClick={() => toggle("mobile")}
|
||||
size="small"
|
||||
>
|
||||
<SidebarLeft className="text-ui-fg-muted" />
|
||||
<SidebarLeft className="text-ui-fg-muted rtl:rotate-180" />
|
||||
</IconButton>
|
||||
</div>
|
||||
)
|
||||
@@ -210,7 +210,7 @@ const DesktopSidebarContainer = ({ children }: PropsWithChildren) => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clx("hidden h-screen w-[220px] border-r", {
|
||||
className={clx("hidden h-screen w-[220px] border-e", {
|
||||
"lg:flex": desktop,
|
||||
})}
|
||||
>
|
||||
@@ -234,8 +234,8 @@ const MobileSidebarContainer = ({ children }: PropsWithChildren) => {
|
||||
/>
|
||||
<RadixDialog.Content
|
||||
className={clx(
|
||||
"bg-ui-bg-subtle shadow-elevation-modal fixed inset-y-2 left-2 flex w-full max-w-[304px] flex-col overflow-hidden rounded-lg border-r",
|
||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:slide-out-to-left-1/2 data-[state=open]:slide-in-from-left-1/2 duration-200"
|
||||
"bg-ui-bg-subtle shadow-elevation-modal fixed inset-y-2 start-2 flex w-full max-w-[304px] flex-col overflow-hidden rounded-lg border-r",
|
||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:slide-out-to-start-1/2 data-[state=open]:slide-in-from-start-1/2 duration-200"
|
||||
)}
|
||||
>
|
||||
<div className="p-3">
|
||||
|
||||
@@ -29,10 +29,12 @@ import { useLogout, useMe } from "../../../hooks/api"
|
||||
import { queryClient } from "../../../lib/query-client"
|
||||
import { useGlobalShortcuts } from "../../../providers/keybind-provider/hooks"
|
||||
import { useTheme } from "../../../providers/theme-provider"
|
||||
import { useDocumentDirection } from "../../../hooks/use-document-direction"
|
||||
|
||||
export const UserMenu = () => {
|
||||
const { t } = useTranslation()
|
||||
const location = useLocation()
|
||||
const direction = useDocumentDirection()
|
||||
|
||||
const [openMenu, setOpenMenu] = useState(false)
|
||||
const [openModal, setOpenModal] = useState(false)
|
||||
@@ -44,33 +46,33 @@ export const UserMenu = () => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<DropdownMenu open={openMenu} onOpenChange={setOpenMenu}>
|
||||
<DropdownMenu dir={direction} open={openMenu} onOpenChange={setOpenMenu}>
|
||||
<UserBadge />
|
||||
<DropdownMenu.Content className="min-w-[var(--radix-dropdown-menu-trigger-width)] max-w-[var(--radix-dropdown-menu-trigger-width)]">
|
||||
<UserItem />
|
||||
<DropdownMenu.Separator />
|
||||
<DropdownMenu.Item asChild>
|
||||
<Link to="/settings/profile" state={{ from: location.pathname }}>
|
||||
<UserIcon className="text-ui-fg-subtle mr-2" />
|
||||
<UserIcon className="text-ui-fg-subtle me-2" />
|
||||
{t("app.menus.user.profileSettings")}
|
||||
</Link>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Separator />
|
||||
<DropdownMenu.Item asChild>
|
||||
<Link to="https://docs.medusajs.com" target="_blank">
|
||||
<BookOpen className="text-ui-fg-subtle mr-2" />
|
||||
<BookOpen className="text-ui-fg-subtle me-2" />
|
||||
{t("app.menus.user.documentation")}
|
||||
</Link>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item asChild>
|
||||
<Link to="https://medusajs.com/changelog/" target="_blank">
|
||||
<TimelineVertical className="text-ui-fg-subtle mr-2" />
|
||||
<TimelineVertical className="text-ui-fg-subtle me-2" />
|
||||
{t("app.menus.user.changelog")}
|
||||
</Link>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Separator />
|
||||
<DropdownMenu.Item onClick={toggleModal}>
|
||||
<Keyboard className="text-ui-fg-subtle mr-2" />
|
||||
<Keyboard className="text-ui-fg-subtle me-2" />
|
||||
{t("app.menus.user.shortcuts")}
|
||||
</DropdownMenu.Item>
|
||||
<ThemeToggle />
|
||||
@@ -93,7 +95,7 @@ const UserBadge = () => {
|
||||
|
||||
if (isPending) {
|
||||
return (
|
||||
<button className="shadow-borders-base flex max-w-[192px] select-none items-center gap-x-2 overflow-hidden text-ellipsis whitespace-nowrap rounded-full py-1 pl-1 pr-2.5">
|
||||
<button className="shadow-borders-base flex max-w-[192px] select-none items-center gap-x-2 overflow-hidden text-ellipsis whitespace-nowrap rounded-full py-1 ps-1 pe-2.5">
|
||||
<Skeleton className="h-5 w-5 rounded-full" />
|
||||
<Skeleton className="h-[9px] w-[70px]" />
|
||||
</button>
|
||||
@@ -109,7 +111,7 @@ const UserBadge = () => {
|
||||
<DropdownMenu.Trigger
|
||||
disabled={!user}
|
||||
className={clx(
|
||||
"bg-ui-bg-subtle grid w-full cursor-pointer grid-cols-[24px_1fr_15px] items-center gap-2 rounded-md py-1 pl-0.5 pr-2 outline-none",
|
||||
"bg-ui-bg-subtle grid w-full cursor-pointer grid-cols-[24px_1fr_15px] items-center gap-2 rounded-md py-1 ps-0.5 pe-2 outline-none",
|
||||
"hover:bg-ui-bg-subtle-hover",
|
||||
"data-[state=open]:bg-ui-bg-subtle-hover",
|
||||
"focus-visible:shadow-borders-focus"
|
||||
@@ -148,9 +150,9 @@ const ThemeToggle = () => {
|
||||
|
||||
return (
|
||||
<DropdownMenu.SubMenu>
|
||||
<DropdownMenu.SubMenuTrigger className="rounded-md">
|
||||
<CircleHalfSolid className="text-ui-fg-subtle mr-2" />
|
||||
{t("app.menus.user.theme.label")}
|
||||
<DropdownMenu.SubMenuTrigger dir="ltr" className="rounded-md rtl:rotate-180">
|
||||
<CircleHalfSolid className="text-ui-fg-subtle me-2" />
|
||||
<span className="rtl:rotate-180">{t("app.menus.user.theme.label")}</span>
|
||||
</DropdownMenu.SubMenuTrigger>
|
||||
<DropdownMenu.SubMenuContent>
|
||||
<DropdownMenu.RadioGroup value={theme}>
|
||||
|
||||
Reference in New Issue
Block a user