@lobehub/ui 5.41.1 → 5.42.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/es/base-ui/FloatingPanel/FloatingPanel.mjs +9 -4
- package/es/base-ui/FloatingPanel/FloatingPanel.mjs.map +1 -1
- package/es/base-ui/FloatingPanel/ToastDodge.mjs +81 -0
- package/es/base-ui/FloatingPanel/ToastDodge.mjs.map +1 -0
- package/es/base-ui/FloatingPanel/style.mjs +11 -1
- package/es/base-ui/FloatingPanel/style.mjs.map +1 -1
- package/es/base-ui/Input/style.d.mts +1 -1
- package/es/base-ui/Text/style.d.mts +1 -1
- package/es/base-ui/Toast/dodge.mjs +51 -0
- package/es/base-ui/Toast/dodge.mjs.map +1 -0
- package/es/base-ui/Toast/style.mjs +14 -1
- package/es/base-ui/Toast/style.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { ModalBackdrop, ModalClose, ModalContent, ModalFooter, ModalHeader, ModalPopup, ModalPortal, ModalRoot, ModalTitle } from "../Modal/atoms.mjs";
|
|
3
3
|
import { styles } from "./style.mjs";
|
|
4
|
+
import { ToastDodge } from "./ToastDodge.mjs";
|
|
4
5
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
5
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
import { cx } from "antd-style";
|
|
@@ -94,13 +95,16 @@ const getPlacementStyle = (placement, offset) => {
|
|
|
94
95
|
const { x, y } = resolveOffset(offset);
|
|
95
96
|
const isTop = placement.startsWith("top");
|
|
96
97
|
const isLeft = placement.endsWith("Left");
|
|
98
|
+
const px = (value) => typeof value === "number" ? `${value}px` : value;
|
|
99
|
+
const blockInset = `calc(${px(y)} + var(--floating-panel-reserve-block-end, 0px))`;
|
|
100
|
+
const inlineInset = `calc(${px(x)} + var(--floating-panel-reserve-inline-end, 0px))`;
|
|
97
101
|
return {
|
|
98
102
|
alignItems: isTop ? "flex-start" : "flex-end",
|
|
99
103
|
justifyContent: isLeft ? "flex-start" : "flex-end",
|
|
100
|
-
paddingBlockEnd: isTop ? void 0 :
|
|
101
|
-
paddingBlockStart: isTop ?
|
|
102
|
-
paddingInlineEnd: isLeft ? void 0 :
|
|
103
|
-
paddingInlineStart: isLeft ?
|
|
104
|
+
paddingBlockEnd: isTop ? void 0 : blockInset,
|
|
105
|
+
paddingBlockStart: isTop ? blockInset : void 0,
|
|
106
|
+
paddingInlineEnd: isLeft ? void 0 : inlineInset,
|
|
107
|
+
paddingInlineStart: isLeft ? inlineInset : void 0
|
|
104
108
|
};
|
|
105
109
|
};
|
|
106
110
|
const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
@@ -276,6 +280,7 @@ const FloatingPanel = memo(({ afterClose, ariaLabel, children, className, classN
|
|
|
276
280
|
...semanticStyles?.panel
|
|
277
281
|
},
|
|
278
282
|
children: [
|
|
283
|
+
placement === "bottomRight" && /* @__PURE__ */ jsx(ToastDodge, {}),
|
|
279
284
|
resizable && resizeHandles.map((handle) => /* @__PURE__ */ jsx("div", {
|
|
280
285
|
"aria-hidden": true,
|
|
281
286
|
"data-floating-panel-resize-handle": handle,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingPanel.mjs","names":[],"sources":["../../../src/base-ui/FloatingPanel/FloatingPanel.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport { X } from 'lucide-react';\nimport type { MotionProps } from 'motion/react';\nimport type { CSSProperties, PointerEvent as ReactPointerEvent } from 'react';\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport type { ModalRootProps } from '../Modal';\nimport {\n ModalBackdrop,\n ModalClose,\n ModalContent,\n ModalFooter,\n ModalHeader,\n ModalPopup,\n ModalPortal,\n ModalRoot,\n ModalTitle,\n} from '../Modal';\nimport { styles } from './style';\nimport type {\n FloatingPanelOffset,\n FloatingPanelPlacement,\n FloatingPanelProps,\n FloatingPanelResizeHandle,\n FloatingPanelSize,\n} from './type';\n\nconst DEFAULT_MIN_HEIGHT = 180;\nconst DEFAULT_MIN_WIDTH = 320;\n\ninterface InternalFloatingPanelSize extends FloatingPanelSize {\n sourceHeight?: number | string;\n sourceWidth?: number | string;\n}\n\nconst defaultMotionProps: MotionProps = {\n animate: { opacity: 1, scale: 1, x: 0, y: 0 },\n exit: {\n opacity: 0,\n scale: 0.98,\n transition: { duration: 0.14, ease: [0.4, 0, 1, 1] },\n y: 12,\n },\n initial: { opacity: 0, scale: 0.98, y: 12 },\n transition: { duration: 0.2, ease: [0.32, 0.72, 0, 1] },\n};\n\nconst topMotionProps: MotionProps = {\n animate: { opacity: 1, scale: 1, x: 0, y: 0 },\n exit: {\n opacity: 0,\n scale: 0.98,\n transition: { duration: 0.14, ease: [0.4, 0, 1, 1] },\n y: -12,\n },\n initial: { opacity: 0, scale: 0.98, y: -12 },\n transition: { duration: 0.2, ease: [0.32, 0.72, 0, 1] },\n};\n\nconst resolveOffset = (offset: FloatingPanelOffset) => {\n if (typeof offset === 'object') {\n return {\n x: offset.x ?? 8,\n y: offset.y ?? 8,\n };\n }\n\n return { x: offset, y: offset };\n};\n\nconst getPlacementStyle = (\n placement: FloatingPanelPlacement,\n offset: FloatingPanelOffset,\n): CSSProperties => {\n const { x, y } = resolveOffset(offset);\n const isTop = placement.startsWith('top');\n const isLeft = placement.endsWith('Left');\n\n return {\n alignItems: isTop ? 'flex-start' : 'flex-end',\n justifyContent: isLeft ? 'flex-start' : 'flex-end',\n paddingBlockEnd: isTop ? undefined : y,\n paddingBlockStart: isTop ? y : undefined,\n paddingInlineEnd: isLeft ? undefined : x,\n paddingInlineStart: isLeft ? x : undefined,\n };\n};\n\nconst clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\n\nconst getViewportMaxSize = () => ({\n height: Math.max(DEFAULT_MIN_HEIGHT, window.innerHeight - 16),\n width: Math.max(DEFAULT_MIN_WIDTH, window.innerWidth - 16),\n});\n\nconst getResizeHandles = (placement: FloatingPanelPlacement): FloatingPanelResizeHandle[] => {\n switch (placement) {\n case 'bottomLeft': {\n return ['top', 'right', 'topRight'];\n }\n case 'topLeft': {\n return ['bottom', 'right', 'bottomRight'];\n }\n case 'topRight': {\n return ['bottom', 'left', 'bottomLeft'];\n }\n default: {\n return ['top', 'left', 'topLeft'];\n }\n }\n};\n\nconst getResizeHandleClassName = (s: typeof styles, handle: FloatingPanelResizeHandle) => {\n const handleClassMap: Record<FloatingPanelResizeHandle, string> = {\n bottom: s.resizeHandleBottom,\n bottomLeft: s.resizeHandleBottomLeft,\n bottomRight: s.resizeHandleBottomRight,\n left: s.resizeHandleLeft,\n right: s.resizeHandleRight,\n top: s.resizeHandleTop,\n topLeft: s.resizeHandleTopLeft,\n topRight: s.resizeHandleTopRight,\n };\n\n return handleClassMap[handle];\n};\n\nconst resolveResizeSize = ({\n handle,\n maxHeight,\n maxWidth,\n minHeight,\n minWidth,\n startHeight,\n startWidth,\n startX,\n startY,\n x,\n y,\n}: {\n handle: FloatingPanelResizeHandle;\n maxHeight: number;\n maxWidth: number;\n minHeight: number;\n minWidth: number;\n startHeight: number;\n startWidth: number;\n startX: number;\n startY: number;\n x: number;\n y: number;\n}): FloatingPanelSize => {\n const deltaX = x - startX;\n const deltaY = y - startY;\n const growsLeft = handle.includes('Left') || handle === 'left';\n const growsRight = handle.includes('Right') || handle === 'right';\n const growsTop = handle.includes('top') || handle === 'top';\n const growsBottom = handle.includes('bottom') || handle === 'bottom';\n\n const nextWidth = growsLeft ? startWidth - deltaX : growsRight ? startWidth + deltaX : startWidth;\n const nextHeight = growsTop\n ? startHeight - deltaY\n : growsBottom\n ? startHeight + deltaY\n : startHeight;\n\n return {\n height: clamp(nextHeight, minHeight, maxHeight),\n width: clamp(nextWidth, minWidth, maxWidth),\n };\n};\n\nconst FloatingPanel = memo<FloatingPanelProps>(\n ({\n afterClose,\n ariaLabel,\n children,\n className,\n classNames,\n closable = true,\n closeIcon,\n closeLabel = 'Close',\n defaultOpen,\n actions,\n footer,\n getContainer,\n height,\n keyboard = true,\n mask = false,\n maskClosable = true,\n maxHeight,\n maxWidth,\n minHeight = DEFAULT_MIN_HEIGHT,\n minWidth = DEFAULT_MIN_WIDTH,\n modal = false,\n motionProps,\n offset = 8,\n onClose,\n onOpenChange,\n onResize,\n onResizeEnd,\n open,\n placement = 'bottomRight',\n resizable = true,\n styles: semanticStyles,\n title,\n width = 640,\n zIndex,\n }) => {\n const s = styles;\n const isTop = placement.startsWith('top');\n const container = getContainer === false ? undefined : getContainer;\n const [resizeSize, setResizeSize] = useState<InternalFloatingPanelSize>();\n const latestResizeSizeRef = useRef<FloatingPanelSize | undefined>(undefined);\n const resizeCleanupRef = useRef<(() => void) | undefined>(undefined);\n const activeResizeSize =\n resizeSize?.sourceWidth === width && resizeSize.sourceHeight === height\n ? resizeSize\n : undefined;\n\n useEffect(\n () => () => {\n resizeCleanupRef.current?.();\n },\n [],\n );\n\n const popupStyle = useMemo(\n () => ({\n ...getPlacementStyle(placement, offset),\n ...semanticStyles?.wrapper,\n }),\n [offset, placement, semanticStyles?.wrapper],\n );\n\n const handleOpenChange = useCallback<NonNullable<ModalRootProps['onOpenChange']>>(\n (nextOpen, eventDetails) => {\n if (!nextOpen) {\n if (keyboard === false && eventDetails.reason === 'escape-key') return;\n if (maskClosable === false && eventDetails.reason === 'outside-press') return;\n onClose?.();\n }\n\n onOpenChange?.(nextOpen, eventDetails);\n },\n [keyboard, maskClosable, onClose, onOpenChange],\n );\n\n const showHeader = title !== undefined || actions !== undefined || closable;\n const resolvedMotionProps = motionProps ?? (isTop ? topMotionProps : defaultMotionProps);\n const resizeHandles = useMemo(() => getResizeHandles(placement), [placement]);\n\n const handleResizeStart = useCallback(\n (handle: FloatingPanelResizeHandle) => (event: ReactPointerEvent<HTMLDivElement>) => {\n event.preventDefault();\n event.stopPropagation();\n\n const panel = event.currentTarget.parentElement;\n if (!panel) return;\n\n const rect = panel.getBoundingClientRect();\n const viewportMaxSize = getViewportMaxSize();\n const resolvedMaxWidth = Math.max(minWidth, maxWidth ?? viewportMaxSize.width);\n const resolvedMaxHeight = Math.max(minHeight, maxHeight ?? viewportMaxSize.height);\n const startX = event.clientX;\n const startY = event.clientY;\n\n const handleResizeMove = (moveEvent: PointerEvent) => {\n const nextSize = resolveResizeSize({\n handle,\n maxHeight: resolvedMaxHeight,\n maxWidth: resolvedMaxWidth,\n minHeight,\n minWidth,\n startHeight: rect.height,\n startWidth: rect.width,\n startX,\n startY,\n x: moveEvent.clientX,\n y: moveEvent.clientY,\n });\n\n const nextState = { ...nextSize, sourceHeight: height, sourceWidth: width };\n latestResizeSizeRef.current = nextSize;\n setResizeSize(nextState);\n onResize?.(nextSize);\n };\n\n const handleResizeEnd = () => {\n resizeCleanupRef.current?.();\n resizeCleanupRef.current = undefined;\n\n if (latestResizeSizeRef.current) onResizeEnd?.(latestResizeSizeRef.current);\n };\n\n resizeCleanupRef.current?.();\n window.addEventListener('pointermove', handleResizeMove);\n window.addEventListener('pointerup', handleResizeEnd);\n resizeCleanupRef.current = () => {\n window.removeEventListener('pointermove', handleResizeMove);\n window.removeEventListener('pointerup', handleResizeEnd);\n };\n },\n [height, maxHeight, maxWidth, minHeight, minWidth, onResize, onResizeEnd, width],\n );\n\n return (\n <ModalRoot\n defaultOpen={defaultOpen}\n modal={modal}\n open={open}\n zIndex={zIndex}\n onExitComplete={afterClose}\n onOpenChange={handleOpenChange}\n >\n <ModalPortal container={container}>\n {mask && (\n <ModalBackdrop className={classNames?.backdrop} style={semanticStyles?.backdrop} />\n )}\n <ModalPopup\n aria-label={ariaLabel}\n className={cx(s.wrapper, classNames?.wrapper)}\n motionProps={resolvedMotionProps}\n panelClassName={cx(s.panel, isTop && s.panelTop, className, classNames?.panel)}\n popupStyle={popupStyle}\n width={activeResizeSize?.width ?? width}\n style={{\n height: activeResizeSize?.height ?? height,\n minHeight,\n minWidth,\n width: activeResizeSize?.width,\n ...semanticStyles?.panel,\n }}\n >\n {resizable &&\n resizeHandles.map((handle) => (\n <div\n aria-hidden\n data-floating-panel-resize-handle={handle}\n key={handle}\n style={semanticStyles?.resizeHandle}\n className={cx(\n s.resizeHandle,\n getResizeHandleClassName(s, handle),\n classNames?.resizeHandle,\n )}\n onPointerDown={handleResizeStart(handle)}\n />\n ))}\n {showHeader && (\n <ModalHeader\n className={cx(s.header, classNames?.header)}\n style={semanticStyles?.header}\n >\n {title !== undefined ? (\n <ModalTitle\n className={cx(s.title, classNames?.title)}\n style={semanticStyles?.title}\n >\n {title}\n </ModalTitle>\n ) : (\n <span />\n )}\n <div className={s.headerActions}>\n {actions && (\n <div\n className={cx(s.actions, classNames?.actions)}\n style={semanticStyles?.actions}\n >\n {actions}\n </div>\n )}\n {closable && (\n <ModalClose\n aria-label={closeLabel}\n className={cx(s.close, classNames?.close)}\n style={semanticStyles?.close}\n >\n {closeIcon ?? <X size={16} />}\n </ModalClose>\n )}\n </div>\n </ModalHeader>\n )}\n <ModalContent className={cx(s.body, classNames?.body)} style={semanticStyles?.body}>\n {children}\n </ModalContent>\n {footer && (\n <ModalFooter\n className={cx(s.footer, classNames?.footer)}\n style={semanticStyles?.footer}\n >\n {footer}\n </ModalFooter>\n )}\n </ModalPopup>\n </ModalPortal>\n </ModalRoot>\n );\n },\n);\n\nFloatingPanel.displayName = 'FloatingPanel';\n\nexport { FloatingPanel };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FloatingPanel.mjs","names":[],"sources":["../../../src/base-ui/FloatingPanel/FloatingPanel.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport { X } from 'lucide-react';\nimport type { MotionProps } from 'motion/react';\nimport type { CSSProperties, PointerEvent as ReactPointerEvent } from 'react';\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport type { ModalRootProps } from '../Modal';\nimport {\n ModalBackdrop,\n ModalClose,\n ModalContent,\n ModalFooter,\n ModalHeader,\n ModalPopup,\n ModalPortal,\n ModalRoot,\n ModalTitle,\n} from '../Modal';\nimport { styles } from './style';\nimport { ToastDodge } from './ToastDodge';\nimport type {\n FloatingPanelOffset,\n FloatingPanelPlacement,\n FloatingPanelProps,\n FloatingPanelResizeHandle,\n FloatingPanelSize,\n} from './type';\n\nconst DEFAULT_MIN_HEIGHT = 180;\nconst DEFAULT_MIN_WIDTH = 320;\n\ninterface InternalFloatingPanelSize extends FloatingPanelSize {\n sourceHeight?: number | string;\n sourceWidth?: number | string;\n}\n\nconst defaultMotionProps: MotionProps = {\n animate: { opacity: 1, scale: 1, x: 0, y: 0 },\n exit: {\n opacity: 0,\n scale: 0.98,\n transition: { duration: 0.14, ease: [0.4, 0, 1, 1] },\n y: 12,\n },\n initial: { opacity: 0, scale: 0.98, y: 12 },\n transition: { duration: 0.2, ease: [0.32, 0.72, 0, 1] },\n};\n\nconst topMotionProps: MotionProps = {\n animate: { opacity: 1, scale: 1, x: 0, y: 0 },\n exit: {\n opacity: 0,\n scale: 0.98,\n transition: { duration: 0.14, ease: [0.4, 0, 1, 1] },\n y: -12,\n },\n initial: { opacity: 0, scale: 0.98, y: -12 },\n transition: { duration: 0.2, ease: [0.32, 0.72, 0, 1] },\n};\n\nconst resolveOffset = (offset: FloatingPanelOffset) => {\n if (typeof offset === 'object') {\n return {\n x: offset.x ?? 8,\n y: offset.y ?? 8,\n };\n }\n\n return { x: offset, y: offset };\n};\n\nconst getPlacementStyle = (\n placement: FloatingPanelPlacement,\n offset: FloatingPanelOffset,\n): CSSProperties => {\n const { x, y } = resolveOffset(offset);\n const isTop = placement.startsWith('top');\n const isLeft = placement.endsWith('Left');\n\n const px = (value: number | string) => (typeof value === 'number' ? `${value}px` : value);\n const blockInset = `calc(${px(y)} + var(--floating-panel-reserve-block-end, 0px))`;\n const inlineInset = `calc(${px(x)} + var(--floating-panel-reserve-inline-end, 0px))`;\n\n return {\n alignItems: isTop ? 'flex-start' : 'flex-end',\n justifyContent: isLeft ? 'flex-start' : 'flex-end',\n paddingBlockEnd: isTop ? undefined : blockInset,\n paddingBlockStart: isTop ? blockInset : undefined,\n paddingInlineEnd: isLeft ? undefined : inlineInset,\n paddingInlineStart: isLeft ? inlineInset : undefined,\n };\n};\n\nconst clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\n\nconst getViewportMaxSize = () => ({\n height: Math.max(DEFAULT_MIN_HEIGHT, window.innerHeight - 16),\n width: Math.max(DEFAULT_MIN_WIDTH, window.innerWidth - 16),\n});\n\nconst getResizeHandles = (placement: FloatingPanelPlacement): FloatingPanelResizeHandle[] => {\n switch (placement) {\n case 'bottomLeft': {\n return ['top', 'right', 'topRight'];\n }\n case 'topLeft': {\n return ['bottom', 'right', 'bottomRight'];\n }\n case 'topRight': {\n return ['bottom', 'left', 'bottomLeft'];\n }\n default: {\n return ['top', 'left', 'topLeft'];\n }\n }\n};\n\nconst getResizeHandleClassName = (s: typeof styles, handle: FloatingPanelResizeHandle) => {\n const handleClassMap: Record<FloatingPanelResizeHandle, string> = {\n bottom: s.resizeHandleBottom,\n bottomLeft: s.resizeHandleBottomLeft,\n bottomRight: s.resizeHandleBottomRight,\n left: s.resizeHandleLeft,\n right: s.resizeHandleRight,\n top: s.resizeHandleTop,\n topLeft: s.resizeHandleTopLeft,\n topRight: s.resizeHandleTopRight,\n };\n\n return handleClassMap[handle];\n};\n\nconst resolveResizeSize = ({\n handle,\n maxHeight,\n maxWidth,\n minHeight,\n minWidth,\n startHeight,\n startWidth,\n startX,\n startY,\n x,\n y,\n}: {\n handle: FloatingPanelResizeHandle;\n maxHeight: number;\n maxWidth: number;\n minHeight: number;\n minWidth: number;\n startHeight: number;\n startWidth: number;\n startX: number;\n startY: number;\n x: number;\n y: number;\n}): FloatingPanelSize => {\n const deltaX = x - startX;\n const deltaY = y - startY;\n const growsLeft = handle.includes('Left') || handle === 'left';\n const growsRight = handle.includes('Right') || handle === 'right';\n const growsTop = handle.includes('top') || handle === 'top';\n const growsBottom = handle.includes('bottom') || handle === 'bottom';\n\n const nextWidth = growsLeft ? startWidth - deltaX : growsRight ? startWidth + deltaX : startWidth;\n const nextHeight = growsTop\n ? startHeight - deltaY\n : growsBottom\n ? startHeight + deltaY\n : startHeight;\n\n return {\n height: clamp(nextHeight, minHeight, maxHeight),\n width: clamp(nextWidth, minWidth, maxWidth),\n };\n};\n\nconst FloatingPanel = memo<FloatingPanelProps>(\n ({\n afterClose,\n ariaLabel,\n children,\n className,\n classNames,\n closable = true,\n closeIcon,\n closeLabel = 'Close',\n defaultOpen,\n actions,\n footer,\n getContainer,\n height,\n keyboard = true,\n mask = false,\n maskClosable = true,\n maxHeight,\n maxWidth,\n minHeight = DEFAULT_MIN_HEIGHT,\n minWidth = DEFAULT_MIN_WIDTH,\n modal = false,\n motionProps,\n offset = 8,\n onClose,\n onOpenChange,\n onResize,\n onResizeEnd,\n open,\n placement = 'bottomRight',\n resizable = true,\n styles: semanticStyles,\n title,\n width = 640,\n zIndex,\n }) => {\n const s = styles;\n const isTop = placement.startsWith('top');\n const container = getContainer === false ? undefined : getContainer;\n const [resizeSize, setResizeSize] = useState<InternalFloatingPanelSize>();\n const latestResizeSizeRef = useRef<FloatingPanelSize | undefined>(undefined);\n const resizeCleanupRef = useRef<(() => void) | undefined>(undefined);\n const activeResizeSize =\n resizeSize?.sourceWidth === width && resizeSize.sourceHeight === height\n ? resizeSize\n : undefined;\n\n useEffect(\n () => () => {\n resizeCleanupRef.current?.();\n },\n [],\n );\n\n const popupStyle = useMemo(\n () => ({\n ...getPlacementStyle(placement, offset),\n ...semanticStyles?.wrapper,\n }),\n [offset, placement, semanticStyles?.wrapper],\n );\n\n const handleOpenChange = useCallback<NonNullable<ModalRootProps['onOpenChange']>>(\n (nextOpen, eventDetails) => {\n if (!nextOpen) {\n if (keyboard === false && eventDetails.reason === 'escape-key') return;\n if (maskClosable === false && eventDetails.reason === 'outside-press') return;\n onClose?.();\n }\n\n onOpenChange?.(nextOpen, eventDetails);\n },\n [keyboard, maskClosable, onClose, onOpenChange],\n );\n\n const showHeader = title !== undefined || actions !== undefined || closable;\n const resolvedMotionProps = motionProps ?? (isTop ? topMotionProps : defaultMotionProps);\n const resizeHandles = useMemo(() => getResizeHandles(placement), [placement]);\n\n const handleResizeStart = useCallback(\n (handle: FloatingPanelResizeHandle) => (event: ReactPointerEvent<HTMLDivElement>) => {\n event.preventDefault();\n event.stopPropagation();\n\n const panel = event.currentTarget.parentElement;\n if (!panel) return;\n\n const rect = panel.getBoundingClientRect();\n const viewportMaxSize = getViewportMaxSize();\n const resolvedMaxWidth = Math.max(minWidth, maxWidth ?? viewportMaxSize.width);\n const resolvedMaxHeight = Math.max(minHeight, maxHeight ?? viewportMaxSize.height);\n const startX = event.clientX;\n const startY = event.clientY;\n\n const handleResizeMove = (moveEvent: PointerEvent) => {\n const nextSize = resolveResizeSize({\n handle,\n maxHeight: resolvedMaxHeight,\n maxWidth: resolvedMaxWidth,\n minHeight,\n minWidth,\n startHeight: rect.height,\n startWidth: rect.width,\n startX,\n startY,\n x: moveEvent.clientX,\n y: moveEvent.clientY,\n });\n\n const nextState = { ...nextSize, sourceHeight: height, sourceWidth: width };\n latestResizeSizeRef.current = nextSize;\n setResizeSize(nextState);\n onResize?.(nextSize);\n };\n\n const handleResizeEnd = () => {\n resizeCleanupRef.current?.();\n resizeCleanupRef.current = undefined;\n\n if (latestResizeSizeRef.current) onResizeEnd?.(latestResizeSizeRef.current);\n };\n\n resizeCleanupRef.current?.();\n window.addEventListener('pointermove', handleResizeMove);\n window.addEventListener('pointerup', handleResizeEnd);\n resizeCleanupRef.current = () => {\n window.removeEventListener('pointermove', handleResizeMove);\n window.removeEventListener('pointerup', handleResizeEnd);\n };\n },\n [height, maxHeight, maxWidth, minHeight, minWidth, onResize, onResizeEnd, width],\n );\n\n return (\n <ModalRoot\n defaultOpen={defaultOpen}\n modal={modal}\n open={open}\n zIndex={zIndex}\n onExitComplete={afterClose}\n onOpenChange={handleOpenChange}\n >\n <ModalPortal container={container}>\n {mask && (\n <ModalBackdrop className={classNames?.backdrop} style={semanticStyles?.backdrop} />\n )}\n <ModalPopup\n aria-label={ariaLabel}\n className={cx(s.wrapper, classNames?.wrapper)}\n motionProps={resolvedMotionProps}\n panelClassName={cx(s.panel, isTop && s.panelTop, className, classNames?.panel)}\n popupStyle={popupStyle}\n width={activeResizeSize?.width ?? width}\n style={{\n height: activeResizeSize?.height ?? height,\n minHeight,\n minWidth,\n width: activeResizeSize?.width,\n ...semanticStyles?.panel,\n }}\n >\n {placement === 'bottomRight' && <ToastDodge />}\n {resizable &&\n resizeHandles.map((handle) => (\n <div\n aria-hidden\n data-floating-panel-resize-handle={handle}\n key={handle}\n style={semanticStyles?.resizeHandle}\n className={cx(\n s.resizeHandle,\n getResizeHandleClassName(s, handle),\n classNames?.resizeHandle,\n )}\n onPointerDown={handleResizeStart(handle)}\n />\n ))}\n {showHeader && (\n <ModalHeader\n className={cx(s.header, classNames?.header)}\n style={semanticStyles?.header}\n >\n {title !== undefined ? (\n <ModalTitle\n className={cx(s.title, classNames?.title)}\n style={semanticStyles?.title}\n >\n {title}\n </ModalTitle>\n ) : (\n <span />\n )}\n <div className={s.headerActions}>\n {actions && (\n <div\n className={cx(s.actions, classNames?.actions)}\n style={semanticStyles?.actions}\n >\n {actions}\n </div>\n )}\n {closable && (\n <ModalClose\n aria-label={closeLabel}\n className={cx(s.close, classNames?.close)}\n style={semanticStyles?.close}\n >\n {closeIcon ?? <X size={16} />}\n </ModalClose>\n )}\n </div>\n </ModalHeader>\n )}\n <ModalContent className={cx(s.body, classNames?.body)} style={semanticStyles?.body}>\n {children}\n </ModalContent>\n {footer && (\n <ModalFooter\n className={cx(s.footer, classNames?.footer)}\n style={semanticStyles?.footer}\n >\n {footer}\n </ModalFooter>\n )}\n </ModalPopup>\n </ModalPortal>\n </ModalRoot>\n );\n },\n);\n\nFloatingPanel.displayName = 'FloatingPanel';\n\nexport { FloatingPanel };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { PANEL_ALIGN_INLINE_VAR, PANEL_RESERVE_VAR, TOAST_SHIFT_X_VAR, TOAST_SHIFT_Y_VAR, TOAST_WIDTH_VAR, resolveToastDodge } from "../Toast/dodge.mjs";
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/base-ui/FloatingPanel/ToastDodge.tsx
|
|
5
|
+
const TOAST_VARS = [
|
|
6
|
+
TOAST_SHIFT_X_VAR,
|
|
7
|
+
TOAST_SHIFT_Y_VAR,
|
|
8
|
+
TOAST_WIDTH_VAR
|
|
9
|
+
];
|
|
10
|
+
let owner;
|
|
11
|
+
const ToastDodge = () => {
|
|
12
|
+
const probeRef = useRef(null);
|
|
13
|
+
const reserveRef = useRef(0);
|
|
14
|
+
const tokenRef = useRef({});
|
|
15
|
+
const insetRef = useRef(void 0);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
const root = document.documentElement;
|
|
18
|
+
const panel = probeRef.current?.parentElement;
|
|
19
|
+
const token = tokenRef.current;
|
|
20
|
+
const wrapper = panel?.parentElement;
|
|
21
|
+
const clear = () => {
|
|
22
|
+
reserveRef.current = 0;
|
|
23
|
+
if (wrapper instanceof HTMLElement) {
|
|
24
|
+
wrapper.style.removeProperty(PANEL_RESERVE_VAR);
|
|
25
|
+
wrapper.style.removeProperty(PANEL_ALIGN_INLINE_VAR);
|
|
26
|
+
}
|
|
27
|
+
if (owner !== token) return;
|
|
28
|
+
owner = void 0;
|
|
29
|
+
for (const name of TOAST_VARS) root.style.removeProperty(name);
|
|
30
|
+
};
|
|
31
|
+
if (!panel) return;
|
|
32
|
+
const apply = () => {
|
|
33
|
+
if (!(panel instanceof HTMLElement) || !(wrapper instanceof HTMLElement)) return;
|
|
34
|
+
if (!insetRef.current) {
|
|
35
|
+
const padding = getComputedStyle(wrapper);
|
|
36
|
+
insetRef.current = {
|
|
37
|
+
x: Number.parseFloat(padding.paddingInlineEnd) || 0,
|
|
38
|
+
y: Number.parseFloat(padding.paddingBlockEnd) || 0
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const inset = insetRef.current;
|
|
42
|
+
const maxHeight = Number.parseFloat(getComputedStyle(panel).maxHeight);
|
|
43
|
+
const reserved = reserveRef.current;
|
|
44
|
+
const clamped = panel.offsetHeight >= maxHeight - .5 ? reserved : 0;
|
|
45
|
+
const dodge = resolveToastDodge({
|
|
46
|
+
panelHeight: panel.offsetHeight + clamped,
|
|
47
|
+
panelOffsetX: inset.x,
|
|
48
|
+
panelOffsetY: inset.y,
|
|
49
|
+
panelWidth: panel.offsetWidth,
|
|
50
|
+
viewportHeight: wrapper.clientHeight,
|
|
51
|
+
viewportWidth: wrapper.clientWidth
|
|
52
|
+
});
|
|
53
|
+
owner = token;
|
|
54
|
+
reserveRef.current = dodge.reserve;
|
|
55
|
+
root.style.setProperty(TOAST_SHIFT_X_VAR, `${dodge.shiftX}px`);
|
|
56
|
+
root.style.setProperty(TOAST_SHIFT_Y_VAR, `${dodge.shiftY}px`);
|
|
57
|
+
wrapper.style.setProperty(PANEL_RESERVE_VAR, `${dodge.reserve}px`);
|
|
58
|
+
wrapper.style.setProperty(PANEL_ALIGN_INLINE_VAR, `${dodge.alignInline}px`);
|
|
59
|
+
if (dodge.width === 360) root.style.removeProperty(TOAST_WIDTH_VAR);
|
|
60
|
+
else root.style.setProperty(TOAST_WIDTH_VAR, `${dodge.width}px`);
|
|
61
|
+
};
|
|
62
|
+
const observer = new ResizeObserver(apply);
|
|
63
|
+
observer.observe(panel);
|
|
64
|
+
window.addEventListener("resize", apply);
|
|
65
|
+
apply();
|
|
66
|
+
return () => {
|
|
67
|
+
observer.disconnect();
|
|
68
|
+
window.removeEventListener("resize", apply);
|
|
69
|
+
clear();
|
|
70
|
+
};
|
|
71
|
+
}, []);
|
|
72
|
+
return /* @__PURE__ */ jsx("span", {
|
|
73
|
+
"aria-hidden": true,
|
|
74
|
+
hidden: true,
|
|
75
|
+
ref: probeRef
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
//#endregion
|
|
79
|
+
export { ToastDodge };
|
|
80
|
+
|
|
81
|
+
//# sourceMappingURL=ToastDodge.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToastDodge.mjs","names":[],"sources":["../../../src/base-ui/FloatingPanel/ToastDodge.tsx"],"sourcesContent":["import { useEffect, useRef } from 'react';\n\nimport {\n PANEL_ALIGN_INLINE_VAR,\n PANEL_RESERVE_VAR,\n resolveToastDodge,\n TOAST_SHIFT_X_VAR,\n TOAST_SHIFT_Y_VAR,\n TOAST_WIDTH,\n TOAST_WIDTH_VAR,\n} from '../Toast/dodge';\n\nconst TOAST_VARS = [TOAST_SHIFT_X_VAR, TOAST_SHIFT_Y_VAR, TOAST_WIDTH_VAR];\n\n// A closing panel unmounts after its exit animation, so it can outlive the\n// panel that replaced it. Only the panel that wrote the vars may clear them.\nlet owner: object | undefined;\n\n// Mounted inside the panel so it lives exactly as long as the panel does, and\n// reads its own parentElement to measure it.\nexport const ToastDodge = () => {\n const probeRef = useRef<HTMLSpanElement>(null);\n const reserveRef = useRef(0);\n const tokenRef = useRef({});\n const insetRef = useRef<{ x: number; y: number }>(undefined);\n\n useEffect(() => {\n const root = document.documentElement;\n const panel = probeRef.current?.parentElement;\n\n const token = tokenRef.current;\n const wrapper = panel?.parentElement;\n const clear = () => {\n reserveRef.current = 0;\n // The reserve lives on this panel's own wrapper, so it is always ours to\n // drop; the toast vars are global and only the last writer may clear them.\n if (wrapper instanceof HTMLElement) {\n wrapper.style.removeProperty(PANEL_RESERVE_VAR);\n wrapper.style.removeProperty(PANEL_ALIGN_INLINE_VAR);\n }\n if (owner !== token) return;\n owner = undefined;\n for (const name of TOAST_VARS) root.style.removeProperty(name);\n };\n\n if (!panel) return;\n\n const apply = () => {\n if (!(panel instanceof HTMLElement) || !(wrapper instanceof HTMLElement)) return;\n // Read the resting insets once, before anything is reserved: the wrapper\n // padding animates, so sampling it later feeds the transition's midpoint\n // back into the verdict and the reserve ratchets upward every frame.\n if (!insetRef.current) {\n const padding = getComputedStyle(wrapper);\n insetRef.current = {\n x: Number.parseFloat(padding.paddingInlineEnd) || 0,\n y: Number.parseFloat(padding.paddingBlockEnd) || 0,\n };\n }\n // Layout size, never getBoundingClientRect: the rect carries the entrance\n // animation's transform, so measuring mid-flight reports a scaled-down\n // panel and the toast lands short of the gutter.\n const inset = insetRef.current;\n // Measure the panel as if it were not already yielding, otherwise the\n // reserve it applies shrinks the panel and flips the next verdict.\n // Only add the reserve back when max-height is what is holding the panel\n // down; a panel shorter than its cap was never shrunk by it.\n const maxHeight = Number.parseFloat(getComputedStyle(panel).maxHeight);\n const reserved = reserveRef.current;\n const clamped = panel.offsetHeight >= maxHeight - 0.5 ? reserved : 0;\n const dodge = resolveToastDodge({\n panelHeight: panel.offsetHeight + clamped,\n panelOffsetX: inset.x,\n panelOffsetY: inset.y,\n panelWidth: panel.offsetWidth,\n viewportHeight: wrapper.clientHeight,\n viewportWidth: wrapper.clientWidth,\n });\n\n owner = token;\n reserveRef.current = dodge.reserve;\n root.style.setProperty(TOAST_SHIFT_X_VAR, `${dodge.shiftX}px`);\n root.style.setProperty(TOAST_SHIFT_Y_VAR, `${dodge.shiftY}px`);\n wrapper.style.setProperty(PANEL_RESERVE_VAR, `${dodge.reserve}px`);\n wrapper.style.setProperty(PANEL_ALIGN_INLINE_VAR, `${dodge.alignInline}px`);\n if (dodge.width === TOAST_WIDTH) root.style.removeProperty(TOAST_WIDTH_VAR);\n else root.style.setProperty(TOAST_WIDTH_VAR, `${dodge.width}px`);\n };\n\n const observer = new ResizeObserver(apply);\n observer.observe(panel);\n window.addEventListener('resize', apply);\n apply();\n\n return () => {\n observer.disconnect();\n window.removeEventListener('resize', apply);\n clear();\n };\n }, []);\n\n return <span aria-hidden hidden ref={probeRef} />;\n};\n"],"mappings":";;;;AAYA,MAAM,aAAa;CAAC;CAAmB;CAAmB;AAAe;AAIzE,IAAI;AAIJ,MAAa,mBAAmB;CAC9B,MAAM,WAAW,OAAwB,IAAI;CAC7C,MAAM,aAAa,OAAO,CAAC;CAC3B,MAAM,WAAW,OAAO,CAAC,CAAC;CAC1B,MAAM,WAAW,OAAiC,KAAA,CAAS;CAE3D,gBAAgB;EACd,MAAM,OAAO,SAAS;EACtB,MAAM,QAAQ,SAAS,SAAS;EAEhC,MAAM,QAAQ,SAAS;EACvB,MAAM,UAAU,OAAO;EACvB,MAAM,cAAc;GAClB,WAAW,UAAU;GAGrB,IAAI,mBAAmB,aAAa;IAClC,QAAQ,MAAM,eAAe,iBAAiB;IAC9C,QAAQ,MAAM,eAAe,sBAAsB;GACrD;GACA,IAAI,UAAU,OAAO;GACrB,QAAQ,KAAA;GACR,KAAK,MAAM,QAAQ,YAAY,KAAK,MAAM,eAAe,IAAI;EAC/D;EAEA,IAAI,CAAC,OAAO;EAEZ,MAAM,cAAc;GAClB,IAAI,EAAE,iBAAiB,gBAAgB,EAAE,mBAAmB,cAAc;GAI1E,IAAI,CAAC,SAAS,SAAS;IACrB,MAAM,UAAU,iBAAiB,OAAO;IACxC,SAAS,UAAU;KACjB,GAAG,OAAO,WAAW,QAAQ,gBAAgB,KAAK;KAClD,GAAG,OAAO,WAAW,QAAQ,eAAe,KAAK;IACnD;GACF;GAIA,MAAM,QAAQ,SAAS;GAKvB,MAAM,YAAY,OAAO,WAAW,iBAAiB,KAAK,CAAC,CAAC,SAAS;GACrE,MAAM,WAAW,WAAW;GAC5B,MAAM,UAAU,MAAM,gBAAgB,YAAY,KAAM,WAAW;GACnE,MAAM,QAAQ,kBAAkB;IAC9B,aAAa,MAAM,eAAe;IAClC,cAAc,MAAM;IACpB,cAAc,MAAM;IACpB,YAAY,MAAM;IAClB,gBAAgB,QAAQ;IACxB,eAAe,QAAQ;GACzB,CAAC;GAED,QAAQ;GACR,WAAW,UAAU,MAAM;GAC3B,KAAK,MAAM,YAAY,mBAAmB,GAAG,MAAM,OAAO,GAAG;GAC7D,KAAK,MAAM,YAAY,mBAAmB,GAAG,MAAM,OAAO,GAAG;GAC7D,QAAQ,MAAM,YAAY,mBAAmB,GAAG,MAAM,QAAQ,GAAG;GACjE,QAAQ,MAAM,YAAY,wBAAwB,GAAG,MAAM,YAAY,GAAG;GAC1E,IAAI,MAAM,UAAA,KAAuB,KAAK,MAAM,eAAe,eAAe;QACrE,KAAK,MAAM,YAAY,iBAAiB,GAAG,MAAM,MAAM,GAAG;EACjE;EAEA,MAAM,WAAW,IAAI,eAAe,KAAK;EACzC,SAAS,QAAQ,KAAK;EACtB,OAAO,iBAAiB,UAAU,KAAK;EACvC,MAAM;EAEN,aAAa;GACX,SAAS,WAAW;GACpB,OAAO,oBAAoB,UAAU,KAAK;GAC1C,MAAM;EACR;CACF,GAAG,CAAC,CAAC;CAEL,OAAO,oBAAC,QAAD;EAAM,eAAA;EAAY,QAAA;EAAO,KAAK;CAAW,CAAA;AAClD"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TOAST_DODGE_DURATION, TOAST_DODGE_EASE } from "../Toast/dodge.mjs";
|
|
1
2
|
import { createStaticStyles } from "antd-style";
|
|
2
3
|
//#region src/base-ui/FloatingPanel/style.ts
|
|
3
4
|
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
@@ -40,7 +41,7 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
40
41
|
transform-origin: 100% 100%;
|
|
41
42
|
|
|
42
43
|
width: calc(100dvw - 32px);
|
|
43
|
-
max-height: calc(100dvh - 32px);
|
|
44
|
+
max-height: calc(100dvh - 32px - var(--floating-panel-reserve-block-end, 0px));
|
|
44
45
|
border-radius: 12px;
|
|
45
46
|
|
|
46
47
|
box-shadow:
|
|
@@ -169,6 +170,15 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
169
170
|
`,
|
|
170
171
|
wrapper: css`
|
|
171
172
|
overflow: hidden;
|
|
173
|
+
transition:
|
|
174
|
+
padding-block-end ${TOAST_DODGE_DURATION} ${TOAST_DODGE_EASE},
|
|
175
|
+
padding-block-start ${TOAST_DODGE_DURATION} ${TOAST_DODGE_EASE},
|
|
176
|
+
padding-inline-end ${TOAST_DODGE_DURATION} ${TOAST_DODGE_EASE},
|
|
177
|
+
padding-inline-start ${TOAST_DODGE_DURATION} ${TOAST_DODGE_EASE};
|
|
178
|
+
|
|
179
|
+
@media (prefers-reduced-motion: reduce) {
|
|
180
|
+
transition: none;
|
|
181
|
+
}
|
|
172
182
|
`
|
|
173
183
|
}));
|
|
174
184
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/base-ui/FloatingPanel/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => ({\n body: css`\n overflow: hidden auto;\n flex: 1;\n min-height: 0;\n padding: 0;\n `,\n close: css`\n position: static;\n\n width: 32px;\n height: 32px;\n margin-inline-end: -4px;\n border-radius: 8px;\n `,\n actions: css`\n display: flex;\n flex: none;\n gap: 4px;\n align-items: center;\n `,\n footer: css`\n flex: none;\n border-block-start: 1px solid ${cssVar.colorBorderSecondary};\n `,\n header: css`\n flex: none;\n min-height: 48px;\n border-block-end: 1px solid ${cssVar.colorBorderSecondary};\n `,\n headerActions: css`\n display: flex;\n flex: none;\n gap: 4px;\n align-items: center;\n `,\n panel: css`\n transform-origin: 100% 100%;\n\n width: calc(100dvw - 32px);\n max-height: calc(100dvh - 32px);\n border-radius: 12px;\n\n box-shadow:\n 0 6px 24px 0 rgb(0 0 0 / 8%),\n 0 2px 6px 0 rgb(0 0 0 / 4%);\n `,\n panelTop: css`\n transform-origin: 100% 0;\n `,\n resizeHandle: css`\n touch-action: none;\n position: absolute;\n z-index: 1;\n background: transparent;\n\n &::after {\n content: '';\n\n position: absolute;\n\n border-radius: 999px;\n\n opacity: 0;\n background: ${cssVar.colorPrimary};\n\n transition: opacity 120ms ease;\n }\n\n &:hover::after,\n &:focus-visible::after {\n opacity: 0.55;\n }\n `,\n resizeHandleBottom: css`\n cursor: ns-resize;\n inset-block-end: -4px;\n inset-inline: 16px;\n height: 8px;\n\n &::after {\n inset-block-end: 3px;\n inset-inline: 0;\n height: 2px;\n }\n `,\n resizeHandleBottomLeft: css`\n cursor: nesw-resize;\n\n inset-block-end: -5px;\n inset-inline-start: -5px;\n\n width: 16px;\n height: 16px;\n `,\n resizeHandleBottomRight: css`\n cursor: nwse-resize;\n\n inset-block-end: -5px;\n inset-inline-end: -5px;\n\n width: 16px;\n height: 16px;\n `,\n resizeHandleLeft: css`\n cursor: ew-resize;\n inset-block: 16px;\n inset-inline-start: -4px;\n width: 8px;\n\n &::after {\n inset-block: 0;\n inset-inline-start: 3px;\n width: 2px;\n }\n `,\n resizeHandleRight: css`\n cursor: ew-resize;\n inset-block: 16px;\n inset-inline-end: -4px;\n width: 8px;\n\n &::after {\n inset-block: 0;\n inset-inline-end: 3px;\n width: 2px;\n }\n `,\n resizeHandleTop: css`\n cursor: ns-resize;\n inset-block-start: -4px;\n inset-inline: 16px;\n height: 8px;\n\n &::after {\n inset-block-start: 3px;\n inset-inline: 0;\n height: 2px;\n }\n `,\n resizeHandleTopLeft: css`\n cursor: nwse-resize;\n\n inset-block-start: -5px;\n inset-inline-start: -5px;\n\n width: 16px;\n height: 16px;\n `,\n resizeHandleTopRight: css`\n cursor: nesw-resize;\n\n inset-block-start: -5px;\n inset-inline-end: -5px;\n\n width: 16px;\n height: 16px;\n `,\n title: css`\n overflow: hidden;\n flex: 1;\n\n min-width: 0;\n\n text-overflow: ellipsis;\n white-space: nowrap;\n `,\n wrapper: css`\n overflow: hidden;\n `,\n}));\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/base-ui/FloatingPanel/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nimport { TOAST_DODGE_DURATION, TOAST_DODGE_EASE } from '../Toast/dodge';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => ({\n body: css`\n overflow: hidden auto;\n flex: 1;\n min-height: 0;\n padding: 0;\n `,\n close: css`\n position: static;\n\n width: 32px;\n height: 32px;\n margin-inline-end: -4px;\n border-radius: 8px;\n `,\n actions: css`\n display: flex;\n flex: none;\n gap: 4px;\n align-items: center;\n `,\n footer: css`\n flex: none;\n border-block-start: 1px solid ${cssVar.colorBorderSecondary};\n `,\n header: css`\n flex: none;\n min-height: 48px;\n border-block-end: 1px solid ${cssVar.colorBorderSecondary};\n `,\n headerActions: css`\n display: flex;\n flex: none;\n gap: 4px;\n align-items: center;\n `,\n panel: css`\n transform-origin: 100% 100%;\n\n width: calc(100dvw - 32px);\n max-height: calc(100dvh - 32px - var(--floating-panel-reserve-block-end, 0px));\n border-radius: 12px;\n\n box-shadow:\n 0 6px 24px 0 rgb(0 0 0 / 8%),\n 0 2px 6px 0 rgb(0 0 0 / 4%);\n `,\n panelTop: css`\n transform-origin: 100% 0;\n `,\n resizeHandle: css`\n touch-action: none;\n position: absolute;\n z-index: 1;\n background: transparent;\n\n &::after {\n content: '';\n\n position: absolute;\n\n border-radius: 999px;\n\n opacity: 0;\n background: ${cssVar.colorPrimary};\n\n transition: opacity 120ms ease;\n }\n\n &:hover::after,\n &:focus-visible::after {\n opacity: 0.55;\n }\n `,\n resizeHandleBottom: css`\n cursor: ns-resize;\n inset-block-end: -4px;\n inset-inline: 16px;\n height: 8px;\n\n &::after {\n inset-block-end: 3px;\n inset-inline: 0;\n height: 2px;\n }\n `,\n resizeHandleBottomLeft: css`\n cursor: nesw-resize;\n\n inset-block-end: -5px;\n inset-inline-start: -5px;\n\n width: 16px;\n height: 16px;\n `,\n resizeHandleBottomRight: css`\n cursor: nwse-resize;\n\n inset-block-end: -5px;\n inset-inline-end: -5px;\n\n width: 16px;\n height: 16px;\n `,\n resizeHandleLeft: css`\n cursor: ew-resize;\n inset-block: 16px;\n inset-inline-start: -4px;\n width: 8px;\n\n &::after {\n inset-block: 0;\n inset-inline-start: 3px;\n width: 2px;\n }\n `,\n resizeHandleRight: css`\n cursor: ew-resize;\n inset-block: 16px;\n inset-inline-end: -4px;\n width: 8px;\n\n &::after {\n inset-block: 0;\n inset-inline-end: 3px;\n width: 2px;\n }\n `,\n resizeHandleTop: css`\n cursor: ns-resize;\n inset-block-start: -4px;\n inset-inline: 16px;\n height: 8px;\n\n &::after {\n inset-block-start: 3px;\n inset-inline: 0;\n height: 2px;\n }\n `,\n resizeHandleTopLeft: css`\n cursor: nwse-resize;\n\n inset-block-start: -5px;\n inset-inline-start: -5px;\n\n width: 16px;\n height: 16px;\n `,\n resizeHandleTopRight: css`\n cursor: nesw-resize;\n\n inset-block-start: -5px;\n inset-inline-end: -5px;\n\n width: 16px;\n height: 16px;\n `,\n title: css`\n overflow: hidden;\n flex: 1;\n\n min-width: 0;\n\n text-overflow: ellipsis;\n white-space: nowrap;\n `,\n wrapper: css`\n overflow: hidden;\n transition:\n padding-block-end ${TOAST_DODGE_DURATION} ${TOAST_DODGE_EASE},\n padding-block-start ${TOAST_DODGE_DURATION} ${TOAST_DODGE_EASE},\n padding-inline-end ${TOAST_DODGE_DURATION} ${TOAST_DODGE_EASE},\n padding-inline-start ${TOAST_DODGE_DURATION} ${TOAST_DODGE_EASE};\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `,\n}));\n"],"mappings":";;;AAIA,MAAa,SAAS,oBAAoB,EAAE,KAAK,cAAc;CAC7D,MAAM,GAAG;;;;;;CAMT,OAAO,GAAG;;;;;;;;CAQV,SAAS,GAAG;;;;;;CAMZ,QAAQ,GAAG;;oCAEuB,OAAO,qBAAqB;;CAE9D,QAAQ,GAAG;;;kCAGqB,OAAO,qBAAqB;;CAE5D,eAAe,GAAG;;;;;;CAMlB,OAAO,GAAG;;;;;;;;;;;CAWV,UAAU,GAAG;;;CAGb,cAAc,GAAG;;;;;;;;;;;;;;oBAcC,OAAO,aAAa;;;;;;;;;;CAUtC,oBAAoB,GAAG;;;;;;;;;;;;CAYvB,wBAAwB,GAAG;;;;;;;;;CAS3B,yBAAyB,GAAG;;;;;;;;;CAS5B,kBAAkB,GAAG;;;;;;;;;;;;CAYrB,mBAAmB,GAAG;;;;;;;;;;;;CAYtB,iBAAiB,GAAG;;;;;;;;;;;;CAYpB,qBAAqB,GAAG;;;;;;;;;CASxB,sBAAsB,GAAG;;;;;;;;;CASzB,OAAO,GAAG;;;;;;;;;CASV,SAAS,GAAG;;;0BAGY,qBAAqB,GAAG,iBAAiB;4BACvC,qBAAqB,GAAG,iBAAiB;2BAC1C,qBAAqB,GAAG,iBAAiB;6BACvC,qBAAqB,GAAG,iBAAiB;;;;;;AAMtE,EAAE"}
|
|
@@ -24,7 +24,7 @@ declare const styles: {
|
|
|
24
24
|
declare const rootVariants: (props?: ({
|
|
25
25
|
shadow?: boolean | null | undefined;
|
|
26
26
|
size?: "large" | "middle" | "small" | null | undefined;
|
|
27
|
-
variant?: "
|
|
27
|
+
variant?: "filled" | "borderless" | "outlined" | null | undefined;
|
|
28
28
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
29
29
|
//#endregion
|
|
30
30
|
export { rootVariants, styles };
|
|
@@ -42,7 +42,7 @@ declare const variants: (props?: ({
|
|
|
42
42
|
mark?: boolean | null | undefined;
|
|
43
43
|
shiny?: boolean | null | undefined;
|
|
44
44
|
strong?: boolean | null | undefined;
|
|
45
|
-
type?: "danger" | "
|
|
45
|
+
type?: "danger" | "success" | "info" | "warning" | "secondary" | null | undefined;
|
|
46
46
|
underline?: boolean | null | undefined;
|
|
47
47
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
48
48
|
//#endregion
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const TOAST_DODGE_DURATION = "608ms";
|
|
2
|
+
const TOAST_DODGE_EASE = "linear(0, 0.08, 0.249, 0.437, 0.607, 0.745, 0.847, 0.917, 0.963, 0.99, 1.004, 1.011, 1.012, 1.011, 1.009, 1.007, 1.005, 1.003, 1.002, 1)";
|
|
3
|
+
const TOAST_SHIFT_X_VAR = "--toast-shift-x";
|
|
4
|
+
const TOAST_SHIFT_Y_VAR = "--toast-shift-y";
|
|
5
|
+
const TOAST_WIDTH_VAR = "--toast-width";
|
|
6
|
+
const PANEL_RESERVE_VAR = "--floating-panel-reserve-block-end";
|
|
7
|
+
const PANEL_ALIGN_INLINE_VAR = "--floating-panel-reserve-inline-end";
|
|
8
|
+
const resolveToastDodge = ({ panelHeight, panelOffsetX, panelOffsetY, panelWidth, viewportHeight, viewportWidth }) => {
|
|
9
|
+
const shiftX = Math.max(0, panelWidth + panelOffsetX + 12 - 16);
|
|
10
|
+
const shiftY = Math.max(0, panelHeight + panelOffsetY + 12 - 16);
|
|
11
|
+
const lane = viewportWidth - shiftX - 32;
|
|
12
|
+
const headroom = viewportHeight - shiftY - 32;
|
|
13
|
+
const alignBlock = Math.max(0, 16 - panelOffsetY);
|
|
14
|
+
const alignInline = Math.max(0, 16 - panelOffsetX);
|
|
15
|
+
if (lane >= 360) return {
|
|
16
|
+
alignInline: 0,
|
|
17
|
+
mode: "left",
|
|
18
|
+
reserve: alignBlock,
|
|
19
|
+
shiftX,
|
|
20
|
+
shiftY: 0,
|
|
21
|
+
width: 360
|
|
22
|
+
};
|
|
23
|
+
if (headroom >= 88) return {
|
|
24
|
+
alignInline,
|
|
25
|
+
mode: "up",
|
|
26
|
+
reserve: 0,
|
|
27
|
+
shiftX: 0,
|
|
28
|
+
shiftY,
|
|
29
|
+
width: 360
|
|
30
|
+
};
|
|
31
|
+
if (lane >= 260) return {
|
|
32
|
+
alignInline: 0,
|
|
33
|
+
mode: "shrink",
|
|
34
|
+
reserve: alignBlock,
|
|
35
|
+
shiftX,
|
|
36
|
+
shiftY: 0,
|
|
37
|
+
width: lane
|
|
38
|
+
};
|
|
39
|
+
return {
|
|
40
|
+
alignInline,
|
|
41
|
+
mode: "reserve",
|
|
42
|
+
reserve: Math.max(0, 116 - panelOffsetY),
|
|
43
|
+
shiftX: 0,
|
|
44
|
+
shiftY: 0,
|
|
45
|
+
width: 360
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
//#endregion
|
|
49
|
+
export { PANEL_ALIGN_INLINE_VAR, PANEL_RESERVE_VAR, TOAST_DODGE_DURATION, TOAST_DODGE_EASE, TOAST_SHIFT_X_VAR, TOAST_SHIFT_Y_VAR, TOAST_WIDTH_VAR, resolveToastDodge };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=dodge.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dodge.mjs","names":[],"sources":["../../../src/base-ui/Toast/dodge.ts"],"sourcesContent":["export const TOAST_WIDTH = 360;\nexport const TOAST_MIN_WIDTH = 260;\nexport const TOAST_EDGE = 16;\nexport const TOAST_ROW_HEIGHT = 88;\nexport const TOAST_DODGE_GUTTER = 12;\n\n// Spring baked as linear(): stiffness 460 / damping 53 / mass 2.3, zeta ~0.81\n// with 1.2% overshoot. The duration is the spring's settle time — change them\n// together with the curve, not independently.\nexport const TOAST_DODGE_DURATION = '608ms';\nexport const TOAST_DODGE_EASE =\n 'linear(0, 0.08, 0.249, 0.437, 0.607, 0.745, 0.847, 0.917, 0.963, 0.99, 1.004, 1.011, 1.012, 1.011, 1.009, 1.007, 1.005, 1.003, 1.002, 1)';\n\nexport const TOAST_SHIFT_X_VAR = '--toast-shift-x';\nexport const TOAST_SHIFT_Y_VAR = '--toast-shift-y';\nexport const TOAST_WIDTH_VAR = '--toast-width';\nexport const PANEL_RESERVE_VAR = '--floating-panel-reserve-block-end';\nexport const PANEL_ALIGN_INLINE_VAR = '--floating-panel-reserve-inline-end';\n\nexport interface ToastDodgeInput {\n panelHeight: number;\n panelOffsetX: number;\n panelOffsetY: number;\n panelWidth: number;\n viewportHeight: number;\n viewportWidth: number;\n}\n\nexport type ToastDodgeMode = 'left' | 'reserve' | 'shrink' | 'up';\n\nexport interface ToastDodgeResult {\n alignInline: number;\n mode: ToastDodgeMode;\n reserve: number;\n shiftX: number;\n shiftY: number;\n width: number;\n}\n\nexport const resolveToastDodge = ({\n panelHeight,\n panelOffsetX,\n panelOffsetY,\n panelWidth,\n viewportHeight,\n viewportWidth,\n}: ToastDodgeInput): ToastDodgeResult => {\n const shiftX = Math.max(0, panelWidth + panelOffsetX + TOAST_DODGE_GUTTER - TOAST_EDGE);\n const shiftY = Math.max(0, panelHeight + panelOffsetY + TOAST_DODGE_GUTTER - TOAST_EDGE);\n const lane = viewportWidth - shiftX - TOAST_EDGE * 2;\n const headroom = viewportHeight - shiftY - TOAST_EDGE * 2;\n\n // The panel sits closer to the edge than the toast does, so the pair reads as\n // misaligned until the panel is pushed out to the toast's inset. Which axis\n // needs it follows which edge the two end up sharing.\n const alignBlock = Math.max(0, TOAST_EDGE - panelOffsetY);\n const alignInline = Math.max(0, TOAST_EDGE - panelOffsetX);\n\n if (lane >= TOAST_WIDTH) {\n return {\n alignInline: 0,\n mode: 'left',\n reserve: alignBlock,\n shiftX,\n shiftY: 0,\n width: TOAST_WIDTH,\n };\n }\n\n if (headroom >= TOAST_ROW_HEIGHT) {\n return { alignInline, mode: 'up', reserve: 0, shiftX: 0, shiftY, width: TOAST_WIDTH };\n }\n\n if (lane >= TOAST_MIN_WIDTH) {\n return { alignInline: 0, mode: 'shrink', reserve: alignBlock, shiftX, shiftY: 0, width: lane };\n }\n\n // ponytail: the reserve budget is one toast row, not the live stack height —\n // measuring the stack would feed panel resizes back into the measurement.\n // A taller stack overflows upward here; per-stack reserve if that shows up.\n return {\n alignInline,\n mode: 'reserve',\n reserve: Math.max(0, TOAST_EDGE + TOAST_ROW_HEIGHT + TOAST_DODGE_GUTTER - panelOffsetY),\n shiftX: 0,\n shiftY: 0,\n width: TOAST_WIDTH,\n };\n};\n"],"mappings":"AASA,MAAa,uBAAuB;AACpC,MAAa,mBACX;AAEF,MAAa,oBAAoB;AACjC,MAAa,oBAAoB;AACjC,MAAa,kBAAkB;AAC/B,MAAa,oBAAoB;AACjC,MAAa,yBAAyB;AAsBtC,MAAa,qBAAqB,EAChC,aACA,cACA,cACA,YACA,gBACA,oBACuC;CACvC,MAAM,SAAS,KAAK,IAAI,GAAG,aAAa,eAAA,KAAA,EAA8C;CACtF,MAAM,SAAS,KAAK,IAAI,GAAG,cAAc,eAAA,KAAA,EAA8C;CACvF,MAAM,OAAO,gBAAgB,SAAS;CACtC,MAAM,WAAW,iBAAiB,SAAS;CAK3C,MAAM,aAAa,KAAK,IAAI,GAAA,KAAgB,YAAY;CACxD,MAAM,cAAc,KAAK,IAAI,GAAA,KAAgB,YAAY;CAEzD,IAAI,QAAA,KACF,OAAO;EACL,aAAa;EACb,MAAM;EACN,SAAS;EACT;EACA,QAAQ;EACR,OAAA;CACF;CAGF,IAAI,YAAA,IACF,OAAO;EAAE;EAAa,MAAM;EAAM,SAAS;EAAG,QAAQ;EAAG;EAAQ,OAAA;CAAmB;CAGtF,IAAI,QAAA,KACF,OAAO;EAAE,aAAa;EAAG,MAAM;EAAU,SAAS;EAAY;EAAQ,QAAQ;EAAG,OAAO;CAAK;CAM/F,OAAO;EACL;EACA,MAAM;EACN,SAAS,KAAK,IAAI,GAAG,MAAqD,YAAY;EACtF,QAAQ;EACR,QAAQ;EACR,OAAA;CACF;AACF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { focusRing, focusRingColor } from "../focusRing.mjs";
|
|
2
|
+
import { TOAST_DODGE_DURATION, TOAST_DODGE_EASE } from "./dodge.mjs";
|
|
2
3
|
import { createStaticStyles } from "antd-style";
|
|
3
4
|
import { cva } from "class-variance-authority";
|
|
4
5
|
//#region src/base-ui/Toast/style.ts
|
|
@@ -309,7 +310,7 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
309
310
|
position: fixed;
|
|
310
311
|
z-index: 100000;
|
|
311
312
|
|
|
312
|
-
width: 360px;
|
|
313
|
+
width: var(--toast-width, 360px);
|
|
313
314
|
max-width: calc(100vw - var(--toast-viewport-offset-x, 16px) * 2);
|
|
314
315
|
|
|
315
316
|
outline: 0;
|
|
@@ -330,6 +331,18 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
330
331
|
viewportBottomRight: css`
|
|
331
332
|
inset-block-end: var(--toast-viewport-offset-y, 16px);
|
|
332
333
|
inset-inline-end: var(--toast-viewport-offset-x, 16px);
|
|
334
|
+
|
|
335
|
+
/* Percentages in translate() resolve against the element itself, not the
|
|
336
|
+
viewport, so the dodge offsets have to stay in px. */
|
|
337
|
+
transform: translate(
|
|
338
|
+
calc(-1 * var(--toast-shift-x, 0px)),
|
|
339
|
+
calc(-1 * var(--toast-shift-y, 0px))
|
|
340
|
+
);
|
|
341
|
+
transition: transform ${TOAST_DODGE_DURATION} ${TOAST_DODGE_EASE};
|
|
342
|
+
|
|
343
|
+
@media (prefers-reduced-motion: reduce) {
|
|
344
|
+
transition: none;
|
|
345
|
+
}
|
|
333
346
|
`,
|
|
334
347
|
viewportTop: css`
|
|
335
348
|
inset-block-start: var(--toast-viewport-offset-y, 16px);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/base-ui/Toast/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\nimport { cva } from 'class-variance-authority';\n\nimport { focusRing, focusRingColor } from '@/base-ui/focusRing';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => ({\n action: css`\n cursor: pointer;\n\n display: inline-flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n height: 28px;\n padding-inline: 12px;\n border: none;\n border-radius: ${cssVar.borderRadiusSM};\n\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n\n transition:\n background 0.2s,\n color 0.2s;\n\n ${focusRing};\n `,\n\n actionDanger: css`\n color: ${cssVar.colorBgLayout};\n background: ${cssVar.colorError};\n\n &:hover {\n background: ${cssVar.colorErrorHover};\n }\n\n &:active {\n background: ${cssVar.colorErrorActive};\n }\n\n ${focusRingColor(cssVar.colorError)};\n `,\n\n actionGhost: css`\n border: 1px solid ${cssVar.colorBorder};\n color: ${cssVar.colorText};\n background: transparent;\n\n &:hover {\n border-color: ${cssVar.colorPrimary};\n color: ${cssVar.colorPrimary};\n }\n\n &:active {\n border-color: ${cssVar.colorPrimaryActive};\n color: ${cssVar.colorPrimaryActive};\n }\n `,\n\n actionPrimary: css`\n color: ${cssVar.colorBgLayout};\n background: ${cssVar.colorPrimary};\n\n &:hover {\n background: ${cssVar.colorPrimaryHover};\n }\n\n &:active {\n background: ${cssVar.colorPrimaryActive};\n }\n `,\n\n actionSecondary: css`\n color: ${cssVar.colorText};\n background: ${cssVar.colorFillSecondary};\n\n &:hover {\n background: ${cssVar.colorFillTertiary};\n }\n\n &:active {\n background: ${cssVar.colorFill};\n }\n `,\n\n actionText: css`\n color: ${cssVar.colorPrimary};\n background: transparent;\n\n &:hover {\n background: ${cssVar.colorFillTertiary};\n }\n\n &:active {\n background: ${cssVar.colorFillSecondary};\n }\n `,\n\n actions: css`\n display: flex;\n flex-grow: 1;\n flex-shrink: 0;\n gap: 8px;\n align-items: center;\n align-self: flex-end;\n justify-content: flex-end;\n\n margin-block-start: 8px;\n `,\n\n close: css`\n cursor: pointer;\n\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: 20px;\n height: 20px;\n margin-inline-start: auto;\n padding: 0;\n border: none;\n border-radius: ${cssVar.borderRadiusSM};\n\n color: ${cssVar.colorTextSecondary};\n\n background: transparent;\n\n transition: all 0.2s;\n\n &:hover {\n color: ${cssVar.colorText};\n background: ${cssVar.colorFillSecondary};\n }\n `,\n\n content: css`\n overflow: hidden;\n transition: opacity 0.2s;\n\n &[data-behind] {\n pointer-events: none;\n opacity: 0;\n }\n\n &[data-expanded] {\n pointer-events: auto;\n opacity: 1;\n }\n `,\n\n contentArea: css`\n display: flex;\n flex: 1;\n flex-direction: column;\n min-width: 0;\n `,\n\n description: css`\n margin: 0;\n font-size: 13px;\n line-height: 1.5;\n color: ${cssVar.colorTextSecondary};\n `,\n\n descriptionStandalone: css`\n color: ${cssVar.colorText};\n `,\n\n icon: css`\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n `,\n\n root: css`\n --toast-gap: 12px;\n --toast-peek: 12px;\n --toast-scale: calc(1 - var(--toast-index) * 0.05);\n --toast-shrink: calc(1 - var(--toast-scale));\n --toast-collapsed-height: var(--toast-frontmost-height, var(--toast-height));\n\n cursor: default;\n user-select: none;\n\n position: absolute;\n z-index: calc(1000 - var(--toast-index));\n inset-inline: 0;\n\n box-sizing: border-box;\n width: 100%;\n height: var(--toast-collapsed-height);\n padding-block: 12px;\n padding-inline: 16px;\n border-radius: var(--toast-border-radius, ${cssVar.borderRadiusLG});\n\n color: ${cssVar.colorText};\n\n background: ${cssVar.colorBgElevated};\n background-clip: padding-box;\n box-shadow:\n 0 0 0 1px ${cssVar.colorBorderSecondary},\n 0 4px 12px rgb(0 0 0 / 10%),\n 0 16px 32px -8px rgb(0 0 0 / 12%);\n\n transition:\n transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),\n opacity 0.4s,\n height 0.15s;\n\n /* Fill gap between stacked toasts to prevent hover flicker */\n &::after {\n content: '';\n position: absolute;\n inset-inline: 0;\n height: calc(var(--toast-gap) + var(--toast-peek) + 8px);\n }\n\n &[data-limited] {\n opacity: 0;\n }\n\n &[data-swiping] {\n transition: none;\n }\n `,\n\n // Bottom positions - stack upward\n rootBottom: css`\n inset-block: auto 0;\n transform-origin: bottom center;\n transform: translateX(var(--toast-swipe-movement-x))\n translateY(\n calc(\n var(--toast-swipe-movement-y) - (var(--toast-index) * var(--toast-peek)) -\n (var(--toast-shrink) * var(--toast-collapsed-height))\n )\n )\n scale(var(--toast-scale));\n\n &::after {\n inset-block-start: 100%;\n }\n\n &[data-expanded] {\n transform: translateX(var(--toast-swipe-movement-x))\n translateY(\n calc(\n var(--toast-swipe-movement-y) + var(--toast-offset-y) * -1 + var(--toast-index) *\n var(--toast-gap) * -1\n )\n )\n scale(1);\n height: var(--toast-height);\n }\n\n &[data-starting-style],\n &[data-ending-style] {\n transform: translateY(150%);\n opacity: 0;\n }\n `,\n\n // Top positions - stack downward\n rootTop: css`\n inset-block: 0 auto;\n transform-origin: top center;\n transform: translateX(var(--toast-swipe-movement-x))\n translateY(\n calc(\n var(--toast-swipe-movement-y) + (var(--toast-index) * var(--toast-peek)) +\n (var(--toast-shrink) * var(--toast-collapsed-height))\n )\n )\n scale(var(--toast-scale));\n\n &::after {\n inset-block-end: 100%;\n }\n\n &[data-expanded] {\n transform: translateX(var(--toast-swipe-movement-x))\n translateY(\n calc(\n var(--toast-swipe-movement-y) + var(--toast-offset-y) + var(--toast-index) *\n var(--toast-gap)\n )\n )\n scale(1);\n height: var(--toast-height);\n }\n\n &[data-starting-style],\n &[data-ending-style] {\n transform: translateY(-150%);\n opacity: 0;\n }\n `,\n\n title: css`\n margin: 0;\n\n font-size: 14px;\n font-weight: 500;\n line-height: 1.5;\n color: ${cssVar.colorText};\n `,\n\n titleRow: css`\n display: flex;\n gap: 8px;\n align-items: flex-start;\n `,\n\n toastBody: css`\n display: flex;\n gap: 12px;\n align-items: flex-start;\n `,\n\n toastBodyCenter: css`\n display: flex;\n gap: 12px;\n align-items: flex-start;\n `,\n\n viewport: css`\n position: fixed;\n z-index: 100000;\n\n width: 360px;\n max-width: calc(100vw - var(--toast-viewport-offset-x, 16px) * 2);\n\n outline: 0;\n\n @media (width <= 480px) {\n width: calc(100vw - var(--toast-viewport-offset-x, 16px) * 2);\n }\n `,\n\n viewportBottom: css`\n inset-block-end: var(--toast-viewport-offset-y, 16px);\n inset-inline-start: 50%;\n transform: translateX(-50%);\n `,\n\n viewportBottomLeft: css`\n inset-block-end: var(--toast-viewport-offset-y, 16px);\n inset-inline-start: var(--toast-viewport-offset-x, 16px);\n `,\n\n viewportBottomRight: css`\n inset-block-end: var(--toast-viewport-offset-y, 16px);\n inset-inline-end: var(--toast-viewport-offset-x, 16px);\n `,\n\n viewportTop: css`\n inset-block-start: var(--toast-viewport-offset-y, 16px);\n inset-inline-start: 50%;\n transform: translateX(-50%);\n `,\n\n viewportTopLeft: css`\n inset-block-start: var(--toast-viewport-offset-y, 16px);\n inset-inline-start: var(--toast-viewport-offset-x, 16px);\n `,\n\n viewportTopRight: css`\n inset-block-start: var(--toast-viewport-offset-y, 16px);\n inset-inline-end: var(--toast-viewport-offset-x, 16px);\n `,\n}));\n\nexport const viewportVariants = cva(styles.viewport, {\n defaultVariants: {\n position: 'bottom-right',\n },\n variants: {\n position: {\n 'bottom': styles.viewportBottom,\n 'bottom-left': styles.viewportBottomLeft,\n 'bottom-right': styles.viewportBottomRight,\n 'top': styles.viewportTop,\n 'top-left': styles.viewportTopLeft,\n 'top-right': styles.viewportTopRight,\n },\n },\n});\n\nexport const rootVariants = cva(styles.root, {\n defaultVariants: {\n position: 'bottom-right',\n },\n variants: {\n position: {\n 'bottom': styles.rootBottom,\n 'bottom-left': styles.rootBottom,\n 'bottom-right': styles.rootBottom,\n 'top': styles.rootTop,\n 'top-left': styles.rootTop,\n 'top-right': styles.rootTop,\n },\n },\n});\n\nexport const actionVariants = cva(styles.action, {\n defaultVariants: {\n variant: 'primary',\n },\n variants: {\n variant: {\n danger: styles.actionDanger,\n ghost: styles.actionGhost,\n primary: styles.actionPrimary,\n secondary: styles.actionSecondary,\n text: styles.actionText,\n },\n },\n});\n"],"mappings":";;;;AAKA,MAAa,SAAS,oBAAoB,EAAE,KAAK,cAAc;CAC7D,QAAQ,GAAG;;;;;;;;;;;qBAWQ,OAAO,eAAe;;;;;;;;;;MAUrC,UAAU;;CAGd,cAAc,GAAG;aACN,OAAO,cAAc;kBAChB,OAAO,WAAW;;;oBAGhB,OAAO,gBAAgB;;;;oBAIvB,OAAO,iBAAiB;;;MAGtC,eAAe,OAAO,UAAU,EAAE;;CAGtC,aAAa,GAAG;wBACM,OAAO,YAAY;aAC9B,OAAO,UAAU;;;;sBAIR,OAAO,aAAa;eAC3B,OAAO,aAAa;;;;sBAIb,OAAO,mBAAmB;eACjC,OAAO,mBAAmB;;;CAIvC,eAAe,GAAG;aACP,OAAO,cAAc;kBAChB,OAAO,aAAa;;;oBAGlB,OAAO,kBAAkB;;;;oBAIzB,OAAO,mBAAmB;;;CAI5C,iBAAiB,GAAG;aACT,OAAO,UAAU;kBACZ,OAAO,mBAAmB;;;oBAGxB,OAAO,kBAAkB;;;;oBAIzB,OAAO,UAAU;;;CAInC,YAAY,GAAG;aACJ,OAAO,aAAa;;;;oBAIb,OAAO,kBAAkB;;;;oBAIzB,OAAO,mBAAmB;;;CAI5C,SAAS,GAAG;;;;;;;;;;;CAYZ,OAAO,GAAG;;;;;;;;;;;;;qBAaS,OAAO,eAAe;;aAE9B,OAAO,mBAAmB;;;;;;;eAOxB,OAAO,UAAU;oBACZ,OAAO,mBAAmB;;;CAI5C,SAAS,GAAG;;;;;;;;;;;;;;CAeZ,aAAa,GAAG;;;;;;CAOhB,aAAa,GAAG;;;;aAIL,OAAO,mBAAmB;;CAGrC,uBAAuB,GAAG;aACf,OAAO,UAAU;;CAG5B,MAAM,GAAG;;;;;;CAOT,MAAM,GAAG;;;;;;;;;;;;;;;;;;;gDAmBqC,OAAO,eAAe;;aAEzD,OAAO,UAAU;;kBAEZ,OAAO,gBAAgB;;;kBAGvB,OAAO,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;CA2B5C,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCf,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCZ,OAAO,GAAG;;;;;;aAMC,OAAO,UAAU;;CAG5B,UAAU,GAAG;;;;;CAMb,WAAW,GAAG;;;;;CAMd,iBAAiB,GAAG;;;;;CAMpB,UAAU,GAAG;;;;;;;;;;;;;CAcb,gBAAgB,GAAG;;;;;CAMnB,oBAAoB,GAAG;;;;CAKvB,qBAAqB,GAAG;;;;CAKxB,aAAa,GAAG;;;;;CAMhB,iBAAiB,GAAG;;;;CAKpB,kBAAkB,GAAG;;;;AAIvB,EAAE;AAEF,MAAa,mBAAmB,IAAI,OAAO,UAAU;CACnD,iBAAiB,EACf,UAAU,eACZ;CACA,UAAU,EACR,UAAU;EACR,UAAU,OAAO;EACjB,eAAe,OAAO;EACtB,gBAAgB,OAAO;EACvB,OAAO,OAAO;EACd,YAAY,OAAO;EACnB,aAAa,OAAO;CACtB,EACF;AACF,CAAC;AAED,MAAa,eAAe,IAAI,OAAO,MAAM;CAC3C,iBAAiB,EACf,UAAU,eACZ;CACA,UAAU,EACR,UAAU;EACR,UAAU,OAAO;EACjB,eAAe,OAAO;EACtB,gBAAgB,OAAO;EACvB,OAAO,OAAO;EACd,YAAY,OAAO;EACnB,aAAa,OAAO;CACtB,EACF;AACF,CAAC;AAED,MAAa,iBAAiB,IAAI,OAAO,QAAQ;CAC/C,iBAAiB,EACf,SAAS,UACX;CACA,UAAU,EACR,SAAS;EACP,QAAQ,OAAO;EACf,OAAO,OAAO;EACd,SAAS,OAAO;EAChB,WAAW,OAAO;EAClB,MAAM,OAAO;CACf,EACF;AACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/base-ui/Toast/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\nimport { cva } from 'class-variance-authority';\n\nimport { focusRing, focusRingColor } from '@/base-ui/focusRing';\n\nimport { TOAST_DODGE_DURATION, TOAST_DODGE_EASE } from './dodge';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => ({\n action: css`\n cursor: pointer;\n\n display: inline-flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n height: 28px;\n padding-inline: 12px;\n border: none;\n border-radius: ${cssVar.borderRadiusSM};\n\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n\n transition:\n background 0.2s,\n color 0.2s;\n\n ${focusRing};\n `,\n\n actionDanger: css`\n color: ${cssVar.colorBgLayout};\n background: ${cssVar.colorError};\n\n &:hover {\n background: ${cssVar.colorErrorHover};\n }\n\n &:active {\n background: ${cssVar.colorErrorActive};\n }\n\n ${focusRingColor(cssVar.colorError)};\n `,\n\n actionGhost: css`\n border: 1px solid ${cssVar.colorBorder};\n color: ${cssVar.colorText};\n background: transparent;\n\n &:hover {\n border-color: ${cssVar.colorPrimary};\n color: ${cssVar.colorPrimary};\n }\n\n &:active {\n border-color: ${cssVar.colorPrimaryActive};\n color: ${cssVar.colorPrimaryActive};\n }\n `,\n\n actionPrimary: css`\n color: ${cssVar.colorBgLayout};\n background: ${cssVar.colorPrimary};\n\n &:hover {\n background: ${cssVar.colorPrimaryHover};\n }\n\n &:active {\n background: ${cssVar.colorPrimaryActive};\n }\n `,\n\n actionSecondary: css`\n color: ${cssVar.colorText};\n background: ${cssVar.colorFillSecondary};\n\n &:hover {\n background: ${cssVar.colorFillTertiary};\n }\n\n &:active {\n background: ${cssVar.colorFill};\n }\n `,\n\n actionText: css`\n color: ${cssVar.colorPrimary};\n background: transparent;\n\n &:hover {\n background: ${cssVar.colorFillTertiary};\n }\n\n &:active {\n background: ${cssVar.colorFillSecondary};\n }\n `,\n\n actions: css`\n display: flex;\n flex-grow: 1;\n flex-shrink: 0;\n gap: 8px;\n align-items: center;\n align-self: flex-end;\n justify-content: flex-end;\n\n margin-block-start: 8px;\n `,\n\n close: css`\n cursor: pointer;\n\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: 20px;\n height: 20px;\n margin-inline-start: auto;\n padding: 0;\n border: none;\n border-radius: ${cssVar.borderRadiusSM};\n\n color: ${cssVar.colorTextSecondary};\n\n background: transparent;\n\n transition: all 0.2s;\n\n &:hover {\n color: ${cssVar.colorText};\n background: ${cssVar.colorFillSecondary};\n }\n `,\n\n content: css`\n overflow: hidden;\n transition: opacity 0.2s;\n\n &[data-behind] {\n pointer-events: none;\n opacity: 0;\n }\n\n &[data-expanded] {\n pointer-events: auto;\n opacity: 1;\n }\n `,\n\n contentArea: css`\n display: flex;\n flex: 1;\n flex-direction: column;\n min-width: 0;\n `,\n\n description: css`\n margin: 0;\n font-size: 13px;\n line-height: 1.5;\n color: ${cssVar.colorTextSecondary};\n `,\n\n descriptionStandalone: css`\n color: ${cssVar.colorText};\n `,\n\n icon: css`\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n `,\n\n root: css`\n --toast-gap: 12px;\n --toast-peek: 12px;\n --toast-scale: calc(1 - var(--toast-index) * 0.05);\n --toast-shrink: calc(1 - var(--toast-scale));\n --toast-collapsed-height: var(--toast-frontmost-height, var(--toast-height));\n\n cursor: default;\n user-select: none;\n\n position: absolute;\n z-index: calc(1000 - var(--toast-index));\n inset-inline: 0;\n\n box-sizing: border-box;\n width: 100%;\n height: var(--toast-collapsed-height);\n padding-block: 12px;\n padding-inline: 16px;\n border-radius: var(--toast-border-radius, ${cssVar.borderRadiusLG});\n\n color: ${cssVar.colorText};\n\n background: ${cssVar.colorBgElevated};\n background-clip: padding-box;\n box-shadow:\n 0 0 0 1px ${cssVar.colorBorderSecondary},\n 0 4px 12px rgb(0 0 0 / 10%),\n 0 16px 32px -8px rgb(0 0 0 / 12%);\n\n transition:\n transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),\n opacity 0.4s,\n height 0.15s;\n\n /* Fill gap between stacked toasts to prevent hover flicker */\n &::after {\n content: '';\n position: absolute;\n inset-inline: 0;\n height: calc(var(--toast-gap) + var(--toast-peek) + 8px);\n }\n\n &[data-limited] {\n opacity: 0;\n }\n\n &[data-swiping] {\n transition: none;\n }\n `,\n\n // Bottom positions - stack upward\n rootBottom: css`\n inset-block: auto 0;\n transform-origin: bottom center;\n transform: translateX(var(--toast-swipe-movement-x))\n translateY(\n calc(\n var(--toast-swipe-movement-y) - (var(--toast-index) * var(--toast-peek)) -\n (var(--toast-shrink) * var(--toast-collapsed-height))\n )\n )\n scale(var(--toast-scale));\n\n &::after {\n inset-block-start: 100%;\n }\n\n &[data-expanded] {\n transform: translateX(var(--toast-swipe-movement-x))\n translateY(\n calc(\n var(--toast-swipe-movement-y) + var(--toast-offset-y) * -1 + var(--toast-index) *\n var(--toast-gap) * -1\n )\n )\n scale(1);\n height: var(--toast-height);\n }\n\n &[data-starting-style],\n &[data-ending-style] {\n transform: translateY(150%);\n opacity: 0;\n }\n `,\n\n // Top positions - stack downward\n rootTop: css`\n inset-block: 0 auto;\n transform-origin: top center;\n transform: translateX(var(--toast-swipe-movement-x))\n translateY(\n calc(\n var(--toast-swipe-movement-y) + (var(--toast-index) * var(--toast-peek)) +\n (var(--toast-shrink) * var(--toast-collapsed-height))\n )\n )\n scale(var(--toast-scale));\n\n &::after {\n inset-block-end: 100%;\n }\n\n &[data-expanded] {\n transform: translateX(var(--toast-swipe-movement-x))\n translateY(\n calc(\n var(--toast-swipe-movement-y) + var(--toast-offset-y) + var(--toast-index) *\n var(--toast-gap)\n )\n )\n scale(1);\n height: var(--toast-height);\n }\n\n &[data-starting-style],\n &[data-ending-style] {\n transform: translateY(-150%);\n opacity: 0;\n }\n `,\n\n title: css`\n margin: 0;\n\n font-size: 14px;\n font-weight: 500;\n line-height: 1.5;\n color: ${cssVar.colorText};\n `,\n\n titleRow: css`\n display: flex;\n gap: 8px;\n align-items: flex-start;\n `,\n\n toastBody: css`\n display: flex;\n gap: 12px;\n align-items: flex-start;\n `,\n\n toastBodyCenter: css`\n display: flex;\n gap: 12px;\n align-items: flex-start;\n `,\n\n viewport: css`\n position: fixed;\n z-index: 100000;\n\n width: var(--toast-width, 360px);\n max-width: calc(100vw - var(--toast-viewport-offset-x, 16px) * 2);\n\n outline: 0;\n\n @media (width <= 480px) {\n width: calc(100vw - var(--toast-viewport-offset-x, 16px) * 2);\n }\n `,\n\n viewportBottom: css`\n inset-block-end: var(--toast-viewport-offset-y, 16px);\n inset-inline-start: 50%;\n transform: translateX(-50%);\n `,\n\n viewportBottomLeft: css`\n inset-block-end: var(--toast-viewport-offset-y, 16px);\n inset-inline-start: var(--toast-viewport-offset-x, 16px);\n `,\n\n viewportBottomRight: css`\n inset-block-end: var(--toast-viewport-offset-y, 16px);\n inset-inline-end: var(--toast-viewport-offset-x, 16px);\n\n /* Percentages in translate() resolve against the element itself, not the\n viewport, so the dodge offsets have to stay in px. */\n transform: translate(\n calc(-1 * var(--toast-shift-x, 0px)),\n calc(-1 * var(--toast-shift-y, 0px))\n );\n transition: transform ${TOAST_DODGE_DURATION} ${TOAST_DODGE_EASE};\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `,\n\n viewportTop: css`\n inset-block-start: var(--toast-viewport-offset-y, 16px);\n inset-inline-start: 50%;\n transform: translateX(-50%);\n `,\n\n viewportTopLeft: css`\n inset-block-start: var(--toast-viewport-offset-y, 16px);\n inset-inline-start: var(--toast-viewport-offset-x, 16px);\n `,\n\n viewportTopRight: css`\n inset-block-start: var(--toast-viewport-offset-y, 16px);\n inset-inline-end: var(--toast-viewport-offset-x, 16px);\n `,\n}));\n\nexport const viewportVariants = cva(styles.viewport, {\n defaultVariants: {\n position: 'bottom-right',\n },\n variants: {\n position: {\n 'bottom': styles.viewportBottom,\n 'bottom-left': styles.viewportBottomLeft,\n 'bottom-right': styles.viewportBottomRight,\n 'top': styles.viewportTop,\n 'top-left': styles.viewportTopLeft,\n 'top-right': styles.viewportTopRight,\n },\n },\n});\n\nexport const rootVariants = cva(styles.root, {\n defaultVariants: {\n position: 'bottom-right',\n },\n variants: {\n position: {\n 'bottom': styles.rootBottom,\n 'bottom-left': styles.rootBottom,\n 'bottom-right': styles.rootBottom,\n 'top': styles.rootTop,\n 'top-left': styles.rootTop,\n 'top-right': styles.rootTop,\n },\n },\n});\n\nexport const actionVariants = cva(styles.action, {\n defaultVariants: {\n variant: 'primary',\n },\n variants: {\n variant: {\n danger: styles.actionDanger,\n ghost: styles.actionGhost,\n primary: styles.actionPrimary,\n secondary: styles.actionSecondary,\n text: styles.actionText,\n },\n },\n});\n"],"mappings":";;;;;AAOA,MAAa,SAAS,oBAAoB,EAAE,KAAK,cAAc;CAC7D,QAAQ,GAAG;;;;;;;;;;;qBAWQ,OAAO,eAAe;;;;;;;;;;MAUrC,UAAU;;CAGd,cAAc,GAAG;aACN,OAAO,cAAc;kBAChB,OAAO,WAAW;;;oBAGhB,OAAO,gBAAgB;;;;oBAIvB,OAAO,iBAAiB;;;MAGtC,eAAe,OAAO,UAAU,EAAE;;CAGtC,aAAa,GAAG;wBACM,OAAO,YAAY;aAC9B,OAAO,UAAU;;;;sBAIR,OAAO,aAAa;eAC3B,OAAO,aAAa;;;;sBAIb,OAAO,mBAAmB;eACjC,OAAO,mBAAmB;;;CAIvC,eAAe,GAAG;aACP,OAAO,cAAc;kBAChB,OAAO,aAAa;;;oBAGlB,OAAO,kBAAkB;;;;oBAIzB,OAAO,mBAAmB;;;CAI5C,iBAAiB,GAAG;aACT,OAAO,UAAU;kBACZ,OAAO,mBAAmB;;;oBAGxB,OAAO,kBAAkB;;;;oBAIzB,OAAO,UAAU;;;CAInC,YAAY,GAAG;aACJ,OAAO,aAAa;;;;oBAIb,OAAO,kBAAkB;;;;oBAIzB,OAAO,mBAAmB;;;CAI5C,SAAS,GAAG;;;;;;;;;;;CAYZ,OAAO,GAAG;;;;;;;;;;;;;qBAaS,OAAO,eAAe;;aAE9B,OAAO,mBAAmB;;;;;;;eAOxB,OAAO,UAAU;oBACZ,OAAO,mBAAmB;;;CAI5C,SAAS,GAAG;;;;;;;;;;;;;;CAeZ,aAAa,GAAG;;;;;;CAOhB,aAAa,GAAG;;;;aAIL,OAAO,mBAAmB;;CAGrC,uBAAuB,GAAG;aACf,OAAO,UAAU;;CAG5B,MAAM,GAAG;;;;;;CAOT,MAAM,GAAG;;;;;;;;;;;;;;;;;;;gDAmBqC,OAAO,eAAe;;aAEzD,OAAO,UAAU;;kBAEZ,OAAO,gBAAgB;;;kBAGvB,OAAO,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;CA2B5C,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCf,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCZ,OAAO,GAAG;;;;;;aAMC,OAAO,UAAU;;CAG5B,UAAU,GAAG;;;;;CAMb,WAAW,GAAG;;;;;CAMd,iBAAiB,GAAG;;;;;CAMpB,UAAU,GAAG;;;;;;;;;;;;;CAcb,gBAAgB,GAAG;;;;;CAMnB,oBAAoB,GAAG;;;;CAKvB,qBAAqB,GAAG;;;;;;;;;;4BAUE,qBAAqB,GAAG,iBAAiB;;;;;;CAOnE,aAAa,GAAG;;;;;CAMhB,iBAAiB,GAAG;;;;CAKpB,kBAAkB,GAAG;;;;AAIvB,EAAE;AAEF,MAAa,mBAAmB,IAAI,OAAO,UAAU;CACnD,iBAAiB,EACf,UAAU,eACZ;CACA,UAAU,EACR,UAAU;EACR,UAAU,OAAO;EACjB,eAAe,OAAO;EACtB,gBAAgB,OAAO;EACvB,OAAO,OAAO;EACd,YAAY,OAAO;EACnB,aAAa,OAAO;CACtB,EACF;AACF,CAAC;AAED,MAAa,eAAe,IAAI,OAAO,MAAM;CAC3C,iBAAiB,EACf,UAAU,eACZ;CACA,UAAU,EACR,UAAU;EACR,UAAU,OAAO;EACjB,eAAe,OAAO;EACtB,gBAAgB,OAAO;EACvB,OAAO,OAAO;EACd,YAAY,OAAO;EACnB,aAAa,OAAO;CACtB,EACF;AACF,CAAC;AAED,MAAa,iBAAiB,IAAI,OAAO,QAAQ;CAC/C,iBAAiB,EACf,SAAS,UACX;CACA,UAAU,EACR,SAAS;EACP,QAAQ,OAAO;EACf,OAAO,OAAO;EACd,SAAS,OAAO;EAChB,WAAW,OAAO;EAClB,MAAM,OAAO;CACf,EACF;AACF,CAAC"}
|