@stackone/malachite 2.75.0 → 2.77.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/COMPONENTS.md +5 -5
- package/dist/components/Alert.js +139 -100
- package/dist/components/Alert.js.map +1 -1
- package/dist/components/BaseFormComponent.js +67 -57
- package/dist/components/BaseFormComponent.js.map +1 -1
- package/dist/components/Modal.js +137 -120
- package/dist/components/Modal.js.map +1 -1
- package/dist/components/SidePanel.js +204 -145
- package/dist/components/SidePanel.js.map +1 -1
- package/dist/components/Stepper.js +100 -34
- package/dist/components/Stepper.js.map +1 -1
- package/dist/components/ToastItem.js +1 -1
- package/dist/components/ToastItem.js.map +1 -1
- package/dist/index.d.ts +69 -6
- package/dist/tailwind.css.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Modal.js","sources":["../../src/components/Modal.tsx"],"sourcesContent":["import type React from 'react';\nimport { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ShadowRootWrapper } from '../ShadowRootWrapper';\nimport type { AlertType } from './Alert';\nimport CalloutStrip from './CalloutStrip';\nimport DismissIcon from './CustomIcons/DismissIcon';\nimport type { RenderLink } from './PageLayout/types';\nimport { getDeepActiveElement } from './activeElement';\nimport { GLASS_SURFACE_STYLE } from './glassSurface';\nimport { MODAL_TRAY_BACKGROUND, MODAL_TRAY_CAPTION_COLOR, type ModalTrayTone } from './modalTray';\nimport { OVERLAY_ICON_BUTTON_CLASSES, useOverlayBehaviour } from './overlayBehaviour';\nimport { OVERLAY_ELEVATED_ATTR, overlayIdentity } from './portalOverlay';\n\nexport type ModalSize = 'small' | 'medium' | 'large';\n\n/** Widths keyed to the size union — a raw `width` prop would let a consumer off the scale. */\nconst SIZE_MAX_WIDTH: Record<ModalSize, string> = {\n small: '420px',\n medium: '612px',\n large: '760px',\n};\n\nconst TRANSITION_MS = 200;\n\n// A basis of its own: a `flex-1` body's zero basis would override the height in Chrome.\nconst TALL_BODY = 'flex-[0_1_auto] h-[min(600px,calc(100dvh-160px))]';\n\nexport interface ModalProps {\n open: boolean;\n /** Dismiss handler — close button, ESC, or overlay click. */\n onClose: () => void;\n title: React.ReactNode;\n /** Secondary line beneath the title. */\n subtitle?: React.ReactNode;\n /** Leading header slot, typically an icon or logo. */\n icon?: React.ReactNode;\n /** Content pinned right in the header, before the close button. */\n headerExtra?: React.ReactNode;\n titleAdornment?: React.ReactNode;\n tray?: { tone?: ModalTrayTone; caption?: { label?: string; message: string } };\n /** Divider under the header. Default: false. */\n headerDivider?: boolean;\n /** Pinned action row below the scrolling body. */\n footer?: React.ReactNode;\n size?: ModalSize;\n /** Default: true. */\n showCloseButton?: boolean;\n /** Default: true. Turn off for a dialog whose choice must be made deliberately. */\n closeOnOverlayClick?: boolean;\n /** Whether the body gets default padding. Default: true. */\n bodyPadding?: boolean;\n /** `tall`: 600px, or the viewport less 160px, for content that sizes to its box. */\n bodyHeight?: 'auto' | 'tall';\n /** Full-width Alert bands at the top of the body, above `children`, in order. Unaffected by\n * `bodyPadding`, and announced ahead of the dialog's description. The message is markdown. */\n callouts?: { type?: AlertType; message: string }[];\n /** Routes root-relative links in `callouts` through the app's router; see `MarkdownBlock`. */\n renderLink?: RenderLink;\n /**\n * `alertdialog` for a dialog interrupting the user over a consequential choice — it\n * tells assistive tech to announce the body, not just the name.\n */\n role?: 'dialog' | 'alertdialog';\n /** Accessible dialog name; required when `title` isn't a plain string. */\n 'aria-label'?: string;\n /** ID of a visible element naming the dialog (alternative to `aria-label`). */\n 'aria-labelledby'?: string;\n /** ID of the element describing what the dialog is asking. */\n 'aria-describedby'?: string;\n /**\n * Work is in flight: suppresses the pointer dismissal routes and announces the busy\n * state. Never ESC — that is the only guaranteed keyboard exit from a focus trap, so it\n * always reaches `onClose` and whether to abort is left to the caller.\n */\n busy?: boolean;\n children: React.ReactNode;\n}\n\nconst Modal: React.FC<ModalProps> = ({\n open,\n onClose,\n title,\n subtitle,\n icon,\n headerExtra,\n titleAdornment,\n tray,\n headerDivider = false,\n footer,\n size = 'medium',\n showCloseButton = true,\n closeOnOverlayClick = true,\n bodyPadding = true,\n bodyHeight = 'auto',\n callouts,\n renderLink,\n role = 'dialog',\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n busy = false,\n children,\n}) => {\n const captionId = useId();\n const calloutId = useId();\n const shownCallouts = callouts?.filter((callout) => callout.message.trim()) ?? [];\n const [isVisible, setIsVisible] = useState(false);\n // Starts false even when `open` does: portals are unsupported on the server, so the\n // dialog must reach `document.body` from the client effect below and nowhere else.\n const [isMounted, setIsMounted] = useState(false);\n // Distinct from `!isVisible`, which is also false on the frame the dialog opens.\n const [isExiting, setIsExiting] = useState(false);\n const panelRef = useRef<HTMLElement | null>(null);\n const frameRef = useRef<number | null>(null);\n const unmountTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const busyRef = useRef(busy);\n const onCloseRef = useRef(onClose);\n useEffect(() => {\n busyRef.current = busy;\n onCloseRef.current = onClose;\n }, [busy, onClose]);\n\n // Pointer routes only. Removing ESC too would leave a focus-trapped keyboard user no\n // exit while a request hangs (WCAG 2.1.2), so ESC always reaches onClose.\n const dismissByPointer = useCallback(() => {\n if (!busyRef.current) {\n onCloseRef.current();\n }\n }, []);\n const hostRef = useRef<HTMLDivElement | null>(null);\n // No prop of its own: it stays in the base band unless a SidePanel elevated the stack,\n // and follows it up when one has.\n const {\n ref: takePanelRef,\n isTopmost,\n zIndex,\n elevated,\n } = useOverlayBehaviour({\n open,\n onClose,\n hostRef,\n });\n const handlePanelRef = useCallback(\n (node: HTMLElement | null) => {\n panelRef.current = node;\n takePanelRef(node);\n },\n [takePanelRef],\n );\n\n // Mounted outlives `open` by one transition, so the dialog can animate out.\n useEffect(() => {\n if (open) {\n setIsMounted(true);\n setIsExiting(false);\n if (unmountTimerRef.current) {\n clearTimeout(unmountTimerRef.current);\n unmountTimerRef.current = null;\n }\n frameRef.current = requestAnimationFrame(() => {\n frameRef.current = null;\n setIsVisible(true);\n });\n } else {\n // A browser refuses `aria-hidden` on a subtree still holding focus, so the\n // attribute waits for this point — after useOverlayBehaviour's cleanup has\n // returned focus to the trigger — and blurs what is left if the trigger has gone.\n const active = getDeepActiveElement();\n if (active && panelRef.current?.contains(active)) {\n active.blur();\n }\n setIsExiting(true);\n setIsVisible(false);\n unmountTimerRef.current = setTimeout(() => {\n unmountTimerRef.current = null;\n setIsMounted(false);\n }, TRANSITION_MS);\n }\n return () => {\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current);\n frameRef.current = null;\n }\n if (unmountTimerRef.current) {\n clearTimeout(unmountTimerRef.current);\n unmountTimerRef.current = null;\n }\n };\n }, [open]);\n\n if (!isMounted) {\n return null;\n }\n\n return createPortal(\n // Host carries the stacking context — ShadowRootWrapper's `isolation` would otherwise\n // flatten our z-index. Not promoted to the top layer, so host dialogs can cover us.\n <ShadowRootWrapper\n hostRef={hostRef}\n hostStyle={{ position: 'relative', zIndex }}\n hostProps={\n elevated\n ? { ...overlayIdentity('modal'), [OVERLAY_ELEVATED_ATTR]: '' }\n : overlayIdentity('modal')\n }\n >\n {/* The exit transition outlives `open`, so a closed-but-mounted dialog has to stop\n taking clicks and leave the a11y tree — a faded opacity does neither. */}\n <div\n className={`fixed inset-0 z-[1000] flex items-center justify-center p-[16px] ${\n open ? '' : 'pointer-events-none'\n }`}\n >\n <div\n aria-hidden=\"true\"\n onClick={closeOnOverlayClick ? dismissByPointer : undefined}\n className={`absolute inset-0 bg-[var(--malachite-overlay-scrim)] transition-opacity duration-200 ease-in-out ${\n isVisible ? 'opacity-100' : 'opacity-0'\n }`}\n />\n <div\n ref={handlePanelRef}\n role={role}\n aria-hidden={isExiting ? 'true' : undefined}\n aria-modal={isTopmost ? 'true' : undefined}\n aria-describedby={\n [\n ...shownCallouts.map((_, index) => `${calloutId}-${index}`),\n ariaDescribedBy,\n tray?.caption ? captionId : null,\n ]\n .filter(Boolean)\n .join(' ') || undefined\n }\n aria-busy={busy || undefined}\n tabIndex={-1}\n aria-label={\n ariaLabelledBy\n ? undefined\n : (ariaLabel ?? (typeof title === 'string' ? title : undefined))\n }\n aria-labelledby={ariaLabelledBy}\n className={\n tray\n ? 'relative flex max-h-full w-full flex-col gap-[4px] rounded-[20px] p-[4px] text-[var(--malachite-card-foreground)] outline-none [box-shadow:var(--malachite-shadow-glow,var(--malachite-shadow-lg))]'\n : 'relative flex max-h-full w-full flex-col overflow-hidden rounded-[20px] border border-solid border-[var(--malachite-card-border)] bg-[var(--malachite-card-background)] text-[var(--malachite-card-foreground)] outline-none [box-shadow:var(--malachite-shadow-glow,var(--malachite-shadow-lg))]'\n }\n style={{\n maxWidth: tray\n ? `calc(${SIZE_MAX_WIDTH[size]} + 8px)`\n : SIZE_MAX_WIDTH[size],\n ...(tray\n ? {\n backgroundColor: MODAL_TRAY_BACKGROUND[tray.tone ?? 'neutral'],\n }\n : {}),\n // Inline: Tailwind scale/translate utilities silently break inside\n // shadow roots (see CLAUDE.md Shadow DOM caveats).\n transform: isVisible ? 'scale(1)' : 'scale(0.96)',\n opacity: isVisible ? 1 : 0,\n transition: `transform ${TRANSITION_MS}ms ease-out, opacity ${TRANSITION_MS}ms ease-out`,\n }}\n >\n <div\n className={\n tray\n ? 'flex min-h-0 flex-col overflow-hidden rounded-[16px] border border-solid border-[var(--malachite-card-border)] bg-[var(--malachite-card-background)] [box-shadow:var(--malachite-shadow-glow-lg,var(--malachite-shadow-xl))]'\n : 'contents'\n }\n >\n <div\n className={`flex gap-[20px] p-[20px] ${\n subtitle ? 'items-start' : 'items-center'\n } ${\n headerDivider\n ? 'border-0 border-b border-solid border-[var(--malachite-card-border)]'\n : ''\n }`}\n >\n <div className=\"flex h-[18px] min-w-0 flex-1 items-center gap-[12px]\">\n <div className=\"flex min-w-0 items-center gap-[8px]\">\n {icon ? (\n <span className=\"flex shrink-0 items-center\">{icon}</span>\n ) : null}\n <div className=\"flex min-w-0 flex-col gap-[4px]\">\n <span className=\"truncate text-[14px] font-medium leading-[1.25] tracking-[-0.14px] text-[var(--malachite-text-primary)]\">\n {title}\n </span>\n {subtitle ? (\n <span className=\"text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]\">\n {subtitle}\n </span>\n ) : null}\n </div>\n </div>\n {titleAdornment ? (\n <>\n <span\n aria-hidden=\"true\"\n className=\"h-[12px] w-px shrink-0 bg-[var(--malachite-card-border)]\"\n />\n <span className=\"flex min-w-0 items-center overflow-hidden\">\n {titleAdornment}\n </span>\n </>\n ) : null}\n </div>\n {headerExtra ? (\n <span className=\"flex shrink-0 items-center\">{headerExtra}</span>\n ) : null}\n {showCloseButton ? (\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={dismissByPointer}\n disabled={busy}\n className={OVERLAY_ICON_BUTTON_CLASSES}\n >\n <DismissIcon size={10} />\n </button>\n ) : null}\n </div>\n <div\n className={`min-h-0 ${bodyHeight === 'tall' ? TALL_BODY : 'flex-1'} overflow-y-auto ${\n bodyPadding && shownCallouts.length === 0 ? 'px-[20px]' : ''\n }`}\n >\n {shownCallouts.map((callout, index) => (\n <CalloutStrip\n key={index}\n id={`${calloutId}-${index}`}\n type={callout.type}\n message={callout.message}\n renderLink={renderLink}\n />\n ))}\n {bodyPadding ? (\n <div\n className={\n shownCallouts.length > 0\n ? 'px-[20px] pt-[18px] pb-[20px]'\n : `pb-[20px] ${headerDivider ? 'pt-[18px]' : ''}`\n }\n >\n {children}\n </div>\n ) : (\n children\n )}\n </div>\n {footer ? (\n <div\n className=\"flex min-h-[56px] shrink-0 items-center border-0 border-t border-solid border-[var(--malachite-card-border)] px-[12px]\"\n style={GLASS_SURFACE_STYLE}\n >\n {footer}\n </div>\n ) : null}\n </div>\n {tray?.caption ? (\n <div\n id={captionId}\n className=\"flex h-[48px] shrink-0 items-center justify-center px-[16px] text-[13px] tracking-[0.13px]\"\n style={{ color: MODAL_TRAY_CAPTION_COLOR[tray.tone ?? 'neutral'] }}\n >\n <span>\n {tray.caption.label ? (\n <>\n <span className=\"font-medium\">\n {tray.caption.label}\n </span>{' '}\n </>\n ) : null}\n {tray.caption.message}\n </span>\n </div>\n ) : null}\n </div>\n </div>\n </ShadowRootWrapper>,\n document.body,\n );\n};\n\nexport default Modal;\nexport { Modal };\n"],"names":["SIZE_MAX_WIDTH","TRANSITION_MS","TALL_BODY","Modal","open","onClose","title","subtitle","icon","headerExtra","titleAdornment","tray","headerDivider","footer","size","showCloseButton","closeOnOverlayClick","bodyPadding","bodyHeight","callouts","renderLink","role","ariaLabel","ariaLabelledBy","ariaDescribedBy","busy","children","captionId","useId","calloutId","shownCallouts","callout","isVisible","setIsVisible","useState","isMounted","setIsMounted","isExiting","setIsExiting","panelRef","useRef","frameRef","unmountTimerRef","busyRef","onCloseRef","useEffect","dismissByPointer","useCallback","hostRef","takePanelRef","isTopmost","zIndex","elevated","useOverlayBehaviour","handlePanelRef","node","active","getDeepActiveElement","_a","createPortal","jsx","ShadowRootWrapper","overlayIdentity","OVERLAY_ELEVATED_ATTR","jsxs","_","index","MODAL_TRAY_BACKGROUND","Fragment","OVERLAY_ICON_BUTTON_CLASSES","DismissIcon","CalloutStrip","GLASS_SURFACE_STYLE","MODAL_TRAY_CAPTION_COLOR"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Modal.js","sources":["../../src/components/Modal.tsx"],"sourcesContent":["import type React from 'react';\nimport { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ShadowRootWrapper } from '../ShadowRootWrapper';\nimport type { AlertType } from './Alert';\nimport CalloutStrip from './CalloutStrip';\nimport DismissIcon from './CustomIcons/DismissIcon';\nimport type { RenderLink } from './PageLayout/types';\nimport { getDeepActiveElement } from './activeElement';\nimport { GLASS_SURFACE_STYLE } from './glassSurface';\nimport { MODAL_TRAY_BACKGROUND, MODAL_TRAY_CAPTION_COLOR, type ModalTrayTone } from './modalTray';\nimport { OVERLAY_ICON_BUTTON_CLASSES, useOverlayBehaviour } from './overlayBehaviour';\nimport { OVERLAY_ELEVATED_ATTR, overlayIdentity } from './portalOverlay';\n\n/** `fullscreen` fills the window, inside the overlay's margin, in both directions. */\nexport type ModalSize = 'small' | 'medium' | 'large' | 'fullscreen';\nexport type ModalSurface = 'card' | 'none';\n\n/** Widths keyed to the size union — a raw `width` prop would let a consumer off the scale. */\nconst SIZE_MAX_WIDTH: Record<ModalSize, string> = {\n small: '420px',\n medium: '612px',\n large: '760px',\n fullscreen: '100%',\n};\n\nconst TRANSITION_MS = 200;\n\n// A basis of its own: a `flex-1` body's zero basis would override the height in Chrome.\nconst TALL_BODY = 'flex-[0_1_auto] h-[min(600px,calc(100dvh-160px))]';\n\nexport interface ModalProps {\n open: boolean;\n /** Dismiss handler — close button, ESC, or overlay click. */\n onClose: () => void;\n title: React.ReactNode;\n /** Secondary line beneath the title. */\n subtitle?: React.ReactNode;\n /** Leading header slot, typically an icon or logo. */\n icon?: React.ReactNode;\n /** Content pinned right in the header, before the close button. */\n headerExtra?: React.ReactNode;\n titleAdornment?: React.ReactNode;\n tray?: { tone?: ModalTrayTone; caption?: { label?: string; message: string } };\n /** Divider under the header. Default: false. */\n headerDivider?: boolean;\n /** Pinned action row below the scrolling body. */\n footer?: React.ReactNode;\n size?: ModalSize;\n /**\n * `none` draws no card: no header, close button, footer, callouts or tray, only the\n * overlay and a scroll body around content that brings its own chrome, such as the Hub.\n * `title` then only names the dialog for assistive tech. Default: `card`.\n */\n surface?: ModalSurface;\n /** Default: true. */\n showCloseButton?: boolean;\n /** Default: true. Turn off for a dialog whose choice must be made deliberately. */\n closeOnOverlayClick?: boolean;\n /** Whether the body gets default padding. Default: true. */\n bodyPadding?: boolean;\n /** `tall`: 600px, or the viewport less 160px, for content that sizes to its box. */\n bodyHeight?: 'auto' | 'tall';\n /** Full-width Alert bands at the top of the body, above `children`, in order. Unaffected by\n * `bodyPadding`, and announced ahead of the dialog's description. The message is markdown. */\n callouts?: { type?: AlertType; message: string }[];\n /** Routes root-relative links in `callouts` through the app's router; see `MarkdownBlock`. */\n renderLink?: RenderLink;\n /**\n * `alertdialog` for a dialog interrupting the user over a consequential choice — it\n * tells assistive tech to announce the body, not just the name.\n */\n role?: 'dialog' | 'alertdialog';\n /** Accessible dialog name; required when `title` isn't a plain string. */\n 'aria-label'?: string;\n /** ID of a visible element naming the dialog (alternative to `aria-label`). */\n 'aria-labelledby'?: string;\n /** ID of the element describing what the dialog is asking. */\n 'aria-describedby'?: string;\n /**\n * Work is in flight: suppresses the pointer dismissal routes and announces the busy\n * state. Never ESC — that is the only guaranteed keyboard exit from a focus trap, so it\n * always reaches `onClose` and whether to abort is left to the caller.\n */\n busy?: boolean;\n children: React.ReactNode;\n}\n\nconst Modal: React.FC<ModalProps> = ({\n open,\n onClose,\n title,\n subtitle,\n icon,\n headerExtra,\n titleAdornment,\n tray: trayProp,\n headerDivider = false,\n footer,\n size = 'medium',\n surface = 'card',\n showCloseButton = true,\n closeOnOverlayClick = true,\n bodyPadding = true,\n bodyHeight = 'auto',\n callouts,\n renderLink,\n role = 'dialog',\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n busy = false,\n children,\n}) => {\n const captionId = useId();\n const calloutId = useId();\n const isBare = surface === 'none';\n // A bare dialog has no card to ring or caption, so the tray is not drawn either.\n const tray = isBare ? undefined : trayProp;\n const shownCallouts =\n (isBare ? undefined : callouts)?.filter((callout) => callout.message.trim()) ?? [];\n const [isVisible, setIsVisible] = useState(false);\n // Starts false even when `open` does: portals are unsupported on the server, so the\n // dialog must reach `document.body` from the client effect below and nowhere else.\n const [isMounted, setIsMounted] = useState(false);\n // Distinct from `!isVisible`, which is also false on the frame the dialog opens.\n const [isExiting, setIsExiting] = useState(false);\n const panelRef = useRef<HTMLElement | null>(null);\n const frameRef = useRef<number | null>(null);\n const unmountTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const busyRef = useRef(busy);\n const onCloseRef = useRef(onClose);\n useEffect(() => {\n busyRef.current = busy;\n onCloseRef.current = onClose;\n }, [busy, onClose]);\n\n // Pointer routes only. Removing ESC too would leave a focus-trapped keyboard user no\n // exit while a request hangs (WCAG 2.1.2), so ESC always reaches onClose.\n const dismissByPointer = useCallback(() => {\n if (!busyRef.current) {\n onCloseRef.current();\n }\n }, []);\n const hostRef = useRef<HTMLDivElement | null>(null);\n // No prop of its own: it stays in the base band unless a SidePanel elevated the stack,\n // and follows it up when one has.\n const {\n ref: takePanelRef,\n isTopmost,\n zIndex,\n elevated,\n } = useOverlayBehaviour({\n open,\n onClose,\n hostRef,\n });\n const handlePanelRef = useCallback(\n (node: HTMLElement | null) => {\n panelRef.current = node;\n takePanelRef(node);\n },\n [takePanelRef],\n );\n\n // Mounted outlives `open` by one transition, so the dialog can animate out.\n useEffect(() => {\n if (open) {\n setIsMounted(true);\n setIsExiting(false);\n if (unmountTimerRef.current) {\n clearTimeout(unmountTimerRef.current);\n unmountTimerRef.current = null;\n }\n frameRef.current = requestAnimationFrame(() => {\n frameRef.current = null;\n setIsVisible(true);\n });\n } else {\n // A browser refuses `aria-hidden` on a subtree still holding focus, so the\n // attribute waits for this point — after useOverlayBehaviour's cleanup has\n // returned focus to the trigger — and blurs what is left if the trigger has gone.\n const active = getDeepActiveElement();\n if (active && panelRef.current?.contains(active)) {\n active.blur();\n }\n setIsExiting(true);\n setIsVisible(false);\n unmountTimerRef.current = setTimeout(() => {\n unmountTimerRef.current = null;\n setIsMounted(false);\n }, TRANSITION_MS);\n }\n return () => {\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current);\n frameRef.current = null;\n }\n if (unmountTimerRef.current) {\n clearTimeout(unmountTimerRef.current);\n unmountTimerRef.current = null;\n }\n };\n }, [open]);\n\n if (!isMounted) {\n return null;\n }\n\n let panelClassName =\n 'relative flex max-h-full w-full flex-col overflow-hidden rounded-[20px] border border-solid border-[var(--malachite-card-border)] bg-[var(--malachite-card-background)] text-[var(--malachite-card-foreground)] outline-none [box-shadow:var(--malachite-shadow-glow,var(--malachite-shadow-lg))]';\n if (isBare) {\n panelClassName = 'relative flex max-h-full w-full flex-col outline-none';\n } else if (tray) {\n panelClassName =\n 'relative flex max-h-full w-full flex-col gap-[4px] rounded-[20px] p-[4px] text-[var(--malachite-card-foreground)] outline-none [box-shadow:var(--malachite-shadow-glow,var(--malachite-shadow-lg))]';\n }\n\n return createPortal(\n // Host carries the stacking context — ShadowRootWrapper's `isolation` would otherwise\n // flatten our z-index. Not promoted to the top layer, so host dialogs can cover us.\n <ShadowRootWrapper\n hostRef={hostRef}\n hostStyle={{ position: 'relative', zIndex }}\n hostProps={\n elevated\n ? { ...overlayIdentity('modal'), [OVERLAY_ELEVATED_ATTR]: '' }\n : overlayIdentity('modal')\n }\n >\n {/* The exit transition outlives `open`, so a closed-but-mounted dialog has to stop\n taking clicks and leave the a11y tree — a faded opacity does neither. */}\n <div\n className={`fixed inset-0 z-[1000] flex items-center justify-center p-[16px] ${\n open ? '' : 'pointer-events-none'\n }`}\n >\n <div\n aria-hidden=\"true\"\n onClick={closeOnOverlayClick ? dismissByPointer : undefined}\n className={`absolute inset-0 bg-[var(--malachite-overlay-scrim)] transition-opacity duration-200 ease-in-out ${\n isVisible ? 'opacity-100' : 'opacity-0'\n }`}\n />\n <div\n ref={handlePanelRef}\n role={role}\n aria-hidden={isExiting ? 'true' : undefined}\n aria-modal={isTopmost ? 'true' : undefined}\n aria-describedby={\n [\n ...shownCallouts.map((_, index) => `${calloutId}-${index}`),\n ariaDescribedBy,\n tray?.caption ? captionId : null,\n ]\n .filter(Boolean)\n .join(' ') || undefined\n }\n aria-busy={busy || undefined}\n tabIndex={-1}\n aria-label={\n ariaLabelledBy\n ? undefined\n : (ariaLabel ?? (typeof title === 'string' ? title : undefined))\n }\n aria-labelledby={ariaLabelledBy}\n className={panelClassName}\n style={{\n maxWidth: tray\n ? `calc(${SIZE_MAX_WIDTH[size]} + 8px)`\n : SIZE_MAX_WIDTH[size],\n ...(size === 'fullscreen' ? { height: '100%' } : {}),\n ...(tray\n ? {\n backgroundColor: MODAL_TRAY_BACKGROUND[tray.tone ?? 'neutral'],\n }\n : {}),\n // Inline: Tailwind scale/translate utilities silently break inside\n // shadow roots (see CLAUDE.md Shadow DOM caveats).\n transform: isVisible ? 'scale(1)' : 'scale(0.96)',\n opacity: isVisible ? 1 : 0,\n transition: `transform ${TRANSITION_MS}ms ease-out, opacity ${TRANSITION_MS}ms ease-out`,\n }}\n >\n {isBare ? (\n // Still a scroll body: the page behind is locked, so content taller\n // than the viewport has nowhere else to scroll.\n <div\n className={`min-h-0 ${bodyHeight === 'tall' ? TALL_BODY : 'flex-1'} overflow-y-auto`}\n >\n {children}\n </div>\n ) : (\n <div\n className={\n tray\n ? 'flex min-h-0 flex-1 flex-col overflow-hidden rounded-[16px] border border-solid border-[var(--malachite-card-border)] bg-[var(--malachite-card-background)] [box-shadow:var(--malachite-shadow-glow-lg,var(--malachite-shadow-xl))]'\n : 'contents'\n }\n >\n <div\n className={`flex gap-[20px] p-[20px] ${\n subtitle ? 'items-start' : 'items-center'\n } ${\n headerDivider\n ? 'border-0 border-b border-solid border-[var(--malachite-card-border)]'\n : ''\n }`}\n >\n <div className=\"flex h-[18px] min-w-0 flex-1 items-center gap-[12px]\">\n <div className=\"flex min-w-0 items-center gap-[8px]\">\n {icon ? (\n <span className=\"flex shrink-0 items-center\">\n {icon}\n </span>\n ) : null}\n <div className=\"flex min-w-0 flex-col gap-[4px]\">\n <span className=\"truncate text-[14px] font-medium leading-[1.25] tracking-[-0.14px] text-[var(--malachite-text-primary)]\">\n {title}\n </span>\n {subtitle ? (\n <span className=\"text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]\">\n {subtitle}\n </span>\n ) : null}\n </div>\n </div>\n {titleAdornment ? (\n <>\n <span\n aria-hidden=\"true\"\n className=\"h-[12px] w-px shrink-0 bg-[var(--malachite-card-border)]\"\n />\n <span className=\"flex min-w-0 items-center overflow-hidden\">\n {titleAdornment}\n </span>\n </>\n ) : null}\n </div>\n {headerExtra ? (\n <span className=\"flex shrink-0 items-center\">\n {headerExtra}\n </span>\n ) : null}\n {showCloseButton ? (\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={dismissByPointer}\n disabled={busy}\n className={OVERLAY_ICON_BUTTON_CLASSES}\n >\n <DismissIcon size={10} />\n </button>\n ) : null}\n </div>\n <div\n className={`min-h-0 ${bodyHeight === 'tall' ? TALL_BODY : 'flex-1'} overflow-y-auto ${\n bodyPadding && shownCallouts.length === 0 ? 'px-[20px]' : ''\n }`}\n >\n {shownCallouts.map((callout, index) => (\n <CalloutStrip\n key={index}\n id={`${calloutId}-${index}`}\n type={callout.type}\n message={callout.message}\n renderLink={renderLink}\n />\n ))}\n {bodyPadding ? (\n <div\n className={\n shownCallouts.length > 0\n ? 'px-[20px] pt-[18px] pb-[20px]'\n : `pb-[20px] ${headerDivider ? 'pt-[18px]' : ''}`\n }\n >\n {children}\n </div>\n ) : (\n children\n )}\n </div>\n {footer ? (\n <div\n className=\"flex min-h-[56px] shrink-0 items-center border-0 border-t border-solid border-[var(--malachite-card-border)] px-[12px]\"\n style={GLASS_SURFACE_STYLE}\n >\n {footer}\n </div>\n ) : null}\n </div>\n )}\n {tray?.caption ? (\n <div\n id={captionId}\n className=\"flex h-[48px] shrink-0 items-center justify-center px-[16px] text-[13px] tracking-[0.13px]\"\n style={{ color: MODAL_TRAY_CAPTION_COLOR[tray.tone ?? 'neutral'] }}\n >\n <span>\n {tray.caption.label ? (\n <>\n <span className=\"font-medium\">\n {tray.caption.label}\n </span>{' '}\n </>\n ) : null}\n {tray.caption.message}\n </span>\n </div>\n ) : null}\n </div>\n </div>\n </ShadowRootWrapper>,\n document.body,\n );\n};\n\nexport default Modal;\nexport { Modal };\n"],"names":["SIZE_MAX_WIDTH","TRANSITION_MS","TALL_BODY","Modal","open","onClose","title","subtitle","icon","headerExtra","titleAdornment","trayProp","headerDivider","footer","size","surface","showCloseButton","closeOnOverlayClick","bodyPadding","bodyHeight","callouts","renderLink","role","ariaLabel","ariaLabelledBy","ariaDescribedBy","busy","children","captionId","useId","calloutId","isBare","tray","shownCallouts","_a","callout","isVisible","setIsVisible","useState","isMounted","setIsMounted","isExiting","setIsExiting","panelRef","useRef","frameRef","unmountTimerRef","busyRef","onCloseRef","useEffect","dismissByPointer","useCallback","hostRef","takePanelRef","isTopmost","zIndex","elevated","useOverlayBehaviour","handlePanelRef","node","active","getDeepActiveElement","panelClassName","createPortal","jsx","ShadowRootWrapper","overlayIdentity","OVERLAY_ELEVATED_ATTR","jsxs","_","index","MODAL_TRAY_BACKGROUND","Fragment","OVERLAY_ICON_BUTTON_CLASSES","DismissIcon","CalloutStrip","GLASS_SURFACE_STYLE","MODAL_TRAY_CAPTION_COLOR"],"mappings":"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"}
|
|
@@ -1,72 +1,129 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useId as
|
|
3
|
-
import { createPortal as
|
|
4
|
-
import { ShadowRootWrapper as
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import { useOverlayBehaviour as
|
|
10
|
-
import { OVERLAY_ELEVATED_ATTR as
|
|
11
|
-
const
|
|
1
|
+
import { jsxs as r, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import { useId as L, useState as M, useRef as v, useEffect as ae } from "react";
|
|
3
|
+
import { createPortal as ie } from "react-dom";
|
|
4
|
+
import { ShadowRootWrapper as te } from "../ShadowRootWrapper.js";
|
|
5
|
+
import ne from "./CalloutStrip.js";
|
|
6
|
+
import oe from "./CustomIcons/ArrowLeftIcon.js";
|
|
7
|
+
import se from "./CustomIcons/DismissIcon.js";
|
|
8
|
+
import N from "./Typography/EllipsisText.js";
|
|
9
|
+
import { useOverlayBehaviour as ce, OVERLAY_ICON_BUTTON_CLASSES as W } from "./overlayBehaviour.js";
|
|
10
|
+
import { OVERLAY_ELEVATED_ATTR as de, overlayIdentity as j } from "./portalOverlay.js";
|
|
11
|
+
const x = 200, me = "360px", F = ({
|
|
12
|
+
bodyPadding: a,
|
|
13
|
+
callouts: i,
|
|
14
|
+
calloutId: n,
|
|
15
|
+
renderLink: o,
|
|
16
|
+
children: p
|
|
17
|
+
}) => {
|
|
18
|
+
const c = !!(i != null && i.length);
|
|
19
|
+
return /* @__PURE__ */ r(
|
|
20
|
+
"div",
|
|
21
|
+
{
|
|
22
|
+
className: `min-h-0 flex-1 overflow-y-auto ${a && !c ? "px-[28px]" : ""}`,
|
|
23
|
+
children: [
|
|
24
|
+
i == null ? void 0 : i.map((s, d) => /* @__PURE__ */ e(
|
|
25
|
+
ne,
|
|
26
|
+
{
|
|
27
|
+
id: n ? `${n}-${d}` : void 0,
|
|
28
|
+
type: s.type,
|
|
29
|
+
message: s.message,
|
|
30
|
+
renderLink: o
|
|
31
|
+
},
|
|
32
|
+
d
|
|
33
|
+
)),
|
|
34
|
+
a ? /* @__PURE__ */ e("div", { className: c ? "p-[28px]" : "py-[28px]", children: p }) : p
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
}, g = (a) => typeof a == "number" ? `${a}px` : a, ye = ({
|
|
12
39
|
open: a,
|
|
13
|
-
onClose:
|
|
14
|
-
title:
|
|
40
|
+
onClose: i,
|
|
41
|
+
title: n,
|
|
15
42
|
subtitle: o,
|
|
16
|
-
subtitlePlacement:
|
|
17
|
-
titleExtra:
|
|
18
|
-
description:
|
|
19
|
-
toolbar:
|
|
20
|
-
headerDivider:
|
|
21
|
-
icon:
|
|
22
|
-
headerExtra:
|
|
23
|
-
footer:
|
|
24
|
-
onBack:
|
|
25
|
-
maxWidth:
|
|
26
|
-
"aria-label":
|
|
27
|
-
"aria-labelledby":
|
|
28
|
-
bodyPadding:
|
|
29
|
-
stacking:
|
|
30
|
-
callouts:
|
|
31
|
-
renderLink:
|
|
32
|
-
|
|
43
|
+
subtitlePlacement: p = "inline",
|
|
44
|
+
titleExtra: c,
|
|
45
|
+
description: s,
|
|
46
|
+
toolbar: d,
|
|
47
|
+
headerDivider: X = !1,
|
|
48
|
+
icon: w,
|
|
49
|
+
headerExtra: y,
|
|
50
|
+
footer: f,
|
|
51
|
+
onBack: $,
|
|
52
|
+
maxWidth: u = 1080,
|
|
53
|
+
"aria-label": Y,
|
|
54
|
+
"aria-labelledby": T,
|
|
55
|
+
bodyPadding: q = !0,
|
|
56
|
+
stacking: H = "default",
|
|
57
|
+
callouts: h,
|
|
58
|
+
renderLink: U,
|
|
59
|
+
aside: l,
|
|
60
|
+
children: G
|
|
33
61
|
}) => {
|
|
34
|
-
const
|
|
35
|
-
ref:
|
|
36
|
-
isTopmost:
|
|
37
|
-
zIndex:
|
|
38
|
-
elevated:
|
|
39
|
-
} =
|
|
62
|
+
const I = L(), S = L(), [k, C] = M(!1), [J, E] = M(!1), m = v(null), t = v(null), _ = v(null), {
|
|
63
|
+
ref: K,
|
|
64
|
+
isTopmost: Q,
|
|
65
|
+
zIndex: Z,
|
|
66
|
+
elevated: ee
|
|
67
|
+
} = ce({
|
|
40
68
|
open: a,
|
|
41
|
-
onClose:
|
|
42
|
-
elevated:
|
|
43
|
-
hostRef:
|
|
69
|
+
onClose: i,
|
|
70
|
+
elevated: H === "above-app-overlays",
|
|
71
|
+
hostRef: _
|
|
44
72
|
});
|
|
45
|
-
if (
|
|
46
|
-
|
|
47
|
-
})) : (
|
|
48
|
-
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
}), [a]), !
|
|
73
|
+
if (ae(() => (a ? (E(!0), t.current && (clearTimeout(t.current), t.current = null), m.current = requestAnimationFrame(() => {
|
|
74
|
+
m.current = null, C(!0);
|
|
75
|
+
})) : (C(!1), t.current = setTimeout(() => {
|
|
76
|
+
t.current = null, E(!1);
|
|
77
|
+
}, x)), () => {
|
|
78
|
+
m.current !== null && (cancelAnimationFrame(m.current), m.current = null), t.current && (clearTimeout(t.current), t.current = null);
|
|
79
|
+
}), [a]), !J)
|
|
52
80
|
return null;
|
|
53
|
-
const
|
|
81
|
+
const A = h == null ? void 0 : h.filter((D) => D.message.trim()), b = `calc(${g(u)} - 2px)`, R = X ? "border-0 border-b border-solid border-[var(--malachite-card-border)]" : "", re = l ? /* @__PURE__ */ r(
|
|
82
|
+
"aside",
|
|
83
|
+
{
|
|
84
|
+
"aria-label": l.title,
|
|
85
|
+
className: "col-start-1 row-span-3 grid min-w-0 grid-cols-[minmax(0,1fr)] grid-rows-subgrid overflow-hidden border-0 border-r border-solid border-[var(--malachite-card-border)]",
|
|
86
|
+
children: [
|
|
87
|
+
/* @__PURE__ */ r(
|
|
88
|
+
"div",
|
|
89
|
+
{
|
|
90
|
+
className: `flex min-w-0 items-center gap-[8px] px-[20px] py-[18px] ${R}`,
|
|
91
|
+
children: [
|
|
92
|
+
/* @__PURE__ */ e("span", { className: "flex min-w-0 shrink-0", children: /* @__PURE__ */ e(
|
|
93
|
+
N,
|
|
94
|
+
{
|
|
95
|
+
tooltip: l.title,
|
|
96
|
+
tooltipWhenTruncated: !0,
|
|
97
|
+
tooltipPlacement: "bottom",
|
|
98
|
+
className: "min-w-0 text-[length:var(--malachite-font-size-15,15px)] font-semibold",
|
|
99
|
+
children: l.title
|
|
100
|
+
}
|
|
101
|
+
) }),
|
|
102
|
+
l.headerExtra ? /* @__PURE__ */ e("span", { className: "ml-auto flex shrink-0 items-center", children: l.headerExtra }) : null
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
),
|
|
106
|
+
/* @__PURE__ */ e("div", { className: `flex min-h-0 flex-col ${l.footer ? "" : "row-span-2"}`, children: /* @__PURE__ */ e(F, { bodyPadding: l.bodyPadding ?? !0, children: l.children }) }),
|
|
107
|
+
l.footer ? /* @__PURE__ */ e("div", { className: "border-0 border-t border-solid border-[var(--malachite-card-border)] px-[24px] py-[16px]", children: l.footer }) : null
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
) : null, P = p === "below" && !!o, z = /* @__PURE__ */ e(
|
|
54
111
|
"span",
|
|
55
112
|
{
|
|
56
|
-
className:
|
|
113
|
+
className: P ? "flex min-w-0 shrink" : "flex min-w-0 max-w-full shrink-0",
|
|
57
114
|
children: /* @__PURE__ */ e(
|
|
58
|
-
|
|
115
|
+
N,
|
|
59
116
|
{
|
|
60
|
-
tooltip:
|
|
117
|
+
tooltip: n,
|
|
61
118
|
tooltipWhenTruncated: !0,
|
|
62
119
|
tooltipPlacement: "bottom",
|
|
63
120
|
className: "min-w-0 text-[length:var(--malachite-font-size-15,15px)] font-semibold",
|
|
64
|
-
children:
|
|
121
|
+
children: n
|
|
65
122
|
}
|
|
66
123
|
)
|
|
67
124
|
}
|
|
68
|
-
),
|
|
69
|
-
|
|
125
|
+
), O = o ? /* @__PURE__ */ e(
|
|
126
|
+
N,
|
|
70
127
|
{
|
|
71
128
|
tooltip: o,
|
|
72
129
|
tooltipWhenTruncated: !0,
|
|
@@ -75,126 +132,128 @@ const M = 200, se = (a) => typeof a == "number" ? `${a}px` : a, ve = ({
|
|
|
75
132
|
className: "min-w-0 text-[13px]",
|
|
76
133
|
children: o
|
|
77
134
|
}
|
|
78
|
-
) : null,
|
|
79
|
-
return
|
|
135
|
+
) : null, B = c ? /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center", children: c }) : null, V = y ? /* @__PURE__ */ e("span", { className: "flex shrink-0 items-baseline", children: y }) : null;
|
|
136
|
+
return ie(
|
|
80
137
|
// Host carries the stacking context — ShadowRootWrapper's `isolation` would
|
|
81
138
|
// otherwise flatten our z-index and let sticky page elements paint over us.
|
|
82
139
|
/* @__PURE__ */ e(
|
|
83
|
-
|
|
140
|
+
te,
|
|
84
141
|
{
|
|
85
|
-
hostRef:
|
|
86
|
-
hostStyle: { position: "relative", zIndex:
|
|
87
|
-
hostProps:
|
|
142
|
+
hostRef: _,
|
|
143
|
+
hostStyle: { position: "relative", zIndex: Z },
|
|
144
|
+
hostProps: ee ? { ...j("sidepanel"), [de]: "" } : j("sidepanel"),
|
|
88
145
|
children: /* @__PURE__ */ r("div", { className: "fixed inset-0 z-[1000]", children: [
|
|
89
146
|
/* @__PURE__ */ e(
|
|
90
147
|
"div",
|
|
91
148
|
{
|
|
92
149
|
"aria-hidden": "true",
|
|
93
|
-
onClick:
|
|
94
|
-
className: `absolute inset-0 bg-[var(--malachite-overlay-scrim)] transition-opacity duration-200 ease-in-out ${
|
|
150
|
+
onClick: i,
|
|
151
|
+
className: `absolute inset-0 bg-[var(--malachite-overlay-scrim)] transition-opacity duration-200 ease-in-out ${k ? "opacity-100" : "opacity-0"}`
|
|
95
152
|
}
|
|
96
153
|
),
|
|
97
154
|
/* @__PURE__ */ r(
|
|
98
155
|
"div",
|
|
99
156
|
{
|
|
100
|
-
ref:
|
|
157
|
+
ref: K,
|
|
101
158
|
role: "dialog",
|
|
102
|
-
"aria-modal":
|
|
159
|
+
"aria-modal": Q ? "true" : void 0,
|
|
103
160
|
"aria-describedby": [
|
|
104
|
-
...(
|
|
105
|
-
|
|
161
|
+
...(A ?? []).map((D, le) => `${I}-${le}`),
|
|
162
|
+
s ? S : null
|
|
106
163
|
].filter(Boolean).join(" ") || void 0,
|
|
107
164
|
tabIndex: -1,
|
|
108
|
-
"aria-label":
|
|
109
|
-
"aria-labelledby":
|
|
110
|
-
className: "absolute top-[8px] right-[8px] bottom-[8px]
|
|
165
|
+
"aria-label": T ? void 0 : Y ?? (typeof n == "string" ? n : void 0),
|
|
166
|
+
"aria-labelledby": T,
|
|
167
|
+
className: "absolute top-[8px] right-[8px] bottom-[8px] grid grid-rows-[auto_minmax(0,1fr)_auto] overflow-x-auto overflow-y-hidden rounded-[20px] border border-solid border-[var(--malachite-card-border)] bg-[var(--malachite-card-background)] text-[var(--malachite-card-foreground)] outline-none [box-shadow:var(--malachite-shadow-lg)]",
|
|
111
168
|
style: {
|
|
112
|
-
width: `min(calc(100% - 16px), ${
|
|
169
|
+
width: `min(calc(100% - 16px), ${l ? `calc(2 * ${g(u)})` : g(u)})`,
|
|
113
170
|
// Inline: Tailwind translate utilities silently break inside
|
|
114
171
|
// shadow roots (see CLAUDE.md Shadow DOM caveats).
|
|
115
|
-
transform:
|
|
116
|
-
transition: `transform ${
|
|
172
|
+
transform: k ? "translateX(0)" : "translateX(calc(100% + 16px))",
|
|
173
|
+
transition: `transform ${x}ms ease-in-out, width ${x}ms ease-in-out, grid-template-columns ${x}ms ease-in-out`,
|
|
174
|
+
// The panel's own column is the width it has without an aside: `maxWidth`
|
|
175
|
+
// less the 1px border either side, so opening the aside never widens it.
|
|
176
|
+
// With an aside neither column gives way, so a narrow window scrolls the
|
|
177
|
+
// panel instead. Both templates share one shape so the minimums animate
|
|
178
|
+
// with the width rather than overflowing mid-transition.
|
|
179
|
+
gridTemplateColumns: l ? `minmax(${me}, 1fr) minmax(${b}, ${b})` : `minmax(0px, 1fr) minmax(0px, ${b})`
|
|
117
180
|
},
|
|
118
181
|
children: [
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
/* @__PURE__ */
|
|
138
|
-
|
|
139
|
-
|
|
182
|
+
re,
|
|
183
|
+
/* @__PURE__ */ r("div", { className: "col-start-2 row-span-3 grid min-w-0 grid-cols-[minmax(0,1fr)] grid-rows-subgrid", children: [
|
|
184
|
+
/* @__PURE__ */ r(
|
|
185
|
+
"div",
|
|
186
|
+
{
|
|
187
|
+
className: `flex flex-col gap-[20px] px-[20px] py-[18px] ${R}`,
|
|
188
|
+
children: [
|
|
189
|
+
/* @__PURE__ */ r("div", { className: "flex items-center gap-[12px]", children: [
|
|
190
|
+
$ ? /* @__PURE__ */ e(
|
|
191
|
+
"button",
|
|
192
|
+
{
|
|
193
|
+
type: "button",
|
|
194
|
+
"aria-label": "Back",
|
|
195
|
+
onClick: $,
|
|
196
|
+
className: W,
|
|
197
|
+
children: /* @__PURE__ */ e(oe, { size: 16 })
|
|
198
|
+
}
|
|
199
|
+
) : null,
|
|
200
|
+
w ? /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center", children: w }) : null,
|
|
201
|
+
P ? /* @__PURE__ */ r("div", { className: "flex min-w-0 flex-1 items-center gap-[12px]", children: [
|
|
202
|
+
/* @__PURE__ */ r("div", { className: "flex min-w-0 flex-1 flex-col gap-[2px]", children: [
|
|
203
|
+
/* @__PURE__ */ r("div", { className: "flex min-w-0 items-baseline gap-[8px]", children: [
|
|
204
|
+
z,
|
|
205
|
+
B
|
|
206
|
+
] }),
|
|
140
207
|
O
|
|
141
208
|
] }),
|
|
142
|
-
|
|
143
|
-
] }),
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
209
|
+
V
|
|
210
|
+
] }) : /* @__PURE__ */ r("div", { className: "flex min-w-0 flex-1 items-baseline gap-[12px]", children: [
|
|
211
|
+
/* @__PURE__ */ r("div", { className: "flex min-w-0 flex-1 items-baseline gap-[8px]", children: [
|
|
212
|
+
/* @__PURE__ */ r("div", { className: "flex min-w-0 items-baseline gap-[8px]", children: [
|
|
213
|
+
z,
|
|
214
|
+
O
|
|
215
|
+
] }),
|
|
216
|
+
B
|
|
150
217
|
] }),
|
|
151
|
-
|
|
218
|
+
V
|
|
152
219
|
] }),
|
|
153
|
-
|
|
220
|
+
/* @__PURE__ */ e(
|
|
221
|
+
"button",
|
|
222
|
+
{
|
|
223
|
+
type: "button",
|
|
224
|
+
"aria-label": "Close",
|
|
225
|
+
onClick: i,
|
|
226
|
+
className: W,
|
|
227
|
+
children: /* @__PURE__ */ e(se, { size: 10 })
|
|
228
|
+
}
|
|
229
|
+
)
|
|
154
230
|
] }),
|
|
155
|
-
/* @__PURE__ */ e(
|
|
156
|
-
"
|
|
231
|
+
s ? /* @__PURE__ */ e(
|
|
232
|
+
"div",
|
|
157
233
|
{
|
|
158
|
-
|
|
159
|
-
"
|
|
160
|
-
|
|
161
|
-
className: L,
|
|
162
|
-
children: /* @__PURE__ */ e(te, { size: 10 })
|
|
234
|
+
id: S,
|
|
235
|
+
className: "text-[13px] leading-[1.6] text-[var(--malachite-text-secondary)]",
|
|
236
|
+
children: s
|
|
163
237
|
}
|
|
164
|
-
)
|
|
165
|
-
]
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
t == null ? void 0 : t.map((n, c) => /* @__PURE__ */ e(
|
|
184
|
-
le,
|
|
185
|
-
{
|
|
186
|
-
id: `${T}-${c}`,
|
|
187
|
-
type: n.type,
|
|
188
|
-
message: n.message,
|
|
189
|
-
renderLink: q
|
|
190
|
-
},
|
|
191
|
-
c
|
|
192
|
-
)),
|
|
193
|
-
Q
|
|
194
|
-
]
|
|
195
|
-
}
|
|
196
|
-
),
|
|
197
|
-
v ? /* @__PURE__ */ e("div", { className: "border-0 border-t border-solid border-[var(--malachite-card-border)] px-[24px] py-[16px]", children: v }) : null
|
|
238
|
+
) : null
|
|
239
|
+
]
|
|
240
|
+
}
|
|
241
|
+
),
|
|
242
|
+
/* @__PURE__ */ r("div", { className: `flex min-h-0 flex-col ${f ? "" : "row-span-2"}`, children: [
|
|
243
|
+
d ? /* @__PURE__ */ e("div", { className: "shrink-0 px-[16px] pt-[16px] pb-[8px]", children: d }) : null,
|
|
244
|
+
/* @__PURE__ */ e(
|
|
245
|
+
F,
|
|
246
|
+
{
|
|
247
|
+
bodyPadding: q,
|
|
248
|
+
callouts: A,
|
|
249
|
+
calloutId: I,
|
|
250
|
+
renderLink: U,
|
|
251
|
+
children: G
|
|
252
|
+
}
|
|
253
|
+
)
|
|
254
|
+
] }),
|
|
255
|
+
f ? /* @__PURE__ */ e("div", { className: "border-0 border-t border-solid border-[var(--malachite-card-border)] px-[24px] py-[16px]", children: f }) : null
|
|
256
|
+
] })
|
|
198
257
|
]
|
|
199
258
|
}
|
|
200
259
|
)
|
|
@@ -205,7 +264,7 @@ const M = 200, se = (a) => typeof a == "number" ? `${a}px` : a, ve = ({
|
|
|
205
264
|
);
|
|
206
265
|
};
|
|
207
266
|
export {
|
|
208
|
-
|
|
209
|
-
|
|
267
|
+
ye as SidePanel,
|
|
268
|
+
ye as default
|
|
210
269
|
};
|
|
211
270
|
//# sourceMappingURL=SidePanel.js.map
|