best-email-builder 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +86 -0
- package/README.md +113 -1
- package/dist/builder.js +44 -0
- package/dist/builder.js.map +1 -0
- package/dist/{chunk-2DZ6BRIJ.js → chunk-3M36VVXS.js} +132 -119
- package/dist/chunk-3M36VVXS.js.map +1 -0
- package/dist/chunk-57CTQNTK.js +56 -0
- package/dist/chunk-57CTQNTK.js.map +1 -0
- package/dist/chunk-BVOVAEEJ.js +73 -0
- package/dist/chunk-BVOVAEEJ.js.map +1 -0
- package/dist/chunk-ILRAQTHS.js +3677 -0
- package/dist/chunk-ILRAQTHS.js.map +1 -0
- package/dist/chunk-JOC752I3.js +529 -0
- package/dist/chunk-JOC752I3.js.map +1 -0
- package/dist/chunk-ZSUHOCCE.js +1351 -0
- package/dist/chunk-ZSUHOCCE.js.map +1 -0
- package/dist/index.js +88 -4199
- package/dist/index.js.map +1 -1
- package/dist/library.js +31 -0
- package/dist/library.js.map +1 -0
- package/dist/server.js +27 -23
- package/dist/server.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/adapters/grapesjs/GrapesJsAdapter.d.ts +1 -1
- package/dist/types/adapters/grapesjs/engineConfig.d.ts +0 -14
- package/dist/types/blocks/columns/index.d.ts +3 -0
- package/dist/types/blocks/heading/index.d.ts +3 -0
- package/dist/types/blocks/hero/index.d.ts +3 -0
- package/dist/types/blocks/navbar/index.d.ts +6 -0
- package/dist/types/blocks/social/index.d.ts +13 -0
- package/dist/types/builder.d.ts +8 -0
- package/dist/types/core/EmailEditor.d.ts +12 -4
- package/dist/types/core/constants.d.ts +1 -1
- package/dist/types/core/scrollbars.d.ts +13 -0
- package/dist/types/defaultEditor.d.ts +8 -0
- package/dist/types/features/templates/TemplateGallery.d.ts +3 -0
- package/dist/types/features/templates/gallery.d.ts +48 -0
- package/dist/types/features/templates/index.d.ts +2 -0
- package/dist/types/features/templates/starter.d.ts +22 -0
- package/dist/types/index.d.ts +4 -8
- package/dist/types/library.d.ts +5 -0
- package/dist/types/server/compileMjml.d.ts +3 -3
- package/dist/types/server/render.d.ts +4 -4
- package/dist/types/server/templates.d.ts +2 -2
- package/dist/types/storage/client.d.ts +4 -0
- package/dist/types/ui/BlockSidebar.d.ts +2 -1
- package/dist/types/ui/Drawer.d.ts +19 -0
- package/dist/types/ui/EmailBuilder.d.ts +2 -0
- package/dist/types/ui/EmailStudio.d.ts +42 -0
- package/dist/types/ui/PropertiesPanel.d.ts +2 -1
- package/dist/types/ui/Toolbar.d.ts +9 -2
- package/dist/types/ui/library/TemplateLibrary.d.ts +41 -0
- package/dist/types/ui/primitives/button.d.ts +1 -1
- package/dist/types/ui/useLayoutWidth.d.ts +10 -0
- package/package.json +23 -6
- package/dist/chunk-2DZ6BRIJ.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/context.jsx","../src/ui/primitives/overlays.jsx","../src/ui/primitives/cn.js","../src/ui/primitives/button.jsx","../src/ui/primitives/misc.jsx","../src/blocks/shared.js","../src/features/templates/starter.js","../src/blocks/social/index.js","../src/features/templates/gallery.js","../src/storage/client.js","../src/ui/primitives/fields.jsx","../src/features/preview/PreviewButton.jsx","../src/core/scrollbars.js","../src/ui/useLayoutWidth.js"],"sourcesContent":["import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';\nimport { AlertCircle, CheckCircle2, Info, TriangleAlert, X } from 'lucide-react';\nimport { identity, translatorFor } from '../i18n/index.js';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogTitle,\n} from './primitives/overlays.jsx';\nimport { buttonVariants } from './primitives/button.jsx';\nimport { TooltipProvider } from './primitives/misc.jsx';\nimport { cn } from './primitives/cn.js';\n\n/**\n * Interface services shared by every component of the builder:\n *\n * t translation (see src/i18n) ;\n * locale BCP 47 tag used for dates and times ;\n * notify short messages (`success`, `info`, `warning`, `error`) — shown by\n * the builder itself, or handed to the host's own toaster through\n * the `onNotify` prop ;\n * confirm asynchronous confirmation dialog → Promise<boolean>.\n */\n\n/**\n * @typedef {'success'|'info'|'warning'|'error'} NotifyLevel\n * @typedef {{title?: string, description?: string, confirmLabel?: string,\n * cancelLabel?: string, destructive?: boolean}} ConfirmOptions\n */\n\nconst NoticeContext = createContext({ notices: [], dismiss: () => {} });\n\nconst UiContext = createContext({\n t: identity,\n locale: 'en',\n /** @type {(level: NotifyLevel, message: string) => void} */\n notify: () => {},\n /** @type {(options: ConfirmOptions) => Promise<boolean>} */\n confirm: async () => false,\n});\n\nexport const useUi = () => useContext(UiContext);\nexport const useT = () => useContext(UiContext).t;\n\nconst NOTICE_ICON = { success: CheckCircle2, info: Info, warning: TriangleAlert, error: AlertCircle };\nconst NOTICE_TTL = { success: 3500, info: 4000, warning: 6000, error: 7000 };\n\n/** Where the builder's own notices appear (bottom-right of its root element). */\nexport function NoticeArea() {\n const t = useT();\n const { notices, dismiss: onDismiss } = useContext(NoticeContext);\n return (\n <div className=\"eb:pointer-events-none eb:absolute eb:right-3 eb:bottom-3 eb:z-40 eb:flex eb:w-80 eb:max-w-[calc(100%-1.5rem)] eb:flex-col eb:gap-2\">\n {notices.map((notice) => {\n const Icon = NOTICE_ICON[notice.level] || Info;\n return (\n <div\n key={notice.id}\n role={notice.level === 'error' ? 'alert' : 'status'}\n data-level={notice.level}\n className=\"eb:pointer-events-auto eb:flex eb:items-start eb:gap-2 eb:rounded-lg2 eb:border eb:border-border eb:bg-popover eb:px-3 eb:py-2.5 eb:text-[13px] eb:text-popover-foreground eb:shadow-lg\"\n >\n <Icon\n aria-hidden=\"true\"\n className={cn(\n 'eb:mt-0.5 eb:size-4 eb:shrink-0',\n notice.level === 'error' && 'eb:text-destructive',\n notice.level === 'warning' && 'eb:text-warning',\n notice.level === 'success' && 'eb:text-success',\n notice.level === 'info' && 'eb:text-foreground-muted'\n )}\n />\n <p className=\"eb:min-w-0 eb:flex-1\">{notice.message}</p>\n <button\n type=\"button\"\n aria-label={t('Dismiss')}\n className=\"eb:shrink-0 eb:rounded-sm eb:text-foreground-muted eb:hover:text-foreground\"\n onClick={() => onDismiss(notice.id)}\n >\n <X className=\"eb:size-3.5\" />\n </button>\n </div>\n );\n })}\n </div>\n );\n}\n\n/**\n * @param {{\n * locale?: string,\n * messages?: Record<string, string>,\n * onNotify?: (level: NotifyLevel, message: string) => void,\n * children: import('react').ReactNode,\n * }} props\n */\nexport function UiProvider({ locale = 'en', messages, onNotify, children }) {\n const t = useMemo(() => translatorFor(locale, messages), [locale, messages]);\n\n /* ── Notices ── */\n const [notices, setNotices] = useState([]);\n const timers = useRef(new Map());\n const dismiss = useCallback((id) => {\n clearTimeout(timers.current.get(id));\n timers.current.delete(id);\n setNotices((list) => list.filter((n) => n.id !== id));\n }, []);\n const hostNotify = useRef(onNotify);\n hostNotify.current = onNotify;\n const nextId = useRef(0);\n const notify = useCallback(\n (level, message) => {\n if (hostNotify.current) {\n hostNotify.current(level, message);\n return;\n }\n const id = (nextId.current += 1);\n setNotices((list) => [...list.slice(-3), { id, level, message }]);\n timers.current.set(\n id,\n setTimeout(() => dismiss(id), NOTICE_TTL[level] || 4000)\n );\n },\n [dismiss]\n );\n useEffect(() => {\n const pending = timers.current;\n return () => pending.forEach((timer) => clearTimeout(timer));\n }, []);\n\n /* ── Confirmation ── */\n const [request, setRequest] = useState(null);\n const confirm = useCallback(\n (options = {}) =>\n new Promise((resolve) => {\n setRequest((current) => {\n current?.resolve(false);\n return { options, resolve };\n });\n }),\n []\n );\n const settle = (result) => {\n request?.resolve(result);\n setRequest(null);\n };\n\n const value = useMemo(() => ({ t, locale, notify, confirm }), [t, locale, notify, confirm]);\n const noticeValue = useMemo(() => ({ notices, dismiss }), [notices, dismiss]);\n const options = request?.options || {};\n\n return (\n <UiContext.Provider value={value}>\n <TooltipProvider delayDuration={300}>\n <NoticeContext.Provider value={noticeValue}>{children}</NoticeContext.Provider>\n <AlertDialog open={Boolean(request)} onOpenChange={(open) => !open && settle(false)}>\n <AlertDialogContent>\n <div className=\"eb:flex eb:items-center eb:gap-3\">\n <span\n className={cn(\n 'eb:flex eb:size-10 eb:shrink-0 eb:items-center eb:justify-center eb:rounded-lg2',\n options.destructive ? 'eb:bg-destructive/10 eb:text-destructive' : 'eb:bg-primary/10 eb:text-primary'\n )}\n >\n <AlertCircle className=\"eb:size-5\" />\n </span>\n <AlertDialogTitle className=\"eb:text-base\">{options.title || t('Confirm')}</AlertDialogTitle>\n </div>\n {options.description && (\n <AlertDialogDescription className=\"eb:text-[13px] eb:leading-relaxed\">{options.description}</AlertDialogDescription>\n )}\n <div className=\"eb:flex eb:flex-col-reverse eb:gap-2 eb:sm:flex-row eb:sm:justify-end\">\n <AlertDialogCancel className={buttonVariants({ variant: 'outline' })} onClick={() => settle(false)}>\n {options.cancelLabel || t('Cancel')}\n </AlertDialogCancel>\n <AlertDialogAction\n className={buttonVariants({ variant: options.destructive ? 'destructive' : 'default' })}\n onClick={() => settle(true)}\n >\n {options.confirmLabel || t('Confirm')}\n </AlertDialogAction>\n </div>\n </AlertDialogContent>\n </AlertDialog>\n </TooltipProvider>\n </UiContext.Provider>\n );\n}\n","import {\n AlertDialog as AlertDialogPrimitive,\n Dialog as DialogPrimitive,\n DropdownMenu as DropdownMenuPrimitive,\n Popover as PopoverPrimitive,\n Select as SelectPrimitive,\n} from 'radix-ui';\nimport { CheckIcon, ChevronDownIcon, XIcon } from 'lucide-react';\nimport { useT } from '../context.jsx';\nimport { cn } from './cn.js';\n\n/*\n * Overlays render in a portal, outside the builder's root element: each one\n * carries the `eb-scope` class so the package's base styles reach it.\n */\n\nconst FADE_ZOOM =\n 'eb:data-[state=open]:animate-in eb:data-[state=open]:fade-in-0 eb:data-[state=open]:zoom-in-95 eb:data-[state=closed]:animate-out eb:data-[state=closed]:fade-out-0 eb:data-[state=closed]:zoom-out-95';\n\n/* ── Dialog ───────────────────────────────────────────────────────────── */\n\nexport function Dialog(props) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nexport function DialogContent({ className, children, showCloseButton = true, ...props }) {\n const t = useT();\n return (\n <DialogPrimitive.Portal>\n <DialogPrimitive.Overlay className=\"eb-scope eb:fixed eb:inset-0 eb:z-50 eb:bg-black/50 eb:data-[state=open]:animate-in eb:data-[state=open]:fade-in-0 eb:data-[state=closed]:animate-out eb:data-[state=closed]:fade-out-0\" />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n 'eb-scope eb:fixed eb:top-[50%] eb:left-[50%] eb:z-50 eb:grid eb:w-full eb:max-w-[calc(100%-2rem)] eb:translate-x-[-50%] eb:translate-y-[-50%] eb:gap-4 eb:rounded-lg2 eb:border eb:border-border eb:bg-background eb:p-6 eb:text-foreground eb:shadow-lg eb:duration-200 eb:outline-none eb:sm:max-w-lg',\n FADE_ZOOM,\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close className=\"eb:absolute eb:top-4 eb:right-4 eb:rounded-xs eb:opacity-70 eb:transition-opacity eb:hover:opacity-100 eb:focus:ring-2 eb:focus:ring-ring eb:focus:ring-offset-2 eb:focus:outline-hidden eb:disabled:pointer-events-none eb:[&_svg]:pointer-events-none eb:[&_svg]:shrink-0 eb:[&_svg:not([class*='size-'])]:size-4\">\n <XIcon />\n <span className=\"eb:sr-only\">{t('Close')}</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n );\n}\n\nexport function DialogHeader({ className, ...props }) {\n return <div className={cn('eb:flex eb:flex-col eb:gap-2 eb:text-left', className)} {...props} />;\n}\n\nexport function DialogFooter({ className, ...props }) {\n return <div className={cn('eb:flex eb:flex-col-reverse eb:gap-2 eb:sm:flex-row eb:sm:justify-end', className)} {...props} />;\n}\n\nexport function DialogTitle({ className, ...props }) {\n return <DialogPrimitive.Title className={cn('eb:text-lg eb:leading-none eb:font-semibold', className)} {...props} />;\n}\n\nexport function DialogDescription({ className, ...props }) {\n return <DialogPrimitive.Description className={cn('eb:text-sm eb:text-muted-foreground', className)} {...props} />;\n}\n\n/* ── Alert dialog (confirmations) ─────────────────────────────────────── */\n\nexport function AlertDialog(props) {\n return <AlertDialogPrimitive.Root {...props} />;\n}\n\nexport function AlertDialogContent({ className, ...props }) {\n return (\n <AlertDialogPrimitive.Portal>\n <AlertDialogPrimitive.Overlay className=\"eb-scope eb:fixed eb:inset-0 eb:z-50 eb:bg-black/50 eb:data-[state=open]:animate-in eb:data-[state=open]:fade-in-0 eb:data-[state=closed]:animate-out eb:data-[state=closed]:fade-out-0\" />\n <AlertDialogPrimitive.Content\n className={cn(\n 'eb-scope eb:fixed eb:top-[50%] eb:left-[50%] eb:z-50 eb:grid eb:w-full eb:max-w-[calc(100%-2rem)] eb:translate-x-[-50%] eb:translate-y-[-50%] eb:gap-4 eb:rounded-lg2 eb:border eb:border-border eb:bg-background eb:p-6 eb:text-foreground eb:shadow-lg eb:duration-200 eb:sm:max-w-lg',\n FADE_ZOOM,\n className\n )}\n {...props}\n />\n </AlertDialogPrimitive.Portal>\n );\n}\n\nexport const AlertDialogTitle = ({ className, ...props }) => (\n <AlertDialogPrimitive.Title className={cn('eb:text-lg eb:font-semibold', className)} {...props} />\n);\nexport const AlertDialogDescription = ({ className, ...props }) => (\n <AlertDialogPrimitive.Description className={cn('eb:text-sm eb:text-muted-foreground', className)} {...props} />\n);\nexport const AlertDialogAction = AlertDialogPrimitive.Action;\nexport const AlertDialogCancel = AlertDialogPrimitive.Cancel;\n\n/* ── Popover ──────────────────────────────────────────────────────────── */\n\nexport function Popover(props) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />;\n}\n\nexport function PopoverTrigger(props) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />;\n}\n\nexport function PopoverContent({ className, align = 'center', sideOffset = 4, ...props }) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n 'eb-scope eb:z-50 eb:w-72 eb:origin-(--radix-popover-content-transform-origin) eb:rounded-lg2 eb:border eb:border-border eb:bg-popover eb:p-4 eb:text-popover-foreground eb:shadow-md eb:outline-hidden',\n FADE_ZOOM,\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n );\n}\n\n/* ── Dropdown menu ────────────────────────────────────────────────────── */\n\nexport function DropdownMenu(props) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nexport function DropdownMenuTrigger(props) {\n return <DropdownMenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\n}\n\nexport function DropdownMenuContent({ className, sideOffset = 4, ...props }) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n 'eb-scope eb:z-50 eb:max-h-(--radix-dropdown-menu-content-available-height) eb:min-w-[8rem] eb:origin-(--radix-dropdown-menu-content-transform-origin) eb:overflow-x-hidden eb:overflow-y-auto eb:rounded-lg2 eb:border eb:border-border eb:bg-popover eb:p-1 eb:text-popover-foreground eb:shadow-md',\n FADE_ZOOM,\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nexport function DropdownMenuGroup(props) {\n return <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />;\n}\n\nexport function DropdownMenuItem({ className, ...props }) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n className={cn(\n \"eb:relative eb:flex eb:cursor-default eb:items-center eb:gap-2 eb:rounded-sm eb:px-2 eb:py-1.5 eb:text-[13px] eb:outline-hidden eb:select-none eb:focus:bg-accent eb:focus:text-accent-foreground eb:data-[disabled]:pointer-events-none eb:data-[disabled]:opacity-50 eb:[&_svg]:pointer-events-none eb:[&_svg]:shrink-0 eb:[&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport function DropdownMenuLabel({ className, ...props }) {\n return <DropdownMenuPrimitive.Label className={cn('eb:px-2 eb:py-1.5 eb:text-[13px] eb:font-medium', className)} {...props} />;\n}\n\nexport function DropdownMenuSeparator({ className, ...props }) {\n return <DropdownMenuPrimitive.Separator className={cn('eb:-mx-1 eb:my-1 eb:h-px eb:bg-border', className)} {...props} />;\n}\n\n/* ── Select ───────────────────────────────────────────────────────────── */\n\nexport function Select(props) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nexport function SelectValue(props) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nexport function SelectTrigger({ className, children, ...props }) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n className={cn(\n \"eb:flex eb:h-8 eb:w-full eb:items-center eb:justify-between eb:gap-2 eb:rounded-lg2 eb:border eb:border-border-strong eb:bg-surface-75 eb:px-3 eb:py-1 eb:text-[13px] eb:whitespace-nowrap eb:text-foreground eb:shadow-xs eb:transition-[color,box-shadow] eb:outline-none eb:focus-visible:border-ring eb:focus-visible:ring-[3px] eb:focus-visible:ring-ring/50 eb:disabled:cursor-not-allowed eb:disabled:opacity-50 eb:data-[placeholder]:text-foreground-muted eb:*:data-[slot=select-value]:line-clamp-1 eb:*:data-[slot=select-value]:flex eb:*:data-[slot=select-value]:items-center eb:*:data-[slot=select-value]:gap-2 eb:[&_svg]:pointer-events-none eb:[&_svg]:shrink-0 eb:[&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"eb:size-4 eb:opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\n\nexport function SelectContent({ className, children, position = 'popper', ...props }) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n position={position}\n className={cn(\n 'eb-scope eb:relative eb:z-50 eb:max-h-(--radix-select-content-available-height) eb:min-w-[8rem] eb:origin-(--radix-select-content-transform-origin) eb:overflow-x-hidden eb:overflow-y-auto eb:rounded-lg2 eb:border eb:border-border eb:bg-popover eb:text-popover-foreground eb:shadow-md',\n FADE_ZOOM,\n position === 'popper' && 'eb:data-[side=bottom]:translate-y-1 eb:data-[side=top]:-translate-y-1',\n className\n )}\n {...props}\n >\n <SelectPrimitive.Viewport\n className={cn(\n 'eb:p-1',\n position === 'popper' &&\n 'eb:h-[var(--radix-select-trigger-height)] eb:w-full eb:min-w-[var(--radix-select-trigger-width)] eb:scroll-my-1'\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n}\n\nexport function SelectItem({ className, children, ...props }) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n 'eb:relative eb:flex eb:w-full eb:cursor-default eb:items-center eb:gap-2 eb:rounded-sm eb:py-1.5 eb:pr-8 eb:pl-2 eb:text-[13px] eb:outline-hidden eb:select-none eb:focus:bg-accent eb:focus:text-accent-foreground eb:data-[disabled]:pointer-events-none eb:data-[disabled]:opacity-50',\n className\n )}\n {...props}\n >\n <span className=\"eb:absolute eb:right-2 eb:flex eb:size-3.5 eb:items-center eb:justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"eb:size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\n","import { clsx } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n// Every utility class of the package carries the `eb:` prefix (see src/styles.css),\n// so class merging has to know about it.\nconst twMerge = extendTailwindMerge({ prefix: 'eb' });\n\n/** Joins class names and resolves conflicting utilities (the last one wins). */\nexport function cn(...inputs) {\n return twMerge(clsx(inputs));\n}\n","import { Slot } from 'radix-ui';\nimport { cva } from 'class-variance-authority';\nimport { cn } from './cn.js';\n\nexport const buttonVariants = cva(\n \"eb:inline-flex eb:shrink-0 eb:items-center eb:justify-center eb:gap-2 eb:whitespace-nowrap eb:rounded-lg2 eb:text-sm eb:font-medium eb:transition-all eb:outline-none eb:disabled:pointer-events-none eb:disabled:opacity-50 eb:focus-visible:border-ring eb:focus-visible:ring-[3px] eb:focus-visible:ring-ring/50 eb:aria-invalid:border-destructive eb:aria-invalid:ring-destructive/20 eb:[&_svg]:pointer-events-none eb:[&_svg]:shrink-0 eb:[&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: 'eb:bg-primary eb:text-primary-foreground eb:hover:bg-primary/90',\n destructive: 'eb:bg-destructive eb:text-white eb:hover:bg-destructive/90 eb:focus-visible:ring-destructive/20',\n outline: 'eb:border eb:border-border eb:bg-background eb:text-foreground eb:shadow-xs eb:hover:bg-accent eb:hover:text-accent-foreground',\n secondary: 'eb:bg-secondary eb:text-secondary-foreground eb:hover:bg-secondary/80',\n ghost: 'eb:text-foreground eb:hover:bg-accent eb:hover:text-accent-foreground',\n link: 'eb:text-primary eb:underline-offset-4 eb:hover:underline',\n },\n size: {\n default: 'eb:h-8 eb:gap-1.5 eb:px-3 eb:text-[13px] eb:has-[>svg]:px-2.5',\n xs: \"eb:h-6 eb:gap-1 eb:px-2 eb:text-xs eb:has-[>svg]:px-1.5 eb:[&_svg:not([class*='size-'])]:size-3\",\n 'sm-compact': \"eb:h-7 eb:gap-1.5 eb:px-3 eb:text-xs eb:has-[>svg]:px-2.5 eb:[&_svg:not([class*='size-'])]:size-3\",\n sm: 'eb:h-8 eb:gap-1.5 eb:px-3 eb:text-[13px] eb:has-[>svg]:px-2.5',\n lg: 'eb:h-10 eb:px-6 eb:has-[>svg]:px-4',\n icon: 'eb:size-8',\n 'icon-xs': \"eb:size-6 eb:[&_svg:not([class*='size-'])]:size-3\",\n 'icon-sm-compact': \"eb:size-7 eb:[&_svg:not([class*='size-'])]:size-3\",\n 'icon-sm': 'eb:size-8',\n },\n },\n defaultVariants: { variant: 'default', size: 'default' },\n }\n);\n\nexport function Button({ className, variant = 'default', size = 'default', asChild = false, type, ...props }) {\n const Comp = asChild ? Slot.Root : 'button';\n return (\n <Comp\n data-slot=\"button\"\n type={asChild ? type : type || 'button'}\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n );\n}\n","import { Separator as SeparatorPrimitive, Tabs as TabsPrimitive, Tooltip as TooltipPrimitive } from 'radix-ui';\nimport { cn } from './cn.js';\n\nexport function Separator({ className, orientation = 'horizontal', decorative = true, ...props }) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n decorative={decorative}\n orientation={orientation}\n className={cn(\n 'eb:shrink-0 eb:bg-border eb:data-[orientation=horizontal]:h-px eb:data-[orientation=horizontal]:w-full eb:data-[orientation=vertical]:h-full eb:data-[orientation=vertical]:w-px',\n className\n )}\n {...props}\n />\n );\n}\n\nexport function Skeleton({ className, as: Comp = 'div', ...props }) {\n return <Comp data-slot=\"skeleton\" className={cn('eb:animate-pulse eb:rounded-lg2 eb:bg-accent', className)} {...props} />;\n}\n\n/** Small uppercase heading of a panel section. */\nexport function SectionLabel({ className, ...props }) {\n return (\n <span\n data-slot=\"section-label\"\n className={cn('eb:font-mono eb:text-[10px] eb:uppercase eb:tracking-[0.14em] eb:text-foreground-muted', className)}\n {...props}\n />\n );\n}\n\n/** One line of text, cut with an ellipsis when it overflows (full text on hover). */\nexport function TruncatedText({ children, className, as: Comp = 'span', ...props }) {\n return (\n <Comp\n className={cn('eb:block eb:truncate', className)}\n title={typeof children === 'string' ? children : undefined}\n {...props}\n >\n {children}\n </Comp>\n );\n}\n\n/* ── Tabs ─────────────────────────────────────────────────────────────── */\n\nexport function Tabs({ className, ...props }) {\n return <TabsPrimitive.Root data-slot=\"tabs\" className={cn('eb:flex eb:flex-col eb:gap-2', className)} {...props} />;\n}\n\nexport function TabsList({ className, ...props }) {\n return (\n <TabsPrimitive.List\n data-slot=\"tabs-list\"\n className={cn(\n 'eb:inline-flex eb:h-8 eb:w-fit eb:items-center eb:justify-center eb:rounded-lg2 eb:bg-muted eb:p-[3px] eb:text-muted-foreground',\n className\n )}\n {...props}\n />\n );\n}\n\nexport function TabsTrigger({ className, ...props }) {\n return (\n <TabsPrimitive.Trigger\n data-slot=\"tabs-trigger\"\n className={cn(\n \"eb:inline-flex eb:h-[calc(100%-1px)] eb:flex-1 eb:items-center eb:justify-center eb:gap-1.5 eb:rounded-lg2 eb:border eb:border-transparent eb:px-2 eb:py-1 eb:text-[13px] eb:font-medium eb:whitespace-nowrap eb:text-foreground/60 eb:transition-all eb:hover:text-foreground eb:focus-visible:border-ring eb:focus-visible:ring-[3px] eb:focus-visible:ring-ring/50 eb:focus-visible:outline-1 eb:disabled:pointer-events-none eb:disabled:opacity-50 eb:data-[state=active]:bg-background eb:data-[state=active]:text-foreground eb:data-[state=active]:shadow-sm eb:[&_svg]:pointer-events-none eb:[&_svg]:shrink-0 eb:[&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\n/* ── Tooltip ──────────────────────────────────────────────────────────── */\n\nexport function TooltipProvider({ delayDuration = 0, ...props }) {\n return <TooltipPrimitive.Provider delayDuration={delayDuration} {...props} />;\n}\n\nexport function Tooltip(props) {\n return <TooltipPrimitive.Root {...props} />;\n}\n\nexport function TooltipTrigger(props) {\n return <TooltipPrimitive.Trigger {...props} />;\n}\n\nexport function TooltipContent({ className, sideOffset = 4, children, ...props }) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n 'eb-scope eb:z-50 eb:w-fit eb:origin-(--radix-tooltip-content-transform-origin) eb:animate-in eb:rounded-lg2 eb:border eb:border-border eb:bg-popover eb:px-3 eb:py-1.5 eb:text-xs eb:text-balance eb:text-popover-foreground eb:shadow-md eb:fade-in-0 eb:zoom-in-95 eb:data-[state=closed]:animate-out eb:data-[state=closed]:fade-out-0 eb:data-[state=closed]:zoom-out-95',\n className\n )}\n {...props}\n >\n {children}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\n/** Wraps a control with a tooltip; without a label, renders the control alone. */\nexport function TooltipWrap({ label, side = 'top', children, asChild = true, delayDuration }) {\n if (!label) return children;\n return (\n <Tooltip delayDuration={delayDuration}>\n <TooltipTrigger asChild={asChild}>{children}</TooltipTrigger>\n <TooltipContent side={side} className=\"eb:px-2 eb:py-1 eb:text-[11px]\">\n {label}\n </TooltipContent>\n </Tooltip>\n );\n}\n","// @ts-check\n/**\n * Building blocks shared by all blocks: palette, fonts, recurring properties.\n *\n * -- DEFAULT PALETTE ---------------------------------------------------------\n * Plain hex values: email clients load no stylesheet and understand neither\n * `var()` nor modern color functions, so every value ends up inline in a\n * `style=\"\"` attribute.\n *\n * -- EVERY BLOCK SETS ITS OWN TEXT ATTRIBUTES --------------------------------\n * Font, size, line height and color are written on the element itself, never\n * left to MJML defaults (the \"Ubuntu\" font loaded from Google, line height 1):\n * the canvas and the sent email then render the same thing, and Outlook gets\n * explicit values.\n *\n * Fonts: only web-safe stacks, installed everywhere and understood by\n * Outlook - a web font only renders in a minority of email clients.\n */\n\n/** @typedef {import('../core/EmailEditor.js').BlockProperty} BlockProperty */\n\n/** The default palette. */\nexport const PALETTE = {\n ink: '#2b3038',\n inkSoft: '#41506b',\n navy: '#212e5a',\n brand: '#2977bc',\n border: '#dfe6f0',\n canvas: '#eceff4',\n surface: '#ffffff',\n white: '#ffffff',\n};\n\n/** Default link of a new button. */\nexport const DEFAULT_BUTTON_URL = 'https://example.com';\n\nexport const FONT_STACK = 'Arial, Helvetica, sans-serif';\n\n/** @type {{value: string, label: string}[]} */\nexport const FONT_OPTIONS = [\n { value: 'Arial, Helvetica, sans-serif', label: 'Arial' },\n { value: 'Verdana, Geneva, sans-serif', label: 'Verdana' },\n { value: 'Tahoma, Geneva, sans-serif', label: 'Tahoma' },\n { value: \"'Trebuchet MS', Helvetica, sans-serif\", label: 'Trebuchet' },\n { value: 'Georgia, Times, serif', label: 'Georgia' },\n { value: \"'Times New Roman', Times, serif\", label: 'Times' },\n { value: \"'Courier New', Courier, monospace\", label: 'Courier' },\n];\n\n/** @type {{value: string, label: string}[]} */\nexport const ALIGN_OPTIONS = [\n { value: 'left', label: 'Left' },\n { value: 'center', label: 'Center' },\n { value: 'right', label: 'Right' },\n];\n\n/** Properties panel groups, in display order. */\nexport const GROUPS = {\n content: 'Content',\n link: 'Link',\n typography: 'Typography',\n colors: 'Colors',\n layout: 'Layout',\n spacing: 'Spacing',\n};\n\n/** Recurring properties. */\nexport const prop = {\n /** @returns {BlockProperty} */\n fontFamily: () => ({ key: 'font-family', label: 'Font', type: 'select', group: GROUPS.typography, options: FONT_OPTIONS }),\n /** @returns {BlockProperty} */\n fontSize: (min = 10, max = 48) => ({ key: 'font-size', label: 'Size', type: 'size', group: GROUPS.typography, min, max, unit: 'px' }),\n /** @returns {BlockProperty} */\n lineHeight: () => ({ key: 'line-height', label: 'Line height', type: 'size', group: GROUPS.typography, min: 10, max: 80, unit: 'px' }),\n /** @returns {BlockProperty} */\n color: (label = 'Text') => ({ key: 'color', label, type: 'color', group: GROUPS.colors }),\n /** @returns {BlockProperty} */\n background: (key = 'background-color', label = 'Background') => ({ key, label, type: 'color', group: GROUPS.colors }),\n /** @returns {BlockProperty} */\n align: (options = ALIGN_OPTIONS) => ({ key: 'align', label: 'Alignment', type: 'align', group: GROUPS.layout, options }),\n /** @returns {BlockProperty} */\n padding: (key = 'padding', label = 'Padding') => ({ key, label, type: 'spacing', group: GROUPS.spacing }),\n /** @returns {BlockProperty} */\n href: (label = 'Link URL') => ({ key: 'href', label, type: 'url', group: GROUPS.link, placeholder: 'https://' }),\n /** @returns {BlockProperty} */\n radius: (max = 40) => ({ key: 'border-radius', label: 'Corner radius', type: 'size', group: GROUPS.layout, min: 0, max, unit: 'px' }),\n};\n\n/**\n * White one-column section: the wrapper of a content block dropped outside\n * any column (MJML does not accept text directly inside the body).\n *\n * Warning: padding in LONGHAND form, never `padding=\"...\"`. The canvas starts\n * from the longhand defaults (20 px for a section), which override the\n * shorthand, while the export omits them - the screen and the email would\n * diverge (see core/mjmlAttributes).\n *\n * @param {string} inner\n */\nexport function inWhiteSection(inner) {\n return (\n `<mj-section background-color=\"${PALETTE.surface}\" padding-top=\"0px\" padding-bottom=\"0px\">` +\n `<mj-column>${inner}</mj-column></mj-section>`\n );\n}\n","// @ts-check\n/**\n * Starter template of a new email.\n *\n * A complete email rather than a blank page: header (logo or sender name),\n * headline, text, button, and a FOOTER with the sender's postal address and the\n * unsubscribe link — the two mentions a bulk email must carry (CAN-SPAM, GDPR)\n * and that get forgotten when starting from nothing.\n *\n * Written with the same settings as the blocks (`blocks/`), with longhand\n * paddings (see core/mjmlAttributes): what the canvas shows is what gets sent.\n */\n\nimport { identity } from '../../i18n/index.js';\nimport { DEFAULT_BUTTON_URL, FONT_STACK, PALETTE } from '../../blocks/shared.js';\n\n/**\n * @typedef {{\n * name?: string,\n * address?: string,\n * logoUrl?: string,\n * logoWidth?: number,\n * }} StarterSender\n */\n\nexport function escapeXml(text) {\n return String(text ?? '')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n\nexport const SIDE = 'padding-left=\"32px\" padding-right=\"32px\"';\nexport const TEXT = `font-family=\"${FONT_STACK}\" color=\"${PALETTE.ink}\"`;\n\n/**\n * Header row: the sender's logo, or its name in bold.\n * @param {StarterSender} sender @param {import('../../i18n/index.js').Translate} t\n */\nexport function senderHeaderMjml(sender, t) {\n const name = escapeXml(sender.name || t('Your company'));\n return sender.logoUrl\n ? `<mj-image src=\"${escapeXml(sender.logoUrl)}\" alt=\"${name}\" width=\"${Number(sender.logoWidth) || 140}px\" align=\"left\" ${SIDE}></mj-image>`\n : `<mj-text ${TEXT} font-size=\"18px\" line-height=\"24px\" font-weight=\"bold\" ${SIDE}>${name}</mj-text>`;\n}\n\n/**\n * Footer section: sender name and postal address, unsubscribe link — the two\n * mentions a bulk email must carry (CAN-SPAM, GDPR).\n * @param {StarterSender} sender @param {import('../../i18n/index.js').Translate} t\n */\nexport function footerSectionMjml(sender, t) {\n const name = escapeXml(sender.name || t('Your company'));\n const footer = [name, sender.address ? escapeXml(sender.address) : ''].filter(Boolean).join(' · ');\n return (\n '<mj-section padding-top=\"20px\" padding-bottom=\"28px\">' +\n '<mj-column>' +\n `<mj-text font-family=\"${FONT_STACK}\" font-size=\"12px\" line-height=\"18px\" color=\"#6d7484\" align=\"center\" ${SIDE}>` +\n `${footer}<br />` +\n `<a href=\"{{ unsubscribe }}\" style=\"color:#6d7484;text-decoration:underline;\">${escapeXml(t('Unsubscribe'))}</a>` +\n '</mj-text>' +\n '</mj-column>' +\n '</mj-section>'\n );\n}\n\n/**\n * @param {{\n * sender?: StarterSender,\n * buttonUrl?: string,\n * t?: import('../../i18n/index.js').Translate,\n * }} [options]\n */\nexport function createStarterMjml({ sender = {}, buttonUrl = DEFAULT_BUTTON_URL, t = identity } = {}) {\n return [\n '<mjml>',\n `<mj-body background-color=\"${PALETTE.canvas}\" width=\"600px\">`,\n // Header: logo or sender name.\n `<mj-section background-color=\"${PALETTE.surface}\" padding-top=\"28px\" padding-bottom=\"8px\">`,\n '<mj-column>',\n senderHeaderMjml(sender, t),\n '</mj-column>',\n '</mj-section>',\n // Body: headline, text, button.\n `<mj-section background-color=\"${PALETTE.surface}\" padding-top=\"8px\" padding-bottom=\"28px\">`,\n '<mj-column>',\n `<mj-text ${TEXT} font-size=\"24px\" line-height=\"32px\" font-weight=\"bold\" ${SIDE}>${escapeXml(t('Your headline'))}</mj-text>`,\n `<mj-text ${TEXT} font-size=\"15px\" line-height=\"24px\" ${SIDE}>` +\n `${escapeXml(t('Hello {name},', { name: '{{contact.firstname}}' }))}<br /><br />${escapeXml(t('Your text.'))}</mj-text>`,\n `<mj-button href=\"${escapeXml(buttonUrl)}\" background-color=\"${PALETTE.navy}\" color=\"${PALETTE.white}\" ` +\n `font-family=\"${FONT_STACK}\" font-size=\"15px\" font-weight=\"bold\" border-radius=\"6px\" ` +\n `inner-padding=\"12px 28px\" align=\"left\" ${SIDE}>${escapeXml(t('Learn more'))}</mj-button>`,\n '</mj-column>',\n '</mj-section>',\n // Footer: sender and unsubscribe link.\n footerSectionMjml(sender, t),\n '</mj-body>',\n '</mjml>',\n ].join('');\n}\n\n/** The starter template with default (English) texts. */\nexport const STARTER_MJML = createStarterMjml();\n","// @ts-check\n/**\n * SOCIAL LINKS - `mj-social` and its `mj-social-element` icons.\n *\n * MJML draws each icon as an image in a table cell, so the row holds in\n * Outlook. The networks use their `-noshare` variant: the link goes to the\n * page given (the company's profile), not to a \"share this\" dialog.\n *\n * The icons are MJML's own, served over https by Mailjet; a network can be\n * changed, a link duplicated (one more network) or deleted from the panel.\n * No text next to the icons: the row stays readable on a phone.\n */\n\nimport { GROUPS, inWhiteSection, prop } from '../shared.js';\n\n/** @typedef {import('../../core/EmailEditor.js').EmailBlock} EmailBlock */\n\n/** Networks MJML ships an icon for (server and canvas). */\nexport const SOCIAL_NETWORKS = [\n { value: 'facebook-noshare', label: 'Facebook', href: 'https://www.facebook.com/' },\n { value: 'instagram-noshare', label: 'Instagram', href: 'https://www.instagram.com/' },\n { value: 'linkedin-noshare', label: 'LinkedIn', href: 'https://www.linkedin.com/' },\n { value: 'x-noshare', label: 'X', href: 'https://x.com/' },\n { value: 'youtube-noshare', label: 'YouTube', href: 'https://www.youtube.com/' },\n { value: 'github-noshare', label: 'GitHub', href: 'https://github.com/' },\n];\n\nconst DEFAULT_NETWORKS = ['facebook-noshare', 'instagram-noshare', 'linkedin-noshare', 'x-noshare'];\n\nconst MJML =\n '<mj-social mode=\"horizontal\" align=\"center\" icon-size=\"28px\" border-radius=\"14px\" inner-padding=\"6px\">' +\n DEFAULT_NETWORKS.map((name) => {\n const network = SOCIAL_NETWORKS.find((n) => n.value === name);\n return `<mj-social-element name=\"${name}\" href=\"${network?.href}\"></mj-social-element>`;\n }).join('') +\n '</mj-social>';\n\n/** @type {EmailBlock} */\nexport const socialBlock = {\n id: 'social',\n label: 'Social links',\n description: 'Icons linking to your profiles',\n icon: 'Share2',\n kind: 'content',\n tagName: 'mj-social',\n order: 60,\n mjml: MJML,\n sectionMjml: inWhiteSection(MJML),\n properties: [\n { key: 'icon-size', label: 'Icon size', type: 'size', group: GROUPS.layout, min: 16, max: 48, unit: 'px' },\n prop.radius(24),\n prop.align(),\n {\n key: 'mode',\n label: 'Direction',\n type: 'select',\n group: GROUPS.layout,\n options: [\n { value: 'horizontal', label: 'Horizontal' },\n { value: 'vertical', label: 'Vertical' },\n ],\n },\n prop.padding('inner-padding', 'Space around each icon'),\n prop.padding(),\n ],\n};\n\n/** One icon of the row: selectable, not addable (duplicate it instead). */\n/** @type {EmailBlock} */\nexport const socialElementBlock = {\n id: 'social-element',\n label: 'Social link',\n icon: 'Link',\n kind: 'structure',\n tagName: 'mj-social-element',\n order: 903,\n properties: [\n {\n key: 'name',\n label: 'Network',\n type: 'select',\n group: GROUPS.content,\n options: SOCIAL_NETWORKS.map(({ value, label }) => ({ value, label })),\n },\n prop.href('Profile URL'),\n prop.background('background-color', 'Icon background'),\n ],\n};\n","// @ts-check\n/**\n * TEMPLATE GALLERY — ready-made emails to start from.\n *\n * Each entry builds its MJML from the same pieces as the blocks (palette,\n * web-safe fonts, longhand paddings) and ends with the sender's footer and the\n * unsubscribe link: a template picked here passes the server's quality checks\n * as it is. Texts go through `t()`, so a French interface starts from French\n * emails.\n *\n * Images are left EMPTY on purpose (the canvas shows a frame to fill): a\n * sample photo from a third-party service would, one day, end up in a real\n * send. Thumbnails replace them with a grey placeholder (`withThumbnailImages`).\n *\n * The list is plain data: pass your own to `<EmailBuilder templates>`, or `[]`\n * to hide the gallery.\n */\n\nimport { identity } from '../../i18n/index.js';\nimport { DEFAULT_BUTTON_URL, FONT_STACK, PALETTE } from '../../blocks/shared.js';\nimport { SOCIAL_NETWORKS } from '../../blocks/social/index.js';\nimport { SIDE, createStarterMjml, escapeXml, footerSectionMjml, senderHeaderMjml } from './starter.js';\n\n/**\n * @typedef {import('./starter.js').StarterSender} StarterSender\n * @typedef {import('../../i18n/index.js').Translate} Translate\n *\n * @typedef {{\n * id: string,\n * name: string,\n * description: string,\n * create: (options: {sender: StarterSender, t: Translate}) => string,\n * meta?: (t: Translate) => {subject?: string, preheader?: string},\n * }} GalleryTemplate\n */\n\nconst WHITE_SECTION = `background-color=\"${PALETTE.surface}\"`;\n\n/**\n * White section, paddings in longhand (see core/mjmlAttributes).\n * @param {string} inner @param {{top?: number, bottom?: number, x?: number}} [padding]\n */\nfunction section(inner, { top = 8, bottom = 8, x = 0 } = {}) {\n const sides = x ? ` padding-left=\"${x}px\" padding-right=\"${x}px\"` : '';\n return `<mj-section ${WHITE_SECTION} padding-top=\"${top}px\" padding-bottom=\"${bottom}px\"${sides}>${inner}</mj-section>`;\n}\n\n/** @param {string} inner @param {string} [attrs] */\nfunction column(inner, attrs = '') {\n return `<mj-column${attrs ? ` ${attrs}` : ''}>${inner}</mj-column>`;\n}\n\n/** @param {string} text @param {{size?: number, color?: string, align?: string, side?: boolean}} [o] */\nfunction heading(text, { size = 24, color = PALETTE.navy, align = 'left', side = true } = {}) {\n return (\n `<mj-text font-family=\"${FONT_STACK}\" font-size=\"${size}px\" line-height=\"${Math.round(size * 1.3)}px\" ` +\n `font-weight=\"bold\" color=\"${color}\" align=\"${align}\"${side ? ` ${SIDE}` : ''}>${text}</mj-text>`\n );\n}\n\n/** @param {string} html @param {{size?: number, color?: string, align?: string, side?: boolean}} [o] */\nfunction paragraph(html, { size = 15, color = PALETTE.ink, align = 'left', side = true } = {}) {\n return (\n `<mj-text font-family=\"${FONT_STACK}\" font-size=\"${size}px\" line-height=\"${Math.round(size * 1.6)}px\" ` +\n `color=\"${color}\" align=\"${align}\"${side ? ` ${SIDE}` : ''}>${html}</mj-text>`\n );\n}\n\n/** @param {string} label @param {{align?: string, background?: string, color?: string, side?: boolean}} [o] */\nfunction button(label, { align = 'left', background = PALETTE.navy, color = PALETTE.white, side = true } = {}) {\n return (\n `<mj-button href=\"${DEFAULT_BUTTON_URL}\" background-color=\"${background}\" color=\"${color}\" ` +\n `font-family=\"${FONT_STACK}\" font-size=\"15px\" font-weight=\"bold\" border-radius=\"6px\" ` +\n `inner-padding=\"12px 28px\" align=\"${align}\"${side ? ` ${SIDE}` : ''}>${label}</mj-button>`\n );\n}\n\nconst IMAGE = '<mj-image align=\"center\"></mj-image>';\n\n/** @param {StarterSender} sender @param {Translate} t */\nfunction header(sender, t) {\n return `<mj-section ${WHITE_SECTION} padding-top=\"28px\" padding-bottom=\"8px\">${column(senderHeaderMjml(sender, t))}</mj-section>`;\n}\n\n/** A coloured banner: title, sentence, button — the Hero banner block. */\nfunction banner({ title, text, cta, background = PALETTE.navy }) {\n return (\n `<mj-section background-color=\"${background}\" background-size=\"cover\" background-position=\"center center\" ` +\n 'background-repeat=\"no-repeat\" padding-top=\"48px\" padding-bottom=\"48px\">' +\n column(\n heading(title, { size: 30, color: PALETTE.white, align: 'center' }) +\n paragraph(text, { size: 16, color: PALETTE.border, align: 'center' }) +\n (cta ? button(cta, { align: 'center', background: PALETTE.white, color: PALETTE.navy }) : '')\n ) +\n '</mj-section>'\n );\n}\n\nfunction social() {\n const elements = ['facebook-noshare', 'instagram-noshare', 'linkedin-noshare']\n .map((name) => `<mj-social-element name=\"${name}\" href=\"${SOCIAL_NETWORKS.find((n) => n.value === name)?.href}\"></mj-social-element>`)\n .join('');\n return section(\n column(\n `<mj-social mode=\"horizontal\" align=\"center\" icon-size=\"28px\" border-radius=\"14px\" inner-padding=\"6px\">${elements}</mj-social>`\n ),\n { top: 16, bottom: 16 }\n );\n}\n\n/** @param {string} body */\nfunction email(body) {\n return `<mjml><mj-body background-color=\"${PALETTE.canvas}\" width=\"600px\">${body}</mj-body></mjml>`;\n}\n\nconst esc = escapeXml;\n\n/** @type {GalleryTemplate[]} */\nexport const TEMPLATE_GALLERY = [\n {\n id: 'blank',\n name: 'Blank',\n description: 'An empty page to build from scratch',\n create: () => email(''),\n },\n {\n id: 'simple',\n name: 'Simple',\n description: 'Logo, headline, text and a button',\n create: ({ sender, t }) => createStarterMjml({ sender, t }),\n },\n {\n id: 'newsletter',\n name: 'Newsletter',\n description: 'Monthly news: banner, two articles, highlights',\n meta: (t) => ({\n subject: t('The news of the month'),\n preheader: t('What changed, what is coming, and two stories worth your time.'),\n }),\n create: ({ sender, t }) =>\n email(\n header(sender, t) +\n banner({\n title: esc(t('The news of the month')),\n text: esc(t('What changed, what is coming, and two stories worth your time.')),\n cta: null,\n }) +\n [1, 2]\n .map((n) =>\n section(\n column(IMAGE, 'vertical-align=\"middle\"') +\n column(\n heading(esc(t('Article {n}', { n })), { size: 20, side: false }) +\n paragraph(esc(t('Two or three sentences that sum up the story and make people want the rest.')), {\n side: false,\n }) +\n button(esc(t('Read more')), { side: false }),\n 'vertical-align=\"middle\"'\n ),\n { top: 16, bottom: 16, x: 16 }\n )\n )\n .join('') +\n section(column(heading(esc(t('In brief')), { size: 20 })), { top: 20, bottom: 0 }) +\n section(\n [t('A new feature'), t('An event'), t('A tip')]\n .map((title) =>\n column(\n heading(esc(title), { size: 16, side: false }) +\n paragraph(esc(t('One sentence about it.')), { size: 14, side: false })\n )\n )\n .join(''),\n { bottom: 20, x: 16 }\n ) +\n social() +\n footerSectionMjml(sender, t)\n ),\n },\n {\n id: 'welcome',\n name: 'Welcome',\n description: 'Greets a new customer and lists the first steps',\n meta: (t) => ({ subject: t('Welcome aboard!'), preheader: t('Three steps to get started.') }),\n create: ({ sender, t }) =>\n email(\n header(sender, t) +\n section(\n column(\n heading(esc(t('Welcome, {name}!', { name: '{{contact.firstname}}' })), { size: 28 }) +\n paragraph(esc(t('Thank you for joining us. Here is how to get the most out of your account.')))\n ),\n { top: 16, bottom: 8 }\n ) +\n section(\n [\n [t('1. Complete your profile'), t('So we can tailor what we send you.')],\n [t('2. Explore'), t('Take a tour of what you can do.')],\n [t('3. Ask us anything'), t('Reply to this email: a person reads it.')],\n ]\n .map(([title, text]) =>\n column(\n heading(esc(title), { size: 16, side: false }) + paragraph(esc(text), { size: 14, side: false }),\n `background-color=\"${PALETTE.canvas}\" padding-top=\"12px\" padding-bottom=\"12px\" padding-left=\"12px\" padding-right=\"12px\"`\n )\n )\n .join(''),\n { x: 24 }\n ) +\n section(column(button(esc(t('Get started')), { align: 'center' })), { top: 16, bottom: 28 }) +\n footerSectionMjml(sender, t)\n ),\n },\n {\n id: 'promotion',\n name: 'Promotion',\n description: 'A sale with a discount code and two products',\n meta: (t) => ({ subject: t('30% off this weekend only'), preheader: t('With the code SPRING30, until Sunday midnight.') }),\n create: ({ sender, t }) =>\n email(\n header(sender, t) +\n banner({\n title: esc(t('30% off everything')),\n text: esc(t('This weekend only, with the code SPRING30.')),\n cta: esc(t('Shop the sale')),\n background: PALETTE.brand,\n }) +\n section(\n [t('Product one'), t('Product two')]\n .map((name) =>\n column(\n IMAGE +\n heading(esc(name), { size: 18, side: false }) +\n paragraph(esc(t('€49 instead of €70')), { size: 15, side: false }) +\n button(esc(t('Buy')), { side: false })\n )\n )\n .join(''),\n { top: 20, bottom: 20, x: 16 }\n ) +\n section(\n column(\n paragraph(esc(t('Offer valid until Sunday midnight, while stocks last.')), {\n size: 12,\n color: '#6d7484',\n align: 'center',\n })\n )\n ) +\n footerSectionMjml(sender, t)\n ),\n },\n {\n id: 'event',\n name: 'Event invitation',\n description: 'Date, place and a button to book a seat',\n meta: (t) => ({ subject: t(\"You're invited\"), preheader: t('Save the date — seats are limited.') }),\n create: ({ sender, t }) =>\n email(\n header(sender, t) +\n banner({\n title: esc(t(\"You're invited\")),\n text: esc(t('An evening of talks and drinks with the team and our customers.')),\n cta: null,\n }) +\n section(\n column(heading(esc(t('When')), { size: 16, side: false }) + paragraph(esc(t('Thursday, 7 pm')), { side: false })) +\n column(heading(esc(t('Where')), { size: 16, side: false }) + paragraph(esc(t('Our offices, 1 Main Street')), { side: false })),\n { top: 24, x: 16 }\n ) +\n section(\n column(\n paragraph(esc(t('Seats are limited: book yours now, it takes ten seconds.'))) +\n button(esc(t('Book my seat')), { align: 'left' })\n ),\n { bottom: 28 }\n ) +\n footerSectionMjml(sender, t)\n ),\n },\n];\n\n/**\n * The gallery with its texts translated and the sender applied.\n *\n * @param {{templates?: GalleryTemplate[], sender?: StarterSender, t?: Translate}} [options]\n * @returns {{id: string, name: string, description: string, mjml: string, subject: string, preheader: string}[]}\n */\nexport function buildGallery({ templates = TEMPLATE_GALLERY, sender = {}, t = identity } = {}) {\n return templates.map((template) => {\n const meta = template.meta ? template.meta(t) : {};\n return {\n id: template.id,\n name: t(template.name),\n description: t(template.description),\n mjml: template.create({ sender, t }),\n subject: meta.subject || '',\n preheader: meta.preheader || '',\n };\n });\n}\n\n/** Grey frame drawn in place of an image not chosen yet, in thumbnails only. */\nconst THUMBNAIL_IMAGE =\n \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 300'%3E\" +\n \"%3Crect width='600' height='300' fill='%23dfe6f0'/%3E%3C/svg%3E\";\n\n/**\n * MJML for a thumbnail: empty images get a grey frame instead of a broken\n * image icon. Never saved: the template itself keeps its empty images.\n * @param {string} mjml\n */\nexport function withThumbnailImages(mjml) {\n return String(mjml || '').replace(/<mj-image(?![^>]*\\ssrc=)([^>]*)>/g, `<mj-image src=\"${THUMBNAIL_IMAGE}\"$1>`);\n}\n\n/**\n * Compiled HTML for a thumbnail or a preview: an image not chosen yet (an\n * `<img>` with no `src`) gets the same grey frame. For HTML that went through\n * the server's validator, which rightly refuses `data:` images in MJML.\n * @param {string} html\n */\nexport function withPlaceholderImages(html) {\n return String(html || '').replace(/<img(?![^>]*\\ssrc=)(\\s[^>]*)?>/g, (_m, attrs = '') => `<img src=\"${THUMBNAIL_IMAGE}\"${attrs}>`);\n}\n","// @ts-check\n/**\n * STORAGE on the browser side — the interface only knows this contract.\n *\n * list() → templates, most recently changed first,\n * without document, MJML or HTML (optional:\n * the library — `TemplateLibrary`)\n * load(id) → template (document, mjml, revision…)\n * remove(id) → void (optional)\n * create(payload) → { template, warnings }\n * duplicate(id) → { template, warnings }\n * save(id, payload) → { template, warnings, version }\n * listVersions(id) → versions, newest first\n * getVersion(id, versionId) → version, project included\n * uploadImage(file) → { path }: RELATIVE path of the uploaded image\n * render(input) → { html, warnings, quality } (optional: preview)\n * sendTest(input) → { sent, failed, invalid, results } (optional: test send)\n * listVariables() → custom variables (optional: user-defined\n * saveVariable(variable) → saved variable variables, shared by\n * deleteVariable(key) → void every template)\n *\n * Two implementations: HTTP (talks to `createEmailBuilderHandler` from\n * `best-email-builder/server`, or to any backend with the same routes) and memory\n * (stories, tests, demos). The interface cannot tell them apart.\n *\n * The document ALWAYS travels serialized then re-read (`readDocument`): a\n * project that would not survive JSON shows up in the memory implementation\n * already, not in production.\n */\n\nimport { readDocument } from '../core/document.js';\nimport { DEFAULT_ASSETS_PATH } from '../renderer/links.js';\nimport { IMAGE_TYPES, imageUploadError } from '../validation/images.js';\nimport { DEFAULT_VARIABLES, validateCustomVariable } from '../features/variables/catalog.js';\n\n/**\n * @typedef {import('../core/document.js').EmailDocument} EmailDocument\n * @typedef {import('../features/variables/catalog.js').EmailVariable} EmailVariable\n *\n * @typedef {{\n * id: number|string,\n * name: string,\n * description?: string|null,\n * subject?: string|null,\n * preheader?: string|null,\n * revision?: string|null,\n * document?: EmailDocument,\n * mjml?: string,\n * html?: string,\n * createdAt?: string,\n * updatedAt?: string|null,\n * }} StoredTemplate\n *\n * @typedef {{\n * name?: string,\n * description?: string|null,\n * subject?: string|null,\n * preheader?: string|null,\n * document: EmailDocument,\n * mjml: string,\n * revision?: string|null,\n * createVersion?: boolean,\n * }} SavePayload\n *\n * @typedef {{\n * id: number|string,\n * versionNumber: number,\n * name?: string,\n * subject?: string|null,\n * createdBy?: string|null,\n * createdAt?: string,\n * }} TemplateVersion\n *\n * @typedef {{mjml: string, subject?: string|null, preheader?: string|null}} RenderInput\n * @typedef {{html: string, warnings: {message: string}[], quality: {code: string, level: string, message: string}[]}} RenderResult\n * @typedef {{email: string, ok: boolean, error: string|null}} TestResult\n * @typedef {{sent: number, failed: number, invalid: string[], results: TestResult[]}} SendTestResult\n *\n * @typedef {{\n * list?: () => Promise<StoredTemplate[]>,\n * load: (id: number|string) => Promise<StoredTemplate>,\n * remove?: (id: number|string) => Promise<void>,\n * create: (payload: SavePayload & {name: string}) => Promise<{template: StoredTemplate, warnings: object[]}>,\n * duplicate: (id: number|string) => Promise<{template: StoredTemplate, warnings: object[]}>,\n * save: (id: number|string, payload: SavePayload) => Promise<{template: StoredTemplate, warnings: object[], version: {id: number|string, versionNumber: number}|null}>,\n * listVersions: (id: number|string) => Promise<TemplateVersion[]>,\n * getVersion: (id: number|string, versionId: number|string) => Promise<TemplateVersion & {document: EmailDocument, mjml: string}>,\n * uploadImage: (file: Blob & {name?: string}) => Promise<{path: string}>,\n * render?: (input: RenderInput) => Promise<RenderResult>,\n * sendTest?: (input: RenderInput & {emails: string[]}) => Promise<SendTestResult>,\n * listVariables?: () => Promise<EmailVariable[]>,\n * saveVariable?: (variable: Partial<EmailVariable>, options?: {create?: boolean}) => Promise<EmailVariable>,\n * deleteVariable?: (key: string) => Promise<void>,\n * }} TemplateStorage\n */\n\nexport class StorageError extends Error {\n /** @param {string} message @param {number} status @param {string} [code] */\n constructor(message, status, code) {\n super(message);\n this.name = 'StorageError';\n this.status = status;\n this.code = code;\n }\n}\n\n/** @param {{type?: string, size?: number}} file */\nfunction assertUploadable(file) {\n const error = imageUploadError(file);\n if (error) throw new StorageError(error, 415, 'UNSUPPORTED_IMAGE');\n}\n\n/** Re-reads the document of a received template (JSON → validated envelope). */\nfunction withDocument(template) {\n if (!template || !template.document) return template;\n return { ...template, document: readDocument(template.document) };\n}\n\n/**\n * Client for the routes of `createEmailBuilderHandler` (`best-email-builder/server`).\n *\n * @param {{\n * baseUrl?: string,\n * headers?: Record<string, string> | (() => Record<string, string>),\n * fetch?: typeof fetch,\n * }} [options]\n * @returns {TemplateStorage}\n */\nexport function createHttpStorage({ baseUrl = '/api/email-builder', headers = {}, fetch: fetchImpl } = {}) {\n const root = baseUrl.replace(/\\/+$/, '');\n const doFetch = fetchImpl || ((input, init) => fetch(input, init));\n const extraHeaders = () => (typeof headers === 'function' ? headers() : headers);\n\n /** @param {Response} res */\n async function unwrap(res) {\n const json = await res.json().catch(() => ({}));\n if (!res.ok || json.error) {\n throw new StorageError(json.error || `Request failed (HTTP ${res.status})`, res.status, json.code);\n }\n return json.data;\n }\n\n /** @param {string} path @param {RequestInit} [init] */\n async function call(path, init) {\n const res = await doFetch(`${root}${path}`, {\n ...init,\n headers: { 'Content-Type': 'application/json', ...extraHeaders(), ...(init?.headers || {}) },\n });\n return unwrap(res);\n }\n\n /** @param {SavePayload} payload */\n function body(payload) {\n return JSON.stringify({ ...payload, document: readDocument(payload.document) });\n }\n\n return {\n list: async () => call('/templates'),\n load: async (id) => withDocument(await call(`/templates/${encodeURIComponent(id)}`)),\n remove: async (id) => {\n await call(`/templates/${encodeURIComponent(id)}`, { method: 'DELETE' });\n },\n create: async (payload) => call('/templates', { method: 'POST', body: body(payload) }),\n duplicate: async (id) => call('/templates', { method: 'POST', body: JSON.stringify({ duplicateOf: id }) }),\n save: async (id, payload) => call(`/templates/${encodeURIComponent(id)}`, { method: 'PUT', body: body(payload) }),\n listVersions: async (id) => call(`/templates/${encodeURIComponent(id)}/versions`),\n getVersion: async (id, versionId) =>\n withDocument(await call(`/templates/${encodeURIComponent(id)}/versions/${encodeURIComponent(versionId)}`)),\n render: async (input) => call('/render', { method: 'POST', body: JSON.stringify(input) }),\n sendTest: async (input) => call('/test', { method: 'POST', body: JSON.stringify(input) }),\n listVariables: async () => call('/variables'),\n saveVariable: async (variable, { create = false } = {}) =>\n create\n ? call('/variables', { method: 'POST', body: JSON.stringify(variable) })\n : call(`/variables/${encodeURIComponent(String(variable.key))}`, { method: 'PUT', body: JSON.stringify(variable) }),\n deleteVariable: async (key) => {\n await call(`/variables/${encodeURIComponent(key)}`, { method: 'DELETE' });\n },\n async uploadImage(file) {\n assertUploadable(file);\n const form = new FormData();\n form.append('file', file, file.name || 'image');\n // No Content-Type: the browser sets the multipart boundary itself.\n const res = await doFetch(`${root}/assets`, { method: 'POST', body: form, headers: extraHeaders() });\n const data = await unwrap(res);\n return { path: data.path };\n },\n };\n}\n\n/**\n * In-memory storage, same contract. Documents are kept SERIALIZED.\n * `render` and `sendTest` cannot run in a browser (MJML compiles on the\n * server): pass implementations to enable the preview and test buttons.\n *\n * @param {{\n * render?: TemplateStorage['render'],\n * sendTest?: TemplateStorage['sendTest'],\n * assetsPath?: string,\n * systemVariables?: EmailVariable[],\n * }} [options] `systemVariables`: keys a custom variable may not take\n * @returns {TemplateStorage & {dump: () => object}}\n */\nexport function createMemoryStorage({ render, sendTest, assetsPath = DEFAULT_ASSETS_PATH, systemVariables = DEFAULT_VARIABLES } = {}) {\n /** @type {Map<string, any>} */\n const rows = new Map();\n /** @type {Map<string, any[]>} */\n const versions = new Map();\n /** @type {Map<string, Blob>} */\n const images = new Map();\n /** @type {Map<string, EmailVariable>} */\n const customVariables = new Map();\n let nextId = 1;\n let tick = Date.parse('2026-01-01T00:00:00.000Z');\n const now = () => new Date((tick += 1000)).toISOString();\n\n /** @param {any} row */\n function toTemplate(row) {\n return {\n id: row.id,\n name: row.name,\n description: row.description,\n subject: row.subject,\n preheader: row.preheader,\n revision: row.revision,\n document: readDocument(row.documentJson),\n mjml: row.mjml,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n }\n\n /** @param {any} row */\n function snapshot(row) {\n const list = versions.get(String(row.id)) || [];\n const entry = {\n id: list.length + 1,\n versionNumber: list.length + 1,\n name: row.name,\n subject: row.subject,\n createdBy: null,\n createdAt: row.revision,\n documentJson: row.documentJson,\n mjml: row.mjml,\n };\n versions.set(String(row.id), [...list, entry]);\n return { id: entry.id, versionNumber: entry.versionNumber };\n }\n\n /** @param {number|string} id */\n function rowOf(id) {\n const row = rows.get(String(id));\n if (!row) throw new StorageError('Template not found', 404, 'NOT_FOUND');\n return row;\n }\n\n /** @type {TemplateStorage & {dump: () => object}} */\n const storage = {\n async list() {\n return [...rows.values()]\n .sort((a, b) => (b.updatedAt || b.createdAt).localeCompare(a.updatedAt || a.createdAt))\n .map((row) => {\n const { document: _d, mjml: _m, ...summary } = toTemplate(row);\n return summary;\n });\n },\n async load(id) {\n return toTemplate(rowOf(id));\n },\n async remove(id) {\n rowOf(id);\n rows.delete(String(id));\n versions.delete(String(id));\n },\n async create(payload) {\n if (!payload.name?.trim()) throw new StorageError('Name required', 400, 'NAME_REQUIRED');\n const at = now();\n const row = {\n id: nextId++,\n name: payload.name.trim(),\n description: payload.description ?? null,\n subject: payload.subject ?? null,\n preheader: payload.preheader ?? null,\n documentJson: JSON.stringify(readDocument(payload.document)),\n mjml: payload.mjml,\n createdAt: at,\n updatedAt: null,\n revision: at,\n };\n rows.set(String(row.id), row);\n snapshot(row);\n return { template: toTemplate(row), warnings: [] };\n },\n async duplicate(id) {\n const source = rowOf(id);\n return storage.create({\n name: `${source.name} (copy)`,\n description: source.description,\n subject: source.subject,\n preheader: source.preheader,\n document: readDocument(source.documentJson),\n mjml: source.mjml,\n });\n },\n async save(id, payload) {\n const row = rowOf(id);\n if (payload.revision && payload.revision !== row.revision) {\n throw new StorageError('Template changed in the meantime — reload it before saving', 409, 'CONFLICT');\n }\n const at = now();\n Object.assign(row, {\n ...(payload.name !== undefined ? { name: payload.name } : {}),\n ...(payload.description !== undefined ? { description: payload.description } : {}),\n ...(payload.subject !== undefined ? { subject: payload.subject } : {}),\n ...(payload.preheader !== undefined ? { preheader: payload.preheader } : {}),\n documentJson: JSON.stringify(readDocument(payload.document)),\n mjml: payload.mjml,\n updatedAt: at,\n revision: at,\n });\n const version = payload.createVersion ? snapshot(row) : null;\n const { document: _omit, ...template } = toTemplate(row);\n return { template, warnings: [], version };\n },\n async listVersions(id) {\n rowOf(id);\n return [...(versions.get(String(id)) || [])].reverse().map(({ documentJson: _d, mjml: _m, ...v }) => v);\n },\n async getVersion(id, versionId) {\n const entry = (versions.get(String(id)) || []).find((v) => String(v.id) === String(versionId));\n if (!entry) throw new StorageError('Version not found', 404, 'NOT_FOUND');\n const { documentJson, ...version } = entry;\n return { ...version, document: readDocument(documentJson) };\n },\n async uploadImage(file) {\n assertUploadable(file);\n // Same key as the server: 32 hex characters of the hash + extension.\n const digest = await crypto.subtle.digest('SHA-256', await file.arrayBuffer());\n const hex = [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, '0')).join('');\n const path = `${assetsPath}${hex.slice(0, 32)}.${IMAGE_TYPES[file.type]}`;\n images.set(path, file);\n return { path };\n },\n async listVariables() {\n return [...customVariables.values()].map((v) => ({ ...v }));\n },\n async saveVariable(input, { create = false } = {}) {\n const existing = [...systemVariables, ...customVariables.values()];\n if (!create && !customVariables.has(String(input?.key))) {\n throw new StorageError('Variable not found', 404, 'NOT_FOUND');\n }\n const base = create ? {} : customVariables.get(String(input.key));\n const { variable, errors } = validateCustomVariable({ ...base, ...input }, { existing, editing: create ? null : input.key });\n if (errors) throw new StorageError(Object.values(errors)[0], 400, 'INVALID_VARIABLE');\n customVariables.set(variable.key, variable);\n return { ...variable };\n },\n async deleteVariable(key) {\n if (!customVariables.delete(String(key))) throw new StorageError('Variable not found', 404, 'NOT_FOUND');\n },\n ...(render ? { render } : {}),\n ...(sendTest ? { sendTest } : {}),\n dump: () => ({\n rows: [...rows.values()],\n versions: Object.fromEntries(versions),\n images: [...images.keys()],\n variables: [...customVariables.values()],\n }),\n };\n return storage;\n}\n","import { forwardRef } from 'react';\nimport { Label as LabelPrimitive } from 'radix-ui';\nimport { cn } from './cn.js';\n\n// forwardRef: React 18 does not pass `ref` as a prop.\nexport const Input = forwardRef(function Input({ className, type, ...props }, ref) {\n return (\n <input\n ref={ref}\n type={type}\n data-slot=\"input\"\n className={cn(\n 'eb:h-8 eb:w-full eb:min-w-0 eb:rounded-lg2 eb:border eb:border-border-strong eb:bg-surface-75 eb:px-3 eb:py-1 eb:text-[13px] eb:text-foreground eb:shadow-xs eb:transition-[color,box-shadow] eb:outline-none eb:placeholder:text-foreground-muted eb:selection:bg-primary eb:selection:text-primary-foreground eb:disabled:pointer-events-none eb:disabled:cursor-not-allowed eb:disabled:opacity-50',\n 'eb:focus-visible:border-ring eb:focus-visible:ring-[3px] eb:focus-visible:ring-ring/50',\n 'eb:aria-invalid:border-destructive eb:aria-invalid:ring-destructive/20',\n className\n )}\n {...props}\n />\n );\n});\n\nexport const Textarea = forwardRef(function Textarea({ className, ...props }, ref) {\n return (\n <textarea\n ref={ref}\n data-slot=\"textarea\"\n className={cn(\n 'eb:flex eb:field-sizing-content eb:min-h-16 eb:w-full eb:rounded-lg2 eb:border eb:border-border-strong eb:bg-surface-75 eb:px-3 eb:py-2 eb:text-[13px] eb:text-foreground eb:shadow-xs eb:transition-[color,box-shadow] eb:outline-none eb:placeholder:text-foreground-muted eb:focus-visible:border-ring eb:focus-visible:ring-[3px] eb:focus-visible:ring-ring/50 eb:aria-invalid:border-destructive eb:aria-invalid:ring-destructive/20 eb:disabled:cursor-not-allowed eb:disabled:opacity-50',\n className\n )}\n {...props}\n />\n );\n});\n\nexport function Label({ className, ...props }) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n 'eb:flex eb:items-center eb:gap-2 eb:text-[13px] eb:leading-none eb:font-medium eb:text-foreground eb:select-none eb:peer-disabled:cursor-not-allowed eb:peer-disabled:opacity-50',\n className\n )}\n {...props}\n />\n );\n}\n","import { useMemo, useState } from 'react';\nimport { AlertTriangle, CheckCircle2, Eye, Info, Loader2, Monitor, RefreshCw, Smartphone } from 'lucide-react';\nimport { EMAIL_MOBILE_WIDTH } from '../../core/constants.js';\nimport { FRAME_SCROLLBAR_CSS } from '../../core/scrollbars.js';\nimport { useUi } from '../../ui/context.jsx';\nimport { Button } from '../../ui/primitives/button.jsx';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/primitives/overlays.jsx';\nimport { SectionLabel, Tabs, TabsList, TabsTrigger } from '../../ui/primitives/misc.jsx';\nimport { cn } from '../../ui/primitives/cn.js';\n\n/**\n * PREVIEW of the FINAL email — rendered by the server, as it will be stored.\n *\n * The canvas already compiles in the browser; the preview goes through the\n * server compilation (the only one that counts), with sample values for the\n * variables, and lists the quality checks (unsubscribe link, alt texts, links,\n * Gmail clipping size) and the MJML warnings.\n *\n * The HTML is shown in an iframe with an EMPTY sandbox: no script, form,\n * navigation, nor same origin. An email is a complete HTML document: injected\n * into the page it would inherit the application's styles and lie.\n */\n\nconst LEVEL_ICON = { warning: AlertTriangle, info: Info };\n\nexport function QualityList({ quality = [], warnings = [] }) {\n const { t } = useUi();\n if (!quality.length && !warnings.length) {\n return (\n <p className=\"eb:flex eb:items-center eb:gap-1.5 eb:text-[12px] eb:text-foreground-lighter\">\n <CheckCircle2 className=\"eb:size-3.5 eb:text-success\" aria-hidden=\"true\" />\n {t('Nothing to fix.')}\n </p>\n );\n }\n return (\n <ul className=\"eb:space-y-1.5\" aria-label={t('Points to check')}>\n {quality.map((issue) => {\n const Icon = LEVEL_ICON[issue.level] || Info;\n return (\n <li key={issue.code} className=\"eb:flex eb:items-start eb:gap-1.5 eb:text-[12px] eb:text-foreground\">\n <Icon\n className={cn(\n 'eb:mt-0.5 eb:size-3.5 eb:shrink-0',\n issue.level === 'warning' ? 'eb:text-warning' : 'eb:text-foreground-muted'\n )}\n aria-hidden=\"true\"\n />\n {issue.message}\n </li>\n );\n })}\n {warnings.slice(0, 5).map((w, i) => (\n <li key={`mjml-${i}`} className=\"eb:flex eb:items-start eb:gap-1.5 eb:text-[12px] eb:text-foreground-lighter\">\n <Info className=\"eb:mt-0.5 eb:size-3.5 eb:shrink-0 eb:text-foreground-muted\" aria-hidden=\"true\" />\n MJML: {w.message}\n </li>\n ))}\n </ul>\n );\n}\n\n/** The builder's thin scrollbars inside the frame (see `core/scrollbars.js`). */\nconst PREVIEW_SCROLLBAR_CSS = `<style data-preview-scrollbar>${FRAME_SCROLLBAR_CSS}</style>`;\n\nconst withPreviewScrollbars = (html) =>\n !html ? '' : /<\\/head>/i.test(html) ? html.replace(/<\\/head>/i, `${PREVIEW_SCROLLBAR_CSS}</head>`) : PREVIEW_SCROLLBAR_CSS + html;\n\n/** Sandboxed preview frame, desktop or mobile width. */\nexport function EmailPreview({ html, loading = false, error = null, device = 'desktop', onDeviceChange, onRefresh, hint = true }) {\n const { t } = useUi();\n const isMobile = device === 'mobile';\n // `srcDoc`, not a blob URL: nothing to revoke when the HTML changes.\n const srcDoc = useMemo(() => withPreviewScrollbars(html), [html]);\n\n return (\n <div className=\"eb:flex eb:h-full eb:min-h-0 eb:flex-col\">\n <div className=\"eb:mb-2 eb:flex eb:shrink-0 eb:items-center eb:justify-between eb:gap-2\">\n {/* The same switch as the editor's toolbar. */}\n <Tabs value={device} onValueChange={(value) => onDeviceChange?.(value)}>\n <TabsList aria-label={t('Device')}>\n <TabsTrigger value=\"desktop\">\n <Monitor />\n {t('Desktop')}\n </TabsTrigger>\n <TabsTrigger value=\"mobile\">\n <Smartphone />\n {t('Mobile')}\n </TabsTrigger>\n </TabsList>\n </Tabs>\n {onRefresh && (\n <Button variant=\"outline\" size=\"sm-compact\" onClick={onRefresh} disabled={loading}>\n {loading ? <Loader2 className=\"eb:animate-spin\" /> : <RefreshCw />}\n {t('Refresh')}\n </Button>\n )}\n </div>\n\n <div className=\"eb:min-h-0 eb:flex-1 eb:overflow-auto eb:rounded-lg2 eb:border eb:border-border eb:bg-surface-75 eb:p-3\">\n {error ? (\n <div className=\"eb:flex eb:h-full eb:items-center eb:justify-center eb:p-6 eb:text-center eb:text-[13px] eb:text-destructive\">{error}</div>\n ) : !srcDoc ? (\n <div className=\"eb:flex eb:h-full eb:items-center eb:justify-center eb:p-6 eb:text-center eb:text-[13px] eb:text-foreground-lighter\">\n {loading ? t('Rendering…') : t('Nothing to show yet.')}\n </div>\n ) : (\n // Narrows and widens like the editor's canvas (GrapesJS: width .35s ease).\n <div\n className={cn(\n 'eb:mx-auto eb:max-w-full eb:bg-white eb:transition-[width,box-shadow] eb:duration-[350ms] eb:ease-in-out eb:motion-reduce:transition-none',\n isMobile && 'eb:shadow-sm'\n )}\n style={{ width: isMobile ? EMAIL_MOBILE_WIDTH : '100%' }}\n data-device={device}\n >\n <iframe\n sandbox=\"\"\n srcDoc={srcDoc}\n title={t('Email preview')}\n className=\"eb:block eb:w-full eb:border-0 eb:bg-white eb:transition-[height] eb:duration-[350ms] eb:ease-in-out eb:motion-reduce:transition-none\"\n style={{ height: isMobile ? 760 : 900 }}\n />\n </div>\n )}\n </div>\n\n {hint && (\n <p className=\"eb:mt-2 eb:shrink-0 eb:text-[11px] eb:leading-relaxed eb:text-foreground-lighter\">\n {t('Indicative preview — check it with “Send test”.')}\n </p>\n )}\n </div>\n );\n}\n\nexport default function PreviewButton({ context }) {\n const { editor, ready, meta, storage } = context;\n const { t } = useUi();\n const [open, setOpen] = useState(false);\n const [device, setDevice] = useState('desktop');\n const [state, setState] = useState({ loading: false, html: '', subject: null, preheader: null, warnings: [], quality: [], error: null });\n\n const refresh = async () => {\n setState((s) => ({ ...s, loading: true, error: null }));\n try {\n const data = await storage.render({ mjml: editor.exportMjml(), subject: meta.subject, preheader: meta.preheader });\n setState({\n loading: false,\n html: data.html,\n // Subject and preview text with their variables filled, when the backend returns them.\n subject: data.subject ?? null,\n preheader: data.preheader ?? null,\n warnings: data.warnings || [],\n quality: data.quality || [],\n error: null,\n });\n } catch (error) {\n setState({ loading: false, html: '', subject: null, preheader: null, warnings: [], quality: [], error: error.message });\n }\n };\n\n return (\n <>\n <Button\n variant=\"outline\"\n size=\"sm-compact\"\n disabled={!ready}\n onClick={() => {\n setOpen(true);\n refresh();\n }}\n >\n <Eye />\n {t('Preview')}\n </Button>\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogContent className=\"eb:flex eb:h-[85vh] eb:max-h-[85vh] eb:flex-col eb:gap-4 eb:sm:max-w-[67.2rem]\">\n <DialogHeader>\n <div className=\"eb:flex eb:items-center eb:gap-3\">\n <span className=\"eb:flex eb:size-10 eb:shrink-0 eb:items-center eb:justify-center eb:rounded-lg2 eb:bg-primary/10 eb:text-primary\">\n <Eye className=\"eb:size-5\" />\n </span>\n <div>\n <DialogTitle className=\"eb:text-base eb:font-normal\">{t('Email preview')}</DialogTitle>\n <DialogDescription className=\"eb:text-[13px]\">{t('Final rendering, variables filled with samples.')}</DialogDescription>\n </div>\n </div>\n </DialogHeader>\n <div className=\"eb:grid eb:min-h-0 eb:flex-1 eb:grid-cols-1 eb:gap-4 eb:md:grid-cols-[minmax(0,1fr)_260px]\">\n <EmailPreview\n html={state.html}\n loading={state.loading}\n error={state.error}\n device={device}\n onDeviceChange={setDevice}\n onRefresh={refresh}\n // The reminder points to \"Send test\": only when it exists.\n hint={typeof storage.sendTest === 'function'}\n />\n <aside className=\"eb:min-h-0 eb:space-y-5 eb:overflow-y-auto\" aria-busy={state.loading}>\n <section className=\"eb:space-y-2\">\n <SectionLabel>{t('Inbox')}</SectionLabel>\n <div className=\"eb:rounded-lg2 eb:border eb:border-border eb:bg-surface-75 eb:px-3 eb:py-2.5\">\n <p className=\"eb:text-[13px] eb:font-medium eb:text-foreground\">{(state.subject ?? meta.subject) || t('No subject')}</p>\n <p className=\"eb:text-[12px] eb:text-foreground-muted\">{(state.preheader ?? meta.preheader) || t('No preview text')}</p>\n </div>\n </section>\n <section className=\"eb:space-y-2\">\n <SectionLabel>{t('To check')}</SectionLabel>\n {!state.loading && !state.error && <QualityList quality={state.quality} warnings={state.warnings} />}\n </section>\n </aside>\n </div>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n","// @ts-check\n/**\n * Scrollbars inside the builder's frames (the GrapesJS canvas, the preview),\n * the same as in the rest of the builder: a 5.6 px gutter, a 2.8 px thumb,\n * no arrows, shown only while the pointer is over the scrolling block. A frame is a\n * document of its own, so `styles.css` does not reach it — the same rules\n * are injected into it. Added to the canvas and the preview only, never to\n * the HTML that is saved or sent.\n *\n * Chromium ≥ 121 drops `::-webkit-scrollbar` (and brings back the arrows)\n * as soon as `scrollbar-width` or `scrollbar-color` is set, so those two are\n * kept for Firefox alone.\n */\nexport const FRAME_SCROLLBAR_CSS = `\n::-webkit-scrollbar{width:5.6px;height:5.6px;background:transparent}\n::-webkit-scrollbar-button{display:none;width:0;height:0}\n::-webkit-scrollbar-track,::-webkit-scrollbar-track-piece,::-webkit-scrollbar-corner{background:transparent;border:0;box-shadow:none}\n::-webkit-scrollbar-thumb{background-color:rgba(156,163,175,.45);border:1.4px solid transparent;background-clip:content-box;border-radius:9999px;min-height:2rem;min-width:2rem}\n::-webkit-scrollbar-thumb:hover{background-color:rgba(107,114,128,.7)}\n@supports not selector(::-webkit-scrollbar){*{scrollbar-width:thin;scrollbar-color:rgba(156,163,175,.45) transparent}}\n@media (hover:hover) and (pointer:fine){\n::-webkit-scrollbar-thumb{background-color:transparent}\n*:hover::-webkit-scrollbar-thumb{background-color:rgba(156,163,175,.45)}\n*:hover::-webkit-scrollbar-thumb:hover{background-color:rgba(107,114,128,.7)}\n@supports not selector(::-webkit-scrollbar){*{scrollbar-color:transparent transparent}*:hover{scrollbar-color:rgba(156,163,175,.45) transparent}}\n}`;\n","'use client';\n\nimport { useEffect, useState } from 'react';\n\n/**\n * Layout of the builder from the width of ITS OWN box, not of the window: the\n * builder is embedded in host pages (a side panel, a modal, a phone), and its\n * room is what counts.\n *\n * wide ≥ 1180 px blocks, canvas and properties side by side;\n * medium ≥ 760 px blocks beside the canvas, properties in a drawer;\n * narrow < 760 px the canvas alone, blocks and properties in drawers.\n *\n * Before the first measure (server rendering, first paint) the layout is\n * `wide`, the desktop one.\n */\n\nexport const LAYOUT_BREAKPOINTS = { wide: 1180, medium: 760 };\n\n/** @param {number} width @returns {'wide'|'medium'|'narrow'} */\nexport function layoutFor(width) {\n if (width >= LAYOUT_BREAKPOINTS.wide) return 'wide';\n if (width >= LAYOUT_BREAKPOINTS.medium) return 'medium';\n return 'narrow';\n}\n\n/** @param {{current: HTMLElement|null}} ref */\nexport function useLayoutWidth(ref) {\n const [layout, setLayout] = useState(/** @type {'wide'|'medium'|'narrow'} */ ('wide'));\n useEffect(() => {\n const el = ref.current;\n if (!el || typeof ResizeObserver === 'undefined') return undefined;\n const measure = () => setLayout(layoutFor(el.getBoundingClientRect().width));\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(el);\n return () => observer.disconnect();\n }, [ref]);\n return layout;\n}\n"],"mappings":"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","names":["jsx","jsx","jsxs","jsx","jsxs","options","jsx","Input","Textarea","useMemo","useState","CheckCircle2","Info","jsx","jsxs","Info","CheckCircle2","useMemo","useState","useEffect","useState"]}
|