From a75cf7fb36cf1858c6c9bda1126b092e923beff6 Mon Sep 17 00:00:00 2001 From: Ayman Mustafa <84941140+MEClouds@users.noreply.github.com> Date: Tue, 23 Sep 2025 16:11:30 +0100 Subject: [PATCH] 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> --- .changeset/smooth-gorillas-hide.md | 5 ++ .../common/action-menu/action-menu.tsx | 4 +- .../json-view-section/json-view-section.tsx | 5 +- .../common/sidebar-link/sidebar-link.tsx | 2 +- .../common/switch-box/switch-box.tsx | 2 + .../data-grid/components/data-grid-root.tsx | 12 +++-- .../data-grid-toggleable-number-cell.tsx | 3 +- .../filtering/filter-group/filter-group.tsx | 6 ++- .../filtering/order-by/order-by.tsx | 5 +- .../forms/address-form/address-form.tsx | 9 +++- .../forms/metadata-form/metadata-form.tsx | 9 ++-- .../components/inputs/combobox/combobox.tsx | 22 ++++---- .../inputs/country-select/country-select.tsx | 2 +- .../province-select/province-select.tsx | 2 +- .../layout/main-layout/main-layout.tsx | 12 +++-- .../src/components/layout/shell/shell.tsx | 12 ++--- .../components/layout/user-menu/user-menu.tsx | 22 ++++---- .../src/components/search/search.tsx | 8 +-- .../data-table-order-by.tsx | 5 +- .../data-table-root/data-table-root.tsx | 6 +-- .../form-extension-zone.tsx | 2 +- .../src/hooks/use-document-direction.tsx | 54 +++++++++++++++++++ .../providers/i18n-provider/i18n-provider.tsx | 13 +++-- .../campaign-budget/campaign-budget.tsx | 6 +-- .../create-campaign-form-fields.tsx | 5 +- .../create-category-details.tsx | 15 ++++-- .../create-category-form.tsx | 7 +-- .../category-organize-section.tsx | 2 +- .../edit-category-form/edit-category-form.tsx | 15 ++++-- .../inventory-create-form.tsx | 4 +- .../variants-section.tsx | 2 +- .../create-shipping-option-details-form.tsx | 5 +- .../create-shipping-options-form.tsx | 4 +- .../edit-shipping-option-form.tsx | 9 +++- .../order-allocate-items-form.tsx | 9 +++- .../claim-create-form/claim-create-form.tsx | 3 +- .../order-edit-create-form.tsx | 3 +- .../exchange-create-form.tsx | 3 +- .../order-create-fulfillment-form.tsx | 6 ++- .../create-refund-form/create-refund-form.tsx | 3 ++ .../return-create-form/return-create-form.tsx | 3 +- .../order-create-shipment-form.tsx | 2 + .../order-receive-return-form.tsx | 3 +- .../price-list-create-form.tsx | 4 +- .../price-list-details-form.tsx | 10 +++- .../edit-price-list-form.tsx | 15 ++++-- .../price-list-prices-add-form.tsx | 15 ++++-- .../product-edit-variant-form.tsx | 4 ++ .../category-combobox/category-combobox.tsx | 22 ++++---- .../create-product-variant-form.tsx | 15 ++++-- .../details-tab.tsx | 7 ++- .../product-create-form.tsx | 4 +- .../edit-product-form/edit-product-form.tsx | 9 +++- .../product-media-gallery.tsx | 4 +- .../hooks/use-product-stock-columns.tsx | 3 +- .../edit-profile-form/edit-profile-form.tsx | 12 +++-- .../rules-form-field/rules-form-field.tsx | 4 ++ .../add-campaign-promotion-form.tsx | 10 +++- .../create-promotion-form.tsx | 15 ++++-- .../edit-promotion-details-form.tsx | 7 ++- .../create-region-form/create-region-form.tsx | 13 ++++- .../edit-region-form/edit-region-form.tsx | 13 ++++- .../components/edit-reservation-form.tsx | 4 +- .../create-sales-channel-form.tsx | 2 + .../edit-sales-channel-form.tsx | 2 + .../add-currencies-form.tsx | 2 + .../edit-store-form/edit-store-form.tsx | 9 +++- .../tax-region-tax-override-create.tsx | 4 +- .../tax-region-tax-override-edit-form.tsx | 4 +- .../workflow-execution-timeline-section.tsx | 5 +- 70 files changed, 407 insertions(+), 142 deletions(-) create mode 100644 .changeset/smooth-gorillas-hide.md create mode 100644 packages/admin/dashboard/src/hooks/use-document-direction.tsx diff --git a/.changeset/smooth-gorillas-hide.md b/.changeset/smooth-gorillas-hide.md new file mode 100644 index 0000000000..9b4a6df7f2 --- /dev/null +++ b/.changeset/smooth-gorillas-hide.md @@ -0,0 +1,5 @@ +--- +"@medusajs/dashboard": patch +--- + +feat(dashboard): support RTL in dashboard diff --git a/packages/admin/dashboard/src/components/common/action-menu/action-menu.tsx b/packages/admin/dashboard/src/components/common/action-menu/action-menu.tsx index a9ba82f4aa..1c1a818022 100644 --- a/packages/admin/dashboard/src/components/common/action-menu/action-menu.tsx +++ b/packages/admin/dashboard/src/components/common/action-menu/action-menu.tsx @@ -4,6 +4,7 @@ import { EllipsisHorizontal } from "@medusajs/icons" import { PropsWithChildren, ReactNode } from "react" import { Link } from "react-router-dom" import { ConditionalTooltip } from "../conditional-tooltip" +import { useDocumentDirection } from "../../../hooks/use-document-direction" export type Action = { icon: ReactNode @@ -38,6 +39,7 @@ export const ActionMenu = ({ variant = "transparent", children, }: ActionMenuProps) => { + const direction = useDocumentDirection() const inner = children ?? ( @@ -45,7 +47,7 @@ export const ActionMenu = ({ ) return ( - + {inner} {groups.map((group, index) => { diff --git a/packages/admin/dashboard/src/components/common/json-view-section/json-view-section.tsx b/packages/admin/dashboard/src/components/common/json-view-section/json-view-section.tsx index ba157b5855..fc3f3d7460 100644 --- a/packages/admin/dashboard/src/components/common/json-view-section/json-view-section.tsx +++ b/packages/admin/dashboard/src/components/common/json-view-section/json-view-section.tsx @@ -46,7 +46,10 @@ export const JsonViewSection = ({ data }: JsonViewSectionProps) => { - +
diff --git a/packages/admin/dashboard/src/components/common/sidebar-link/sidebar-link.tsx b/packages/admin/dashboard/src/components/common/sidebar-link/sidebar-link.tsx index 5da28dc2ec..7e0c2c9cb7 100644 --- a/packages/admin/dashboard/src/components/common/sidebar-link/sidebar-link.tsx +++ b/packages/admin/dashboard/src/components/common/sidebar-link/sidebar-link.tsx @@ -37,7 +37,7 @@ export const SidebarLink = ({
- +
diff --git a/packages/admin/dashboard/src/components/common/switch-box/switch-box.tsx b/packages/admin/dashboard/src/components/common/switch-box/switch-box.tsx index 913b8c16d2..4fde523dd9 100644 --- a/packages/admin/dashboard/src/components/common/switch-box/switch-box.tsx +++ b/packages/admin/dashboard/src/components/common/switch-box/switch-box.tsx @@ -50,6 +50,8 @@ export const SwitchBox = <
{ diff --git a/packages/admin/dashboard/src/components/data-grid/components/data-grid-root.tsx b/packages/admin/dashboard/src/components/data-grid/components/data-grid-root.tsx index 9dea7779b9..64ff426ea5 100644 --- a/packages/admin/dashboard/src/components/data-grid/components/data-grid-root.tsx +++ b/packages/admin/dashboard/src/components/data-grid/components/data-grid-root.tsx @@ -29,6 +29,7 @@ import { FieldValues, UseFormReturn } from "react-hook-form" import { useTranslation } from "react-i18next" import { useCommandHistory } from "../../../hooks/use-command-history" +import { useDocumentDirection } from "../../../hooks/use-document-direction" import { ConditionalTooltip } from "../../common/conditional-tooltip" import { DataGridContext } from "../context" import { @@ -50,7 +51,7 @@ import { isCellMatch, isSpecialFocusKey } from "../utils" import { DataGridKeyboardShortcutModal } from "./data-grid-keyboard-shortcut-modal" export interface DataGridRootProps< TData, - TFieldValues extends FieldValues = FieldValues + TFieldValues extends FieldValues = FieldValues, > { data?: TData[] columns: ColumnDef[] @@ -96,7 +97,7 @@ const getCommonPinningStyles = ( export const DataGridRoot = < TData, - TFieldValues extends FieldValues = FieldValues + TFieldValues extends FieldValues = FieldValues, >({ data = [], columns, @@ -700,6 +701,7 @@ const DataGridHeader = ({ const [shortcutsOpen, setShortcutsOpen] = useState(false) const [columnsOpen, setColumnsOpen] = useState(false) const { t } = useTranslation() + const direction = useDocumentDirection() // Since all columns are checked by default, we can check if any column is unchecked const hasChanged = columnOptions.some((column) => !column.checked) @@ -716,7 +718,11 @@ const DataGridHeader = ({ return (
- +
{ + const direction = useDocumentDirection() return ( - +
- + ( e.preventDefault() handleValueChange(isArrayValue ? ([] as unknown as T) : undefined) }} - className="bg-ui-bg-base hover:bg-ui-bg-base-hover txt-compact-small-plus text-ui-fg-subtle focus-within:border-ui-fg-interactive transition-fg absolute left-0.5 top-0.5 z-[1] flex h-[28px] items-center rounded-[4px] border py-[3px] pl-1.5 pr-1 outline-none" + className="bg-ui-bg-base hover:bg-ui-bg-base-hover txt-compact-small-plus text-ui-fg-subtle focus-within:border-ui-fg-interactive transition-fg absolute start-0.5 top-0.5 z-[1] flex h-[28px] items-center rounded-[4px] border py-[3px] ps-1.5 pe-1 outline-none" > {selectedValues.length} @@ -263,8 +263,8 @@ const ComboboxImpl = ( className={clx( "pointer-events-none absolute inset-y-0 flex size-full items-center", { - "left-[calc(var(--tag-width)+8px)]": showTag, - "left-2": !showTag, + "start-[calc(var(--tag-width)+8px)]": showTag, + "start-2": !showTag, } )} > @@ -278,8 +278,8 @@ const ComboboxImpl = ( className={clx( "pointer-events-none absolute inset-y-0 flex size-full items-center overflow-hidden", { - "left-[calc(var(--tag-width)+8px)]": showTag, - "left-2": !showTag, + "start-[calc(var(--tag-width)+8px)]": showTag, + "start-2": !showTag, } )} > @@ -293,12 +293,12 @@ const ComboboxImpl = ( ref={comboboxRef} onFocus={() => setOpen(true)} className={clx( - "txt-compact-small text-ui-fg-base !placeholder:text-ui-fg-muted transition-fg size-full cursor-pointer bg-transparent pl-2 pr-8 outline-none focus:cursor-text", + "txt-compact-small text-ui-fg-base !placeholder:text-ui-fg-muted transition-fg size-full cursor-pointer bg-transparent ps-2 pe-8 outline-none focus:cursor-text", "hover:bg-ui-bg-field-hover", { "opacity-0": hideInput, - "pl-2": !showTag, - "pl-[calc(var(--tag-width)+8px)]": showTag, + "ps-2": !showTag, + "ps-[calc(var(--tag-width)+8px)]": showTag, } )} placeholder={hidePlaceholder ? undefined : placeholder} @@ -312,7 +312,7 @@ const ComboboxImpl = ( e.preventDefault() handleValueChange(undefined) }} - className="bg-ui-bg-base hover:bg-ui-bg-base-hover txt-compact-small-plus text-ui-fg-subtle focus-within:border-ui-fg-interactive transition-fg absolute right-[28px] top-0.5 z-[1] flex h-[28px] items-center rounded-[4px] border px-1.5 py-[2px] outline-none" + className="bg-ui-bg-base hover:bg-ui-bg-base-hover txt-compact-small-plus text-ui-fg-subtle focus-within:border-ui-fg-interactive transition-fg absolute end-[28px] top-0.5 z-[1] flex h-[28px] items-center rounded-[4px] border px-1.5 py-[2px] outline-none" > @@ -323,7 +323,7 @@ const ComboboxImpl = ( @@ -341,7 +341,7 @@ const ComboboxImpl = ( "max-h-[200px] overflow-y-auto", "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95", - "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2" + "data-[side=bottom]:slide-in-from-top-2 data-[side=start]:slide-in-from-end-2 data-[side=end]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2" )} style={{ pointerEvents: open ? "auto" : "none", diff --git a/packages/admin/dashboard/src/components/inputs/country-select/country-select.tsx b/packages/admin/dashboard/src/components/inputs/country-select/country-select.tsx index 344f74d8d4..7ccec4e0ce 100644 --- a/packages/admin/dashboard/src/components/inputs/country-select/country-select.tsx +++ b/packages/admin/dashboard/src/components/inputs/country-select/country-select.tsx @@ -33,7 +33,7 @@ export const CountrySelect = forwardRef<
{ 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 (
- + { ) : ( )} -
+
{name ? ( { )} > -
+
{t("app.search.label")} diff --git a/packages/admin/dashboard/src/components/layout/shell/shell.tsx b/packages/admin/dashboard/src/components/layout/shell/shell.tsx index 28fe9c9e8f..61c9f7f8c5 100644 --- a/packages/admin/dashboard/src/components/layout/shell/shell.tsx +++ b/packages/admin/dashboard/src/components/layout/shell/shell.tsx @@ -156,7 +156,7 @@ const Breadcrumbs = () => { )} {!isLast && ( - + )} @@ -177,7 +177,7 @@ const ToggleSidebar = () => { onClick={() => toggle("desktop")} size="small" > - + { onClick={() => toggle("mobile")} size="small" > - +
) @@ -210,7 +210,7 @@ const DesktopSidebarContainer = ({ children }: PropsWithChildren) => { return (
@@ -234,8 +234,8 @@ const MobileSidebarContainer = ({ children }: PropsWithChildren) => { />
diff --git a/packages/admin/dashboard/src/components/layout/user-menu/user-menu.tsx b/packages/admin/dashboard/src/components/layout/user-menu/user-menu.tsx index e05dcbd4fb..4b92b114d1 100644 --- a/packages/admin/dashboard/src/components/layout/user-menu/user-menu.tsx +++ b/packages/admin/dashboard/src/components/layout/user-menu/user-menu.tsx @@ -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 (
- + - + {t("app.menus.user.profileSettings")} - + {t("app.menus.user.documentation")} - + {t("app.menus.user.changelog")} - + {t("app.menus.user.shortcuts")} @@ -93,7 +95,7 @@ const UserBadge = () => { if (isPending) { return ( - @@ -109,7 +111,7 @@ const UserBadge = () => { { return ( - - - {t("app.menus.user.theme.label")} + + + {t("app.menus.user.theme.label")} diff --git a/packages/admin/dashboard/src/components/search/search.tsx b/packages/admin/dashboard/src/components/search/search.tsx index f52dc9a797..10da87633c 100644 --- a/packages/admin/dashboard/src/components/search/search.tsx +++ b/packages/admin/dashboard/src/components/search/search.tsx @@ -44,6 +44,7 @@ import { } from "./constants" import { SearchArea } from "./types" import { useSearchResults } from "./use-search-results" +import { useDocumentDirection } from "../../hooks/use-document-direction" export const Search = () => { const [area, setArea] = useState("all") @@ -54,6 +55,7 @@ export const Search = () => { const { t } = useTranslation() const navigate = useNavigate() + const inputRef = useRef(null) const listRef = useRef(null) @@ -367,7 +369,7 @@ const CommandInput = forwardRef< ) => { const { t } = useTranslation() const innerRef = useRef(null) - + const direction = useDocumentDirection() useImperativeHandle( ref, () => innerRef.current @@ -376,7 +378,7 @@ const CommandInput = forwardRef< return (
- + -
+
{isFetching && ( )} diff --git a/packages/admin/dashboard/src/components/table/data-table/data-table-order-by/data-table-order-by.tsx b/packages/admin/dashboard/src/components/table/data-table/data-table-order-by/data-table-order-by.tsx index cdc00e31c5..f446d8287b 100644 --- a/packages/admin/dashboard/src/components/table/data-table/data-table-order-by/data-table-order-by.tsx +++ b/packages/admin/dashboard/src/components/table/data-table/data-table-order-by/data-table-order-by.tsx @@ -4,6 +4,8 @@ import { useState } from "react" import { useTranslation } from "react-i18next" import { useSearchParams } from "react-router-dom" +import { useDocumentDirection } from "../../../../hooks/use-document-direction" + export type DataTableOrderByKey = { key: keyof TData label: string @@ -54,6 +56,7 @@ export const DataTableOrderBy = ({ }>(initState(searchParams, prefix)) const param = prefix ? `${prefix}_order` : "order" const { t } = useTranslation() + const direction = useDocumentDirection() const handleDirChange = (dir: string) => { setState((prev) => ({ @@ -97,7 +100,7 @@ export const DataTableOrderBy = ({ } return ( - + diff --git a/packages/admin/dashboard/src/components/table/data-table/data-table-root/data-table-root.tsx b/packages/admin/dashboard/src/components/table/data-table/data-table-root/data-table-root.tsx index 3a6ef2a59d..8dc6048635 100644 --- a/packages/admin/dashboard/src/components/table/data-table/data-table-root/data-table-root.tsx +++ b/packages/admin/dashboard/src/components/table/data-table/data-table-root/data-table-root.tsx @@ -262,7 +262,7 @@ export const DataTableRoot = ({ ({ >
diff --git a/packages/admin/dashboard/src/dashboard-app/forms/form-extension-zone/form-extension-zone.tsx b/packages/admin/dashboard/src/dashboard-app/forms/form-extension-zone/form-extension-zone.tsx index ea742de30e..3144609973 100644 --- a/packages/admin/dashboard/src/dashboard-app/forms/form-extension-zone/form-extension-zone.tsx +++ b/packages/admin/dashboard/src/dashboard-app/forms/form-extension-zone/form-extension-zone.tsx @@ -102,7 +102,7 @@ const FormExtensionFieldComponent = ({ return } case "boolean": { - return + return } default: { return ( diff --git a/packages/admin/dashboard/src/hooks/use-document-direction.tsx b/packages/admin/dashboard/src/hooks/use-document-direction.tsx new file mode 100644 index 0000000000..48643ad316 --- /dev/null +++ b/packages/admin/dashboard/src/hooks/use-document-direction.tsx @@ -0,0 +1,54 @@ +import { useEffect, useState } from "react" + +/** + * Hook to get the current document direction (ltr/rtl) and listen for changes + * @returns The current document direction as "ltr" | "rtl" | undefined + */ +export const useDocumentDirection = (): "ltr" | "rtl" | undefined => { + const [direction, setDirection] = useState<"ltr" | "rtl" | undefined>(() => { + // Initialize with current value + if (typeof document !== "undefined") { + return ( + (document.documentElement.getAttribute("dir") as "ltr" | "rtl") || + undefined + ) + } + return undefined + }) + + useEffect(() => { + // Only run on client side + if (typeof document === "undefined") { + return + } + + // Create a MutationObserver to watch for changes to the dir attribute + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if ( + mutation.type === "attributes" && + mutation.attributeName === "dir" && + mutation.target === document.documentElement + ) { + const newDirection = document.documentElement.getAttribute("dir") as + | "ltr" + | "rtl" + setDirection(newDirection || undefined) + } + }) + }) + + // Start observing the document element for attribute changes + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ["dir"], + }) + + // Cleanup observer on unmount + return () => { + observer.disconnect() + } + }, []) + + return direction +} diff --git a/packages/admin/dashboard/src/providers/i18n-provider/i18n-provider.tsx b/packages/admin/dashboard/src/providers/i18n-provider/i18n-provider.tsx index 29944ef2b9..0ee674be42 100644 --- a/packages/admin/dashboard/src/providers/i18n-provider/i18n-provider.tsx +++ b/packages/admin/dashboard/src/providers/i18n-provider/i18n-provider.tsx @@ -1,5 +1,5 @@ import { I18nProvider as Provider } from "@medusajs/ui" -import { PropsWithChildren } from "react" +import { PropsWithChildren, useEffect } from "react" import { useTranslation } from "react-i18next" import { languages } from "../../i18n/languages" @@ -12,9 +12,14 @@ const formatLocaleCode = (code: string) => { export const I18nProvider = ({ children }: I18nProviderProps) => { const { i18n } = useTranslation() - const locale = - languages.find((lan) => lan.code === i18n.language)?.code || - languages[0].code + const currentLanguage = + languages.find((lan) => lan.code === i18n.language) || languages[0] + const locale = currentLanguage.code + const direction = currentLanguage.ltr ? "ltr" : "rtl" + + useEffect(() => { + document.documentElement.setAttribute("dir", direction) + }, [direction]) return {children} } diff --git a/packages/admin/dashboard/src/routes/campaigns/campaign-detail/components/campaign-budget/campaign-budget.tsx b/packages/admin/dashboard/src/routes/campaigns/campaign-detail/components/campaign-budget/campaign-budget.tsx index 1d6e1746e3..66bfa2c308 100644 --- a/packages/admin/dashboard/src/routes/campaigns/campaign-detail/components/campaign-budget/campaign-budget.tsx +++ b/packages/admin/dashboard/src/routes/campaigns/campaign-detail/components/campaign-budget/campaign-budget.tsx @@ -15,14 +15,14 @@ export const CampaignBudget = ({ campaign }: CampaignBudgetProps) => {
-
+
{t("campaigns.fields.budget_limit")} @@ -46,7 +46,7 @@ export const CampaignBudget = ({ campaign }: CampaignBudgetProps) => {
diff --git a/packages/admin/dashboard/src/routes/campaigns/common/components/create-campaign-form-fields/create-campaign-form-fields.tsx b/packages/admin/dashboard/src/routes/campaigns/common/components/create-campaign-form-fields/create-campaign-form-fields.tsx index 1e4b29cd31..169b623f94 100644 --- a/packages/admin/dashboard/src/routes/campaigns/common/components/create-campaign-form-fields/create-campaign-form-fields.tsx +++ b/packages/admin/dashboard/src/routes/campaigns/common/components/create-campaign-form-fields/create-campaign-form-fields.tsx @@ -14,6 +14,7 @@ import { useTranslation } from "react-i18next" import { Form } from "../../../../../components/common/form" import { useStore } from "../../../../../hooks/api/store" +import { useDocumentDirection } from "../../../../../hooks/use-document-direction" import { currencies, getCurrencySymbol, @@ -22,7 +23,7 @@ import { export const CreateCampaignFormFields = ({ form, fieldScope = "" }) => { const { t } = useTranslation() const { store } = useStore() - + const direction = useDocumentDirection() const watchValueType = useWatch({ control: form.control, name: `${fieldScope}budget.type`, @@ -207,6 +208,7 @@ export const CreateCampaignFormFields = ({ form, fieldScope = "" }) => { { + + + + ({ defaultValues: { name: "", @@ -271,6 +272,7 @@ export function CreateShippingOptionsForm({ }} > onTabChange(tab as Tab)} diff --git a/packages/admin/dashboard/src/routes/locations/location-service-zone-shipping-option-edit/components/edit-region-form/edit-shipping-option-form.tsx b/packages/admin/dashboard/src/routes/locations/location-service-zone-shipping-option-edit/components/edit-region-form/edit-shipping-option-form.tsx index b8bb52f06f..c6f521f059 100644 --- a/packages/admin/dashboard/src/routes/locations/location-service-zone-shipping-option-edit/components/edit-region-form/edit-shipping-option-form.tsx +++ b/packages/admin/dashboard/src/routes/locations/location-service-zone-shipping-option-edit/components/edit-region-form/edit-shipping-option-form.tsx @@ -20,6 +20,7 @@ import { ShippingOptionPriceType, } from "../../../common/constants" import { formatProvider } from "../../../../../lib/format-provider" +import { useDocumentDirection } from "../../../../../hooks/use-document-direction" type EditShippingOptionFormProps = { locationId: string @@ -43,7 +44,7 @@ export const EditShippingOptionForm = ({ }: EditShippingOptionFormProps) => { const { t } = useTranslation() const { handleSuccess } = useRouteModal() - + const direction = useDocumentDirection() const isPickup = type === FulfillmentSetType.Pickup const shippingProfiles = useComboboxData({ @@ -147,7 +148,11 @@ export const EditShippingOptionForm = ({ )} - +
- { setPaymentId(value) diff --git a/packages/admin/dashboard/src/routes/orders/order-create-return/components/return-create-form/return-create-form.tsx b/packages/admin/dashboard/src/routes/orders/order-create-return/components/return-create-form/return-create-form.tsx index e6effeccd6..e4a53f9b77 100644 --- a/packages/admin/dashboard/src/routes/orders/order-create-return/components/return-create-form/return-create-form.tsx +++ b/packages/admin/dashboard/src/routes/orders/order-create-return/components/return-create-form/return-create-form.tsx @@ -726,7 +726,8 @@ export const ReturnCreateForm = ({
({ defaultValues: { type: "sale", @@ -249,6 +250,7 @@ export const PriceListCreateForm = ({ return ( handleChangeTab(tab as Tab)} className="flex h-full flex-col overflow-hidden" diff --git a/packages/admin/dashboard/src/routes/price-lists/price-list-create/components/price-list-create-form/price-list-details-form.tsx b/packages/admin/dashboard/src/routes/price-lists/price-list-create/components/price-list-create-form/price-list-details-form.tsx index 22302c19a3..dc5812f776 100644 --- a/packages/admin/dashboard/src/routes/price-lists/price-list-create/components/price-list-create-form/price-list-details-form.tsx +++ b/packages/admin/dashboard/src/routes/price-lists/price-list-create/components/price-list-create-form/price-list-details-form.tsx @@ -23,6 +23,7 @@ import type { PricingCreateSchemaType, PricingCustomerGroupsArrayType, } from "./schema" +import { useDocumentDirection } from "../../../../../hooks/use-document-direction" type PriceListDetailsFormProps = { form: UseFormReturn @@ -30,7 +31,7 @@ type PriceListDetailsFormProps = { export const PriceListDetailsForm = ({ form }: PriceListDetailsFormProps) => { const { t } = useTranslation() - + const direction = useDocumentDirection() const { fields, remove, append } = useFieldArray({ control: form.control, name: "rules.customer_group_id", @@ -78,6 +79,7 @@ export const PriceListDetailsForm = ({ form }: PriceListDetailsFormProps) => {
{ {t("priceLists.fields.status.label")} - diff --git a/packages/admin/dashboard/src/routes/price-lists/price-list-edit/components/price-list-edit-form/edit-price-list-form.tsx b/packages/admin/dashboard/src/routes/price-lists/price-list-edit/components/price-list-edit-form/edit-price-list-form.tsx index 0cf1cd59b2..ee533e6847 100644 --- a/packages/admin/dashboard/src/routes/price-lists/price-list-edit/components/price-list-edit-form/edit-price-list-form.tsx +++ b/packages/admin/dashboard/src/routes/price-lists/price-list-edit/components/price-list-edit-form/edit-price-list-form.tsx @@ -16,6 +16,7 @@ import { Form } from "../../../../../components/common/form" import { RouteDrawer, useRouteModal } from "../../../../../components/modals" import { KeyboundForm } from "../../../../../components/utilities/keybound-form" import { useUpdatePriceList } from "../../../../../hooks/api/price-lists" +import { useDocumentDirection } from "../../../../../hooks/use-document-direction" import { PriceListStatus, PriceListType } from "../../../common/constants" type PriceListEditFormProps = { @@ -32,7 +33,7 @@ const PriceListEditSchema = z.object({ export const PriceListEditForm = ({ priceList }: PriceListEditFormProps) => { const { t } = useTranslation() const { handleSuccess } = useRouteModal() - + const direction = useDocumentDirection() const form = useForm>({ defaultValues: { type: priceList.type as PriceListType, @@ -80,7 +81,11 @@ export const PriceListEditForm = ({ priceList }: PriceListEditFormProps) => { {t("priceLists.fields.type.hint")}
- + { {t("priceLists.fields.status.label")} - diff --git a/packages/admin/dashboard/src/routes/price-lists/price-list-prices-add/components/price-list-prices-add-form/price-list-prices-add-form.tsx b/packages/admin/dashboard/src/routes/price-lists/price-list-prices-add/components/price-list-prices-add-form/price-list-prices-add-form.tsx index 0d374e5aa3..c32fc78775 100644 --- a/packages/admin/dashboard/src/routes/price-lists/price-list-prices-add/components/price-list-prices-add-form/price-list-prices-add-form.tsx +++ b/packages/admin/dashboard/src/routes/price-lists/price-list-prices-add/components/price-list-prices-add-form/price-list-prices-add-form.tsx @@ -21,6 +21,7 @@ import { PriceListPricesAddProductsIdsFields, PriceListPricesAddSchema, } from "./schema" +import { useDocumentDirection } from "../../../../../hooks/use-document-direction" type PriceListPricesAddFormProps = { priceList: HttpTypes.AdminPriceList @@ -54,7 +55,7 @@ export const PriceListPricesAddForm = ({ const { t } = useTranslation() const { handleSuccess } = useRouteModal() - + const direction = useDocumentDirection() const form = useForm({ defaultValues: { products: {}, @@ -90,10 +91,13 @@ export const PriceListPricesAddForm = ({ ) => { form.clearErrors(fields) - const values = fields.reduce((acc, key) => { - acc[key] = form.getValues(key) - return acc - }, {} as Record) + const values = fields.reduce( + (acc, key) => { + acc[key] = form.getValues(key) + return acc + }, + {} as Record + ) const validationResult = schema.safeParse(values) @@ -196,6 +200,7 @@ export const PriceListPricesAddForm = ({ return ( handleChangeTab(tab as Tab)} className="flex h-full flex-col overflow-hidden" diff --git a/packages/admin/dashboard/src/routes/product-variants/product-variant-edit/components/product-edit-variant-form/product-edit-variant-form.tsx b/packages/admin/dashboard/src/routes/product-variants/product-variant-edit/components/product-edit-variant-form/product-edit-variant-form.tsx index 87ca9a7c62..589b5e1b71 100644 --- a/packages/admin/dashboard/src/routes/product-variants/product-variant-edit/components/product-edit-variant-form/product-edit-variant-form.tsx +++ b/packages/admin/dashboard/src/routes/product-variants/product-variant-edit/components/product-edit-variant-form/product-edit-variant-form.tsx @@ -269,7 +269,9 @@ export const ProductEditVariantForm = ({ onChange(!!checked)} {...field} /> @@ -297,6 +299,8 @@ export const ProductEditVariantForm = ({ onChange(!!checked)} {...field} diff --git a/packages/admin/dashboard/src/routes/products/common/components/category-combobox/category-combobox.tsx b/packages/admin/dashboard/src/routes/products/common/components/category-combobox/category-combobox.tsx index 088dccec57..b6b92bb6a4 100644 --- a/packages/admin/dashboard/src/routes/products/common/components/category-combobox/category-combobox.tsx +++ b/packages/admin/dashboard/src/routes/products/common/components/category-combobox/category-combobox.tsx @@ -277,14 +277,14 @@ export const CategoryCombobox = forwardRef< e.preventDefault() onChange([]) }} - className="bg-ui-bg-base hover:bg-ui-bg-base-hover txt-compact-small-plus text-ui-fg-subtle focus-within:border-ui-fg-interactive transition-fg absolute left-0.5 top-0.5 flex h-[28px] items-center rounded-[4px] border py-[3px] pl-1.5 pr-1 outline-none" + className="bg-ui-bg-base hover:bg-ui-bg-base-hover txt-compact-small-plus text-ui-fg-subtle focus-within:border-ui-fg-interactive transition-fg absolute start-0.5 top-0.5 flex h-[28px] items-center rounded-[4px] border py-[3px] ps-1.5 pe-1 outline-none" > {value.length} )} {showSelected && ( -
+
{t("general.selected")} @@ -297,13 +297,13 @@ export const CategoryCombobox = forwardRef< onSearchValueChange(e.target.value) }} className={clx( - "txt-compact-small size-full cursor-pointer appearance-none bg-transparent pr-8 outline-none", + "txt-compact-small size-full cursor-pointer appearance-none bg-transparent pe-8 outline-none", "hover:bg-ui-bg-field-hover", "focus:cursor-text", "placeholder:text-ui-fg-muted", { - "pl-2": !showTag, - "pl-[calc(var(--tag-width)+8px)]": showTag, + "ps-2": !showTag, + "ps-[calc(var(--tag-width)+8px)]": showTag, } )} {...props} @@ -311,7 +311,7 @@ export const CategoryCombobox = forwardRef< @@ -321,11 +321,11 @@ export const CategoryCombobox = forwardRef< sideOffset={4} role="listbox" className={clx( - "shadow-elevation-flyout bg-ui-bg-base -left-2 z-50 w-[var(--radix-popper-anchor-width)] rounded-[8px]", + "shadow-elevation-flyout bg-ui-bg-base -start-2 z-50 w-[var(--radix-popper-anchor-width)] rounded-[8px]", "max-h-[200px] overflow-y-auto", "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95", - "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2" + "data-[side=bottom]:slide-in-from-top-2 data-[side=start]:slide-in-from-end-2 data-[side=end]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2" )} onInteractOutside={(e) => { e.preventDefault() @@ -346,7 +346,7 @@ export const CategoryCombobox = forwardRef< data-active={focusedIndex === 0} role="button" className={clx( - "transition-fg grid w-full appearance-none grid-cols-[20px_1fr] items-center justify-center gap-2 rounded-md px-2 py-1.5 text-left outline-none", + "transition-fg grid w-full appearance-none grid-cols-[20px_1fr] items-center justify-center gap-2 rounded-md px-2 py-1.5 text-start outline-none", "data-[active=true]:bg-ui-bg-field-hover" )} type="button" @@ -386,7 +386,7 @@ export const CategoryCombobox = forwardRef< type="button" role="option" className={clx( - "grid h-full w-full appearance-none grid-cols-[20px_1fr] items-center gap-2 overflow-hidden rounded-md px-2 py-1.5 text-left outline-none", + "grid h-full w-full appearance-none grid-cols-[20px_1fr] items-center gap-2 overflow-hidden rounded-md px-2 py-1.5 text-start outline-none", "data-[active=true]:bg-ui-bg-field-hover" )} onClick={handleSelect(option)} @@ -418,7 +418,7 @@ export const CategoryCombobox = forwardRef< onClick={handleLevelDown(option)} tabIndex={-1} > - + )}
diff --git a/packages/admin/dashboard/src/routes/products/product-create-variant/components/create-product-variant-form/create-product-variant-form.tsx b/packages/admin/dashboard/src/routes/products/product-create-variant/components/create-product-variant-form/create-product-variant-form.tsx index 011c90e538..e5aaa4049e 100644 --- a/packages/admin/dashboard/src/routes/products/product-create-variant/components/create-product-variant-form/create-product-variant-form.tsx +++ b/packages/admin/dashboard/src/routes/products/product-create-variant/components/create-product-variant-form/create-product-variant-form.tsx @@ -26,6 +26,7 @@ import { import DetailsTab from "./details-tab" import InventoryKitTab from "./inventory-kit-tab" import PricingTab from "./pricing-tab" +import { useDocumentDirection } from "../../../../../hooks/use-document-direction" enum Tab { DETAIL = "detail", @@ -50,7 +51,7 @@ export const CreateProductVariantForm = ({ }: CreateProductVariantFormProps) => { const { t } = useTranslation() const { handleSuccess } = useRouteModal() - + const direction = useDocumentDirection() const [tab, setTab] = useState(Tab.DETAIL) const [tabState, setTabState] = useState(initialTabState) @@ -75,10 +76,13 @@ export const CreateProductVariantForm = ({ return {} } - return regions.reduce((acc, reg) => { - acc[reg.id] = reg.currency_code - return acc - }, {} as Record) + return regions.reduce( + (acc, reg) => { + acc[reg.id] = reg.currency_code + return acc + }, + {} as Record + ) }, [regions]) const isManageInventoryEnabled = useWatch({ @@ -257,6 +261,7 @@ export const CreateProductVariantForm = ({ return ( handleChangeTab(tab as Tab)} className="flex h-full flex-col overflow-hidden" diff --git a/packages/admin/dashboard/src/routes/products/product-create-variant/components/create-product-variant-form/details-tab.tsx b/packages/admin/dashboard/src/routes/products/product-create-variant/components/create-product-variant-form/details-tab.tsx index 6062b2008e..9914b58524 100644 --- a/packages/admin/dashboard/src/routes/products/product-create-variant/components/create-product-variant-form/details-tab.tsx +++ b/packages/admin/dashboard/src/routes/products/product-create-variant/components/create-product-variant-form/details-tab.tsx @@ -99,7 +99,8 @@ function DetailsTab({ form, product }: DetailsTabProps) {
onChange(!!checked)} {...field} @@ -130,6 +131,8 @@ function DetailsTab({ form, product }: DetailsTabProps) {
onChange(!!checked)} {...field} @@ -159,6 +162,8 @@ function DetailsTab({ form, product }: DetailsTabProps) {
onChange(!!checked)} {...field} diff --git a/packages/admin/dashboard/src/routes/products/product-create/components/product-create-form/product-create-form.tsx b/packages/admin/dashboard/src/routes/products/product-create/components/product-create-form/product-create-form.tsx index 7ec650dffb..604978387f 100644 --- a/packages/admin/dashboard/src/routes/products/product-create/components/product-create-form/product-create-form.tsx +++ b/packages/admin/dashboard/src/routes/products/product-create/components/product-create-form/product-create-form.tsx @@ -21,6 +21,7 @@ import { ProductCreateDetailsForm } from "../product-create-details-form" import { ProductCreateInventoryKitForm } from "../product-create-inventory-kit-form" import { ProductCreateOrganizeForm } from "../product-create-organize-form" import { ProductCreateVariantsForm } from "../product-create-variants-form" +import { useDocumentDirection } from "../../../../../hooks/use-document-direction" enum Tab { DETAILS = "details", @@ -58,7 +59,7 @@ export const ProductCreateForm = ({ const { handleSuccess } = useRouteModal() const { getFormConfigs } = useExtension() const configs = getFormConfigs("product", "create") - + const direction = useDocumentDirection() const form = useExtendableForm({ defaultValues: { ...PRODUCT_CREATE_FORM_DEFAULTS, @@ -244,6 +245,7 @@ export const ProductCreateForm = ({ className="flex h-full flex-col" > { const valid = await form.trigger() diff --git a/packages/admin/dashboard/src/routes/products/product-edit/components/edit-product-form/edit-product-form.tsx b/packages/admin/dashboard/src/routes/products/product-edit/components/edit-product-form/edit-product-form.tsx index 5020dd5c79..4d2f93b61a 100644 --- a/packages/admin/dashboard/src/routes/products/product-edit/components/edit-product-form/edit-product-form.tsx +++ b/packages/admin/dashboard/src/routes/products/product-edit/components/edit-product-form/edit-product-form.tsx @@ -13,6 +13,7 @@ import { transformNullableFormData } from "../../../../../lib/form-helpers" import { KeyboundForm } from "../../../../../components/utilities/keybound-form" import { FormExtensionZone } from "../../../../../dashboard-app" import { useExtension } from "../../../../../providers/extension-provider" +import { useDocumentDirection } from "../../../../../hooks/use-document-direction" type EditProductFormProps = { product: HttpTypes.AdminProduct @@ -31,7 +32,7 @@ const EditProductSchema = zod.object({ export const EditProductForm = ({ product }: EditProductFormProps) => { const { t } = useTranslation() const { handleSuccess } = useRouteModal() - + const direction = useDocumentDirection() const { getFormFields, getFormConfigs } = useExtension() const fields = getFormFields("product", "edit") const configs = getFormConfigs("product", "edit") @@ -97,7 +98,11 @@ export const EditProductForm = ({ product }: EditProductFormProps) => { {t("fields.status")} - diff --git a/packages/admin/dashboard/src/routes/products/product-media/components/product-media-gallery/product-media-gallery.tsx b/packages/admin/dashboard/src/routes/products/product-media/components/product-media-gallery/product-media-gallery.tsx index 1f410642e0..5147dc0437 100644 --- a/packages/admin/dashboard/src/routes/products/product-media/components/product-media-gallery/product-media-gallery.tsx +++ b/packages/admin/dashboard/src/routes/products/product-media/components/product-media-gallery/product-media-gallery.tsx @@ -261,7 +261,7 @@ const Preview = ({ type="button" onClick={prev} > - +
{visibleItems.map((item) => { @@ -292,7 +292,7 @@ const Preview = ({ type="button" onClick={next} > - +
) diff --git a/packages/admin/dashboard/src/routes/products/product-stock/hooks/use-product-stock-columns.tsx b/packages/admin/dashboard/src/routes/products/product-stock/hooks/use-product-stock-columns.tsx index 31515dbe2d..0824a366d7 100644 --- a/packages/admin/dashboard/src/routes/products/product-stock/hooks/use-product-stock-columns.tsx +++ b/packages/admin/dashboard/src/routes/products/product-stock/hooks/use-product-stock-columns.tsx @@ -192,7 +192,8 @@ export const useProductStockColumns = ( return (
{ const { t, i18n } = useTranslation() const { handleSuccess } = useRouteModal() - + const direction = useDocumentDirection() const form = useForm>({ defaultValues: { first_name: user.first_name ?? "", @@ -111,7 +112,11 @@ export const EditProfileForm = ({ user }: EditProfileProps) => {
- { {t("profile.fields.usageInsightsLabel")} - {!disabled ? ( c.id === watchCampaignId) - + const direction = useDocumentDirection() return (
- diff --git a/packages/admin/dashboard/src/routes/promotions/promotion-create/components/create-promotion-form/create-promotion-form.tsx b/packages/admin/dashboard/src/routes/promotions/promotion-create/components/create-promotion-form/create-promotion-form.tsx index b76b773240..fac61500e7 100644 --- a/packages/admin/dashboard/src/routes/promotions/promotion-create/components/create-promotion-form/create-promotion-form.tsx +++ b/packages/admin/dashboard/src/routes/promotions/promotion-create/components/create-promotion-form/create-promotion-form.tsx @@ -46,6 +46,7 @@ import { AddCampaignPromotionFields } from "../../../promotion-add-campaign/comp import { Tab } from "./constants" import { CreatePromotionSchema } from "./form-schema" import { templates } from "./templates" +import { useDocumentDirection } from "../../../../../hooks/use-document-direction" const defaultValues = { campaign_id: undefined, @@ -80,7 +81,7 @@ export const CreatePromotionForm = () => { const { t } = useTranslation() const { handleSuccess } = useRouteModal() - + const direction = useDocumentDirection() const form = useForm>({ defaultValues, resolver: zodResolver(CreatePromotionSchema), @@ -364,6 +365,7 @@ export const CreatePromotionForm = () => { handleTabChange(tab as Tab)} className="flex h-full flex-col overflow-hidden" @@ -417,6 +419,7 @@ export const CreatePromotionForm = () => { { { {
{ { @@ -889,6 +897,7 @@ export const CreatePromotionForm = () => { {t("promotions.form.status.label")} {t("promotions.form.method.label")} ({}) const { handleSuccess } = useRouteModal() - + const direction = useDocumentDirection() const form = useForm>({ defaultValues: { name: "", @@ -226,7 +227,11 @@ export const CreateRegionForm = ({ {t("fields.currency")} - @@ -260,6 +265,8 @@ export const CreateRegionForm = ({ {t("fields.automaticTaxes")} preference.attribute === "region_id" && preference.value === region.id ) - + const direction = useDocumentDirection() const form = useForm>({ defaultValues: { name: region.name, @@ -106,7 +107,11 @@ export const EditRegionForm = ({ {t("fields.currency")} - @@ -137,6 +142,8 @@ export const EditRegionForm = ({ {t("fields.automaticTaxes")} { const { t } = useTranslation() const { handleSuccess } = useRouteModal() - + const direction = useDocumentDirection() const form = useForm>({ defaultValues: getDefaultValues(reservation), resolver: zodResolver(EditReservationSchema), @@ -102,6 +103,7 @@ export const EditReservationForm = ({ {t("inventory.reservation.location")} + diff --git a/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/components/tax-region-tax-override-edit-form/tax-region-tax-override-edit-form.tsx b/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/components/tax-region-tax-override-edit-form/tax-region-tax-override-edit-form.tsx index 94e28fc126..c1e336deb5 100644 --- a/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/components/tax-region-tax-override-edit-form/tax-region-tax-override-edit-form.tsx +++ b/packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/components/tax-region-tax-override-edit-form/tax-region-tax-override-edit-form.tsx @@ -37,6 +37,7 @@ import { } from "../../../common/schemas" import { createTaxRulePayload } from "../../../common/utils" import { InitialRuleValues } from "../../types" +import { useDocumentDirection } from "../../../../../hooks/use-document-direction" export const DISPLAY_OVERRIDE_ITEMS_LIMIT = 10 @@ -81,7 +82,7 @@ export const TaxRegionTaxOverrideEditForm = ({ const { t } = useTranslation() const { handleSuccess } = useRouteModal() const { setIsOpen } = useStackedModal() - + const direction = useDocumentDirection() const form = useForm>({ defaultValues: { name: taxRate.name, @@ -514,6 +515,7 @@ export const TaxRegionTaxOverrideEditForm = ({
{isLast ? (