chore(ui): move toast to top right (#13092)
* chore(ui): display toast in top right corner * fix: error as well * refactor: feedback * chore: move the rest of the modal controls to footer --------- Co-authored-by: William Bouchard <46496014+willbouch@users.noreply.github.com>
This commit is contained in:
5
.changeset/wise-yaks-wink.md
Normal file
5
.changeset/wise-yaks-wink.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@medusajs/ui": patch
|
||||
---
|
||||
|
||||
chore(ui): display toast in top right corner
|
||||
@@ -148,14 +148,6 @@ export const EditCategoryProductsForm = ({
|
||||
{form.formState.errors.product_ids.message}
|
||||
</Hint>
|
||||
)}
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button size="small" type="submit" isLoading={isMutating}>
|
||||
{t("actions.save")}
|
||||
</Button>
|
||||
</div>
|
||||
</RouteFocusModal.Header>
|
||||
<RouteFocusModal.Body className="size-full overflow-hidden">
|
||||
@@ -178,6 +170,16 @@ export const EditCategoryProductsForm = ({
|
||||
search="autofocus"
|
||||
/>
|
||||
</RouteFocusModal.Body>
|
||||
<RouteFocusModal.Footer>
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button size="small" type="submit" isLoading={isMutating}>
|
||||
{t("actions.save")}
|
||||
</Button>
|
||||
</RouteFocusModal.Footer>
|
||||
</KeyboundForm>
|
||||
</RouteFocusModal.Form>
|
||||
)
|
||||
|
||||
@@ -157,14 +157,6 @@ export const AddProductsToCollectionForm = ({
|
||||
{form.formState.errors.add && (
|
||||
<Hint variant="error">{form.formState.errors.add.message}</Hint>
|
||||
)}
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button size="small" type="submit" isLoading={isMutating}>
|
||||
{t("actions.save")}
|
||||
</Button>
|
||||
</div>
|
||||
</RouteFocusModal.Header>
|
||||
<RouteFocusModal.Body className="size-full overflow-hidden">
|
||||
@@ -187,6 +179,16 @@ export const AddProductsToCollectionForm = ({
|
||||
search="autofocus"
|
||||
/>
|
||||
</RouteFocusModal.Body>
|
||||
<RouteFocusModal.Footer>
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button size="small" type="submit" isLoading={isMutating}>
|
||||
{t("actions.save")}
|
||||
</Button>
|
||||
</RouteFocusModal.Footer>
|
||||
</KeyboundForm>
|
||||
</RouteFocusModal.Form>
|
||||
)
|
||||
|
||||
@@ -46,25 +46,13 @@ export const CreateCollectionForm = () => {
|
||||
|
||||
return (
|
||||
<RouteFocusModal.Form form={form}>
|
||||
<KeyboundForm onSubmit={handleSubmit}>
|
||||
<RouteFocusModal.Header>
|
||||
<div className="flex items-center justify-end gap-x-2">
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button
|
||||
size="small"
|
||||
variant="primary"
|
||||
type="submit"
|
||||
isLoading={isPending}
|
||||
>
|
||||
{t("actions.create")}
|
||||
</Button>
|
||||
</div>
|
||||
</RouteFocusModal.Header>
|
||||
<RouteFocusModal.Body className="flex flex-col items-center p-16">
|
||||
<KeyboundForm
|
||||
onSubmit={handleSubmit}
|
||||
className="flex h-full flex-col overflow-hidden"
|
||||
>
|
||||
<RouteFocusModal.Header />
|
||||
|
||||
<RouteFocusModal.Body className="flex size-full flex-col items-center p-16">
|
||||
<div className="flex w-full max-w-[720px] flex-col gap-y-8">
|
||||
<div>
|
||||
<Heading>{t("collections.createCollection")}</Heading>
|
||||
@@ -111,6 +99,21 @@ export const CreateCollectionForm = () => {
|
||||
</div>
|
||||
</div>
|
||||
</RouteFocusModal.Body>
|
||||
<RouteFocusModal.Footer>
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button
|
||||
size="small"
|
||||
variant="primary"
|
||||
type="submit"
|
||||
isLoading={isPending}
|
||||
>
|
||||
{t("actions.create")}
|
||||
</Button>
|
||||
</RouteFocusModal.Footer>
|
||||
</KeyboundForm>
|
||||
</RouteFocusModal.Form>
|
||||
)
|
||||
|
||||
@@ -137,19 +137,6 @@ export const AddCustomersForm = ({
|
||||
{form.formState.errors.customer_ids.message}
|
||||
</Hint>
|
||||
)}
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button variant="secondary" size="small">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="primary"
|
||||
size="small"
|
||||
isLoading={isPending}
|
||||
>
|
||||
{t("actions.save")}
|
||||
</Button>
|
||||
</div>
|
||||
</RouteFocusModal.Header>
|
||||
<RouteFocusModal.Body className="size-full overflow-hidden">
|
||||
@@ -176,6 +163,21 @@ export const AddCustomersForm = ({
|
||||
}}
|
||||
/>
|
||||
</RouteFocusModal.Body>
|
||||
<RouteFocusModal.Footer>
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button variant="secondary" size="small">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="primary"
|
||||
size="small"
|
||||
isLoading={isPending}
|
||||
>
|
||||
{t("actions.save")}
|
||||
</Button>
|
||||
</RouteFocusModal.Footer>
|
||||
</KeyboundForm>
|
||||
</RouteFocusModal.Form>
|
||||
)
|
||||
|
||||
@@ -44,12 +44,12 @@ export function OrderCreateShipmentForm({
|
||||
|
||||
const handleSubmit = form.handleSubmit(async (data) => {
|
||||
const addedLabels = data.labels
|
||||
.filter((l) => !!l.tracking_number)
|
||||
.map((l) => ({
|
||||
tracking_number: l.tracking_number,
|
||||
tracking_url: "#",
|
||||
label_url: "#",
|
||||
}))
|
||||
.filter((l) => !!l.tracking_number)
|
||||
.map((l) => ({
|
||||
tracking_number: l.tracking_number,
|
||||
tracking_url: "#",
|
||||
label_url: "#",
|
||||
}))
|
||||
|
||||
await createShipment(
|
||||
{
|
||||
@@ -78,18 +78,8 @@ export function OrderCreateShipmentForm({
|
||||
onSubmit={handleSubmit}
|
||||
className="flex h-full flex-col overflow-hidden"
|
||||
>
|
||||
<RouteFocusModal.Header>
|
||||
<div className="flex items-center justify-end gap-x-2">
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button size="small" type="submit" isLoading={isMutating}>
|
||||
{t("actions.save")}
|
||||
</Button>
|
||||
</div>
|
||||
</RouteFocusModal.Header>
|
||||
<RouteFocusModal.Header />
|
||||
|
||||
<RouteFocusModal.Body className="flex h-full w-full flex-col items-center divide-y overflow-y-auto">
|
||||
<div className="flex size-full flex-col items-center overflow-auto p-16">
|
||||
<div className="flex w-full max-w-[736px] flex-col justify-center px-2 pb-2">
|
||||
@@ -166,6 +156,16 @@ export function OrderCreateShipmentForm({
|
||||
</div>
|
||||
</div>
|
||||
</RouteFocusModal.Body>
|
||||
<RouteFocusModal.Footer>
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button size="small" type="submit" isLoading={isMutating}>
|
||||
{t("actions.save")}
|
||||
</Button>
|
||||
</RouteFocusModal.Footer>
|
||||
</KeyboundForm>
|
||||
</RouteFocusModal.Form>
|
||||
)
|
||||
|
||||
@@ -310,18 +310,7 @@ export function ManageVariantInventoryItemsForm({
|
||||
return (
|
||||
<RouteFocusModal.Form form={form}>
|
||||
<KeyboundForm className="flex h-full flex-col" onSubmit={handleSubmit}>
|
||||
<RouteFocusModal.Header>
|
||||
<div className="flex items-center justify-end gap-x-2">
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button size="small" type="submit" isLoading={isPending}>
|
||||
{t("actions.save")}
|
||||
</Button>
|
||||
</div>
|
||||
</RouteFocusModal.Header>
|
||||
<RouteFocusModal.Header />
|
||||
<RouteFocusModal.Body className="flex justify-center overflow-auto">
|
||||
<div className="flex w-full flex-col gap-y-8 px-6 pt-12 md:w-[720px] md:pt-24">
|
||||
<Heading>
|
||||
@@ -371,6 +360,16 @@ export function ManageVariantInventoryItemsForm({
|
||||
</div>
|
||||
</div>
|
||||
</RouteFocusModal.Body>
|
||||
<RouteFocusModal.Footer>
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button size="small" type="submit" isLoading={isPending}>
|
||||
{t("actions.save")}
|
||||
</Button>
|
||||
</RouteFocusModal.Footer>
|
||||
</KeyboundForm>
|
||||
</RouteFocusModal.Form>
|
||||
)
|
||||
|
||||
@@ -129,18 +129,8 @@ export const AddCountriesForm = ({ region }: AddCountriesFormProps) => {
|
||||
onSubmit={handleSubmit}
|
||||
className="flex h-full flex-col overflow-hidden"
|
||||
>
|
||||
<RouteFocusModal.Header>
|
||||
<div className="flex items-center justify-end gap-x-2">
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button size="small" isLoading={isLoading} type="submit">
|
||||
{t("actions.add")}
|
||||
</Button>
|
||||
</div>
|
||||
</RouteFocusModal.Header>
|
||||
<RouteFocusModal.Header />
|
||||
|
||||
<RouteFocusModal.Body className="overflow-hidden">
|
||||
<_DataTable
|
||||
table={table}
|
||||
@@ -158,6 +148,16 @@ export const AddCountriesForm = ({ region }: AddCountriesFormProps) => {
|
||||
prefix={PREFIX}
|
||||
/>
|
||||
</RouteFocusModal.Body>
|
||||
<RouteFocusModal.Footer>
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button size="small" isLoading={isLoading} type="submit">
|
||||
{t("actions.add")}
|
||||
</Button>
|
||||
</RouteFocusModal.Footer>
|
||||
</KeyboundForm>
|
||||
</RouteFocusModal.Form>
|
||||
)
|
||||
|
||||
@@ -186,18 +186,7 @@ export const CreateRegionForm = ({
|
||||
className="flex h-full flex-col overflow-hidden"
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
<RouteFocusModal.Header>
|
||||
<div className="flex items-center justify-end gap-x-2">
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button size="small" type="submit" isLoading={isPendingRegion}>
|
||||
{t("actions.save")}
|
||||
</Button>
|
||||
</div>
|
||||
</RouteFocusModal.Header>
|
||||
<RouteFocusModal.Header />
|
||||
<RouteFocusModal.Body className="flex overflow-hidden">
|
||||
<div
|
||||
className={clx(
|
||||
@@ -434,6 +423,16 @@ export const CreateRegionForm = ({
|
||||
</div>
|
||||
</div>
|
||||
</RouteFocusModal.Body>
|
||||
<RouteFocusModal.Footer>
|
||||
<RouteFocusModal.Close asChild>
|
||||
<Button size="small" variant="secondary">
|
||||
{t("actions.cancel")}
|
||||
</Button>
|
||||
</RouteFocusModal.Close>
|
||||
<Button size="small" type="submit" isLoading={isPendingRegion}>
|
||||
{t("actions.save")}
|
||||
</Button>
|
||||
</RouteFocusModal.Footer>
|
||||
</KeyboundForm>
|
||||
</RouteFocusModal.Form>
|
||||
)
|
||||
|
||||
@@ -3,6 +3,8 @@ import { ToastAction, ToastVariant, ToasterPosition } from "@/types"
|
||||
import * as React from "react"
|
||||
import { ExternalToast, toast as toastFn } from "sonner"
|
||||
|
||||
const DEFAULT_TOAST_POSITION = "top-right"
|
||||
|
||||
interface BaseToastProps {
|
||||
id?: string | number
|
||||
position?: ToasterPosition
|
||||
@@ -16,7 +18,11 @@ interface ToastProps extends BaseToastProps {
|
||||
action?: ToastAction
|
||||
}
|
||||
|
||||
function create(variant: ToastVariant, title: React.ReactNode, props: ToastProps = {}) {
|
||||
function create(
|
||||
variant: ToastVariant,
|
||||
title: React.ReactNode,
|
||||
props: ToastProps = {}
|
||||
) {
|
||||
const external: ExternalToast = {
|
||||
position: props.position,
|
||||
duration: props.duration,
|
||||
@@ -50,13 +56,15 @@ function message(
|
||||
/**
|
||||
* The props of the toast.
|
||||
*/
|
||||
props: ToastProps = {}
|
||||
props: ToastProps = {
|
||||
position: DEFAULT_TOAST_POSITION,
|
||||
}
|
||||
) {
|
||||
return create("message", title, props)
|
||||
}
|
||||
|
||||
function custom() {
|
||||
return create("message", "Custom",)
|
||||
return create("message", "Custom")
|
||||
}
|
||||
|
||||
interface VariantToastProps extends Omit<ToastProps, "icon"> {}
|
||||
@@ -68,7 +76,9 @@ function info(
|
||||
/**
|
||||
* The props of the toast.
|
||||
*/
|
||||
props: VariantToastProps = {}
|
||||
props: VariantToastProps = {
|
||||
position: DEFAULT_TOAST_POSITION,
|
||||
}
|
||||
) {
|
||||
return create("info", title, props)
|
||||
}
|
||||
@@ -80,7 +90,9 @@ function error(
|
||||
/**
|
||||
* The props of the toast.
|
||||
*/
|
||||
props: VariantToastProps = {}
|
||||
props: VariantToastProps = {
|
||||
position: DEFAULT_TOAST_POSITION,
|
||||
}
|
||||
) {
|
||||
return create("error", title, props)
|
||||
}
|
||||
@@ -92,7 +104,9 @@ function success(
|
||||
/**
|
||||
* The props of the toast.
|
||||
*/
|
||||
props: VariantToastProps = { }
|
||||
props: VariantToastProps = {
|
||||
position: DEFAULT_TOAST_POSITION,
|
||||
}
|
||||
) {
|
||||
return create("success", title, props)
|
||||
}
|
||||
@@ -104,7 +118,9 @@ function warning(
|
||||
/**
|
||||
* The props of the toast.
|
||||
*/
|
||||
props: VariantToastProps = {}
|
||||
props: VariantToastProps = {
|
||||
position: DEFAULT_TOAST_POSITION,
|
||||
}
|
||||
) {
|
||||
return create("warning", title, props)
|
||||
}
|
||||
@@ -116,7 +132,9 @@ function loading(
|
||||
/**
|
||||
* The props of the toast.
|
||||
*/
|
||||
props: VariantToastProps = {}
|
||||
props: VariantToastProps = {
|
||||
position: DEFAULT_TOAST_POSITION,
|
||||
}
|
||||
) {
|
||||
return create("loading", title, { ...props, dismissable: false })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user