@transferwise/components 0.0.0-experimental-1ce1b08 → 0.0.0-experimental-02e6e73

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.
@@ -70,7 +70,7 @@ const Snackbar = ({
70
70
  visible
71
71
  });
72
72
  const {
73
- clearSwipePosition,
73
+ cancelSwipe,
74
74
  containerRef,
75
75
  handleClickCapture,
76
76
  handlePointerCancel,
@@ -79,8 +79,7 @@ const Snackbar = ({
79
79
  handlePointerUp
80
80
  } = useSnackbarSwipeDismiss.default({
81
81
  onDismissRequest,
82
- onSwipeChange: setSwiping,
83
- visible
82
+ onSwipeChange: setSwiping
84
83
  });
85
84
  React.useEffect(() => {
86
85
  if (!visible) {
@@ -149,10 +148,8 @@ const Snackbar = ({
149
148
  },
150
149
  unmountOnExit: true,
151
150
  onEntered: handleEntered,
152
- onExited: () => {
153
- clearSwipePosition();
154
- onExited();
155
- },
151
+ onExit: cancelSwipe,
152
+ onExited: onExited,
156
153
  children: /*#__PURE__*/jsxRuntime.jsx(PrimitivePrompt.PrimitivePrompt, {
157
154
  ref: surfaceRef,
158
155
  className: "wds-Snackbar-container",
@@ -1 +1 @@
1
- {"version":3,"file":"Snackbar.js","sources":["../../../src/Prompt/Snackbar/Snackbar.tsx"],"sourcesContent":["import { Tags } from '@transferwise/icons';\nimport { useEffect } from 'react';\nimport { useIntl } from 'react-intl';\nimport { CSSTransition } from 'react-transition-group';\n\nimport Button, { type ButtonReferenceType } from '../../Button';\nimport Body from '../../Body';\nimport { LiveRegion } from '../../common';\nimport type { ThemeDark, ThemeLight } from '../../common';\nimport { PrimitivePrompt } from '../PrimitivePrompt';\nimport ProcessIndicator from '../../ProcessIndicator';\nimport type { Sentiment } from '../../SentimentSurface';\nimport StatusIcon from '../../StatusIcon';\n\nimport { SNACKBAR_ENTER_DURATION, SNACKBAR_EXIT_DURATION } from './constants';\nimport messages from './Snackbar.messages';\nimport type { SnackbarAction, SnackbarDuration } from './Snackbar.types';\nimport useSnackbarAutoDismiss from './useSnackbarAutoDismiss';\nimport useSnackbarSwipeDismiss from './useSnackbarSwipeDismiss';\n\n/**\n * Props for the controlled Snackbar surface, including provider-managed lifecycle controls.\n * Use SnackbarCreationProps when creating notifications through SnackbarProvider/useSnackbar.\n */\nexport interface SnackbarProps {\n /** One optional callback or navigation action. Activating it dismisses after its callback runs. */\n action?: SnackbarAction;\n /** Changes for each new Snackbar so LiveRegion re-announces it. */\n announcementKey: number;\n /**\n * Controls auto-dismiss with a four-second, six-second or indefinite duration after entry finishes.\n * Takes precedence over the deprecated `timeout`.\n * When neither option is supplied, the default is 4000ms (previously 4500ms).\n * @default 'default'\n */\n duration?: SnackbarDuration;\n /**\n * Replaces the media with a progress indicator, uses neutral styling and prevents auto-dismiss.\n * Takes precedence over `media`, `sentiment`, `duration` and the deprecated `timeout`.\n * @default false\n */\n loading?: boolean;\n /** Overrides sentiment-derived media with content for the 24×24px media slot. */\n media?: React.ReactNode;\n /**\n * Called once after this Snackbar finishes exiting, including after an action (e.g. Undo)\n * or replacement by a newer Snackbar. The action callback runs first.\n * Not called for Snackbars discarded before being shown, such as earlier creates batched\n * before the first render.\n */\n onDismiss?: () => void;\n /** Requests an exit; the provider retains the surface until onExited confirms it has finished. */\n onDismissRequest: () => void;\n /** Called after the exit animation so the provider can unmount active or show its replacement. */\n onExited: () => void;\n /**\n * Controls the sentiment surface and default media.\n * @default 'neutral'\n */\n sentiment?: Sentiment;\n /** Message content. Empty strings or absent text dismiss without creating a blank replacement. */\n text: React.ReactNode;\n /** @deprecated Has no effect. Snackbar theming is based on ThemeProvider. */\n theme?: ThemeLight | ThemeDark;\n /**\n * @deprecated Use `duration` instead. Explicit millisecond values remain supported and are not\n * automatically remapped when no `duration` is supplied.\n * To migrate, use `default` for 0–5000ms, `extended` for values above 5000ms, and `indefinite`\n * for intentionally persistent notifications.\n */\n timeout?: number;\n /** @deprecated Has no effect when using SnackbarProvider, which manages Snackbar identity. */\n timestamp?: number;\n /** Controls entry/exit; the surface does not manage visibility itself. */\n visible: boolean;\n}\n\nexport const Snackbar = ({\n action,\n announcementKey,\n duration,\n loading = false,\n media,\n onDismissRequest,\n onExited,\n sentiment = 'neutral',\n text,\n timeout,\n visible,\n}: SnackbarProps) => {\n const { formatMessage } = useIntl();\n const {\n handleBlur,\n handleEntered,\n handleFocus,\n handleMouseEnter,\n handleMouseLeave,\n setSwiping,\n surfaceRef,\n } = useSnackbarAutoDismiss({\n duration,\n loading,\n onDismissRequest,\n timeout,\n visible,\n });\n const {\n clearSwipePosition,\n containerRef,\n handleClickCapture,\n handlePointerCancel,\n handlePointerDown,\n handlePointerMove,\n handlePointerUp,\n } = useSnackbarSwipeDismiss({ onDismissRequest, onSwipeChange: setSwiping, visible });\n\n useEffect(() => {\n if (!visible) {\n return undefined;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && !event.defaultPrevented && !event.isComposing) {\n onDismissRequest();\n }\n };\n\n // Let document-level overlays consume Escape before this fallback handles it.\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [visible, onDismissRequest]);\n\n const handleActionClick: React.MouseEventHandler<ButtonReferenceType> = (event) => {\n try {\n action?.onClick?.(event);\n } finally {\n onDismissRequest();\n }\n };\n\n const renderMedia = () => {\n if (loading) {\n return (\n <ProcessIndicator\n className=\"wds-Snackbar__process-indicator\"\n data-testid=\"Snackbar_ProcessIndicator\"\n size=\"xs\"\n />\n );\n }\n\n if (media) {\n return <span className=\"wds-Snackbar__media-asset\">{media}</span>;\n }\n\n if (sentiment === 'proposition') {\n return (\n <span className=\"wds-Snackbar__media-asset\">\n <Tags aria-hidden size={24} />\n </span>\n );\n }\n\n return <StatusIcon sentiment={sentiment} size={24} />;\n };\n\n return (\n <div\n ref={containerRef}\n className=\"wds-Snackbar\"\n style={\n {\n '--Snackbar-enter-duration': `${SNACKBAR_ENTER_DURATION}ms`,\n '--Snackbar-exit-duration': `${SNACKBAR_EXIT_DURATION}ms`,\n } as React.CSSProperties\n }\n >\n <CSSTransition\n appear\n nodeRef={surfaceRef}\n in={visible}\n classNames=\"wds-Snackbar-container\"\n timeout={{\n appear: SNACKBAR_ENTER_DURATION,\n enter: SNACKBAR_ENTER_DURATION,\n exit: SNACKBAR_EXIT_DURATION,\n }}\n unmountOnExit\n onEntered={handleEntered}\n onExited={() => {\n clearSwipePosition();\n onExited();\n }}\n >\n <PrimitivePrompt\n ref={surfaceRef}\n className=\"wds-Snackbar-container\"\n sentiment={loading ? 'neutral' : sentiment}\n emphasis=\"elevated\"\n media={renderMedia()}\n dismissButtonPriority=\"minimal\"\n onDismiss={onDismissRequest}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onClickCapture={handleClickCapture}\n onDragStart={(event) => event.preventDefault()}\n onPointerDown={visible ? handlePointerDown : undefined}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerCancel}\n >\n <div className=\"wds-Snackbar__content\">\n <LiveRegion\n aria-live=\"polite\"\n announceOnChange={announcementKey}\n className=\"wds-Snackbar__message\"\n >\n <Body as=\"span\" className=\"wds-Snackbar__body\">\n {text}\n <span className=\"sr-only\"> {formatMessage(messages.escapeDismissHint)}</span>\n </Body>\n </LiveRegion>\n {action ? (\n <Button\n className=\"wds-Snackbar__action\"\n v2\n size=\"sm\"\n priority=\"secondary\"\n href={action.href}\n target={action.target}\n onClick={handleActionClick}\n >\n {action.label}\n </Button>\n ) : null}\n </div>\n </PrimitivePrompt>\n </CSSTransition>\n </div>\n );\n};\n\nexport default Snackbar;\n"],"names":["Snackbar","action","announcementKey","duration","loading","media","onDismissRequest","onExited","sentiment","text","timeout","visible","formatMessage","useIntl","handleBlur","handleEntered","handleFocus","handleMouseEnter","handleMouseLeave","setSwiping","surfaceRef","useSnackbarAutoDismiss","clearSwipePosition","containerRef","handleClickCapture","handlePointerCancel","handlePointerDown","handlePointerMove","handlePointerUp","useSnackbarSwipeDismiss","onSwipeChange","useEffect","undefined","handleKeyDown","event","key","defaultPrevented","isComposing","window","addEventListener","removeEventListener","handleActionClick","onClick","renderMedia","_jsx","ProcessIndicator","className","size","children","Tags","StatusIcon","ref","style","SNACKBAR_ENTER_DURATION","SNACKBAR_EXIT_DURATION","CSSTransition","appear","nodeRef","in","classNames","enter","exit","unmountOnExit","onEntered","PrimitivePrompt","emphasis","dismissButtonPriority","onDismiss","onMouseEnter","onMouseLeave","onFocus","onBlur","onClickCapture","onDragStart","preventDefault","onPointerDown","onPointerMove","onPointerUp","onPointerCancel","_jsxs","LiveRegion","announceOnChange","Body","as","messages","escapeDismissHint","Button","v2","priority","href","target","label"],"mappings":"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"}
1
+ {"version":3,"file":"Snackbar.js","sources":["../../../src/Prompt/Snackbar/Snackbar.tsx"],"sourcesContent":["import { Tags } from '@transferwise/icons';\nimport { useEffect } from 'react';\nimport { useIntl } from 'react-intl';\nimport { CSSTransition } from 'react-transition-group';\n\nimport Button, { type ButtonReferenceType } from '../../Button';\nimport Body from '../../Body';\nimport { LiveRegion } from '../../common';\nimport type { ThemeDark, ThemeLight } from '../../common';\nimport { PrimitivePrompt } from '../PrimitivePrompt';\nimport ProcessIndicator from '../../ProcessIndicator';\nimport type { Sentiment } from '../../SentimentSurface';\nimport StatusIcon from '../../StatusIcon';\n\nimport { SNACKBAR_ENTER_DURATION, SNACKBAR_EXIT_DURATION } from './constants';\nimport messages from './Snackbar.messages';\nimport type { SnackbarAction, SnackbarDuration } from './Snackbar.types';\nimport useSnackbarAutoDismiss from './useSnackbarAutoDismiss';\nimport useSnackbarSwipeDismiss from './useSnackbarSwipeDismiss';\n\n/**\n * Props for the controlled Snackbar surface, including provider-managed lifecycle controls.\n * Use SnackbarCreationProps when creating notifications through SnackbarProvider/useSnackbar.\n */\nexport interface SnackbarProps {\n /** One optional callback or navigation action. Activating it dismisses after its callback runs. */\n action?: SnackbarAction;\n /** Changes for each new Snackbar so LiveRegion re-announces it. */\n announcementKey: number;\n /**\n * Controls auto-dismiss with a four-second, six-second or indefinite duration after entry finishes.\n * Takes precedence over the deprecated `timeout`.\n * When neither option is supplied, the default is 4000ms (previously 4500ms).\n * @default 'default'\n */\n duration?: SnackbarDuration;\n /**\n * Replaces the media with a progress indicator, uses neutral styling and prevents auto-dismiss.\n * Takes precedence over `media`, `sentiment`, `duration` and the deprecated `timeout`.\n * @default false\n */\n loading?: boolean;\n /** Overrides sentiment-derived media with content for the 24×24px media slot. */\n media?: React.ReactNode;\n /**\n * Called once after this Snackbar finishes exiting, including after an action (e.g. Undo)\n * or replacement by a newer Snackbar. The action callback runs first.\n * Not called for Snackbars discarded before being shown, such as earlier creates batched\n * before the first render.\n */\n onDismiss?: () => void;\n /** Requests an exit; the provider retains the surface until onExited confirms it has finished. */\n onDismissRequest: () => void;\n /** Called after the exit animation so the provider can unmount active or show its replacement. */\n onExited: () => void;\n /**\n * Controls the sentiment surface and default media.\n * @default 'neutral'\n */\n sentiment?: Sentiment;\n /** Message content. Empty strings or absent text dismiss without creating a blank replacement. */\n text: React.ReactNode;\n /** @deprecated Has no effect. Snackbar theming is based on ThemeProvider. */\n theme?: ThemeLight | ThemeDark;\n /**\n * @deprecated Use `duration` instead. Explicit millisecond values remain supported and are not\n * automatically remapped when no `duration` is supplied.\n * To migrate, use `default` for 0–5000ms, `extended` for values above 5000ms, and `indefinite`\n * for intentionally persistent notifications.\n */\n timeout?: number;\n /** @deprecated Has no effect when using SnackbarProvider, which manages Snackbar identity. */\n timestamp?: number;\n /** Controls entry/exit; the surface does not manage visibility itself. */\n visible: boolean;\n}\n\nexport const Snackbar = ({\n action,\n announcementKey,\n duration,\n loading = false,\n media,\n onDismissRequest,\n onExited,\n sentiment = 'neutral',\n text,\n timeout,\n visible,\n}: SnackbarProps) => {\n const { formatMessage } = useIntl();\n const {\n handleBlur,\n handleEntered,\n handleFocus,\n handleMouseEnter,\n handleMouseLeave,\n setSwiping,\n surfaceRef,\n } = useSnackbarAutoDismiss({\n duration,\n loading,\n onDismissRequest,\n timeout,\n visible,\n });\n const {\n cancelSwipe,\n containerRef,\n handleClickCapture,\n handlePointerCancel,\n handlePointerDown,\n handlePointerMove,\n handlePointerUp,\n } = useSnackbarSwipeDismiss({ onDismissRequest, onSwipeChange: setSwiping });\n\n useEffect(() => {\n if (!visible) {\n return undefined;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && !event.defaultPrevented && !event.isComposing) {\n onDismissRequest();\n }\n };\n\n // Let document-level overlays consume Escape before this fallback handles it.\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [visible, onDismissRequest]);\n\n const handleActionClick: React.MouseEventHandler<ButtonReferenceType> = (event) => {\n try {\n action?.onClick?.(event);\n } finally {\n onDismissRequest();\n }\n };\n\n const renderMedia = () => {\n if (loading) {\n return (\n <ProcessIndicator\n className=\"wds-Snackbar__process-indicator\"\n data-testid=\"Snackbar_ProcessIndicator\"\n size=\"xs\"\n />\n );\n }\n\n if (media) {\n return <span className=\"wds-Snackbar__media-asset\">{media}</span>;\n }\n\n if (sentiment === 'proposition') {\n return (\n <span className=\"wds-Snackbar__media-asset\">\n <Tags aria-hidden size={24} />\n </span>\n );\n }\n\n return <StatusIcon sentiment={sentiment} size={24} />;\n };\n\n return (\n <div\n ref={containerRef}\n className=\"wds-Snackbar\"\n style={\n {\n '--Snackbar-enter-duration': `${SNACKBAR_ENTER_DURATION}ms`,\n '--Snackbar-exit-duration': `${SNACKBAR_EXIT_DURATION}ms`,\n } as React.CSSProperties\n }\n >\n <CSSTransition\n appear\n nodeRef={surfaceRef}\n in={visible}\n classNames=\"wds-Snackbar-container\"\n timeout={{\n appear: SNACKBAR_ENTER_DURATION,\n enter: SNACKBAR_ENTER_DURATION,\n exit: SNACKBAR_EXIT_DURATION,\n }}\n unmountOnExit\n onEntered={handleEntered}\n onExit={cancelSwipe}\n onExited={onExited}\n >\n <PrimitivePrompt\n ref={surfaceRef}\n className=\"wds-Snackbar-container\"\n sentiment={loading ? 'neutral' : sentiment}\n emphasis=\"elevated\"\n media={renderMedia()}\n dismissButtonPriority=\"minimal\"\n onDismiss={onDismissRequest}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onClickCapture={handleClickCapture}\n onDragStart={(event) => event.preventDefault()}\n onPointerDown={visible ? handlePointerDown : undefined}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerCancel}\n >\n <div className=\"wds-Snackbar__content\">\n <LiveRegion\n aria-live=\"polite\"\n announceOnChange={announcementKey}\n className=\"wds-Snackbar__message\"\n >\n <Body as=\"span\" className=\"wds-Snackbar__body\">\n {text}\n <span className=\"sr-only\"> {formatMessage(messages.escapeDismissHint)}</span>\n </Body>\n </LiveRegion>\n {action ? (\n <Button\n className=\"wds-Snackbar__action\"\n v2\n size=\"sm\"\n priority=\"secondary\"\n href={action.href}\n target={action.target}\n onClick={handleActionClick}\n >\n {action.label}\n </Button>\n ) : null}\n </div>\n </PrimitivePrompt>\n </CSSTransition>\n </div>\n );\n};\n\nexport default Snackbar;\n"],"names":["Snackbar","action","announcementKey","duration","loading","media","onDismissRequest","onExited","sentiment","text","timeout","visible","formatMessage","useIntl","handleBlur","handleEntered","handleFocus","handleMouseEnter","handleMouseLeave","setSwiping","surfaceRef","useSnackbarAutoDismiss","cancelSwipe","containerRef","handleClickCapture","handlePointerCancel","handlePointerDown","handlePointerMove","handlePointerUp","useSnackbarSwipeDismiss","onSwipeChange","useEffect","undefined","handleKeyDown","event","key","defaultPrevented","isComposing","window","addEventListener","removeEventListener","handleActionClick","onClick","renderMedia","_jsx","ProcessIndicator","className","size","children","Tags","StatusIcon","ref","style","SNACKBAR_ENTER_DURATION","SNACKBAR_EXIT_DURATION","CSSTransition","appear","nodeRef","in","classNames","enter","exit","unmountOnExit","onEntered","onExit","PrimitivePrompt","emphasis","dismissButtonPriority","onDismiss","onMouseEnter","onMouseLeave","onFocus","onBlur","onClickCapture","onDragStart","preventDefault","onPointerDown","onPointerMove","onPointerUp","onPointerCancel","_jsxs","LiveRegion","announceOnChange","Body","as","messages","escapeDismissHint","Button","v2","priority","href","target","label"],"mappings":"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"}
@@ -68,7 +68,7 @@ const Snackbar = ({
68
68
  visible
69
69
  });
70
70
  const {
71
- clearSwipePosition,
71
+ cancelSwipe,
72
72
  containerRef,
73
73
  handleClickCapture,
74
74
  handlePointerCancel,
@@ -77,8 +77,7 @@ const Snackbar = ({
77
77
  handlePointerUp
78
78
  } = useSnackbarSwipeDismiss({
79
79
  onDismissRequest,
80
- onSwipeChange: setSwiping,
81
- visible
80
+ onSwipeChange: setSwiping
82
81
  });
83
82
  useEffect(() => {
84
83
  if (!visible) {
@@ -147,10 +146,8 @@ const Snackbar = ({
147
146
  },
148
147
  unmountOnExit: true,
149
148
  onEntered: handleEntered,
150
- onExited: () => {
151
- clearSwipePosition();
152
- onExited();
153
- },
149
+ onExit: cancelSwipe,
150
+ onExited: onExited,
154
151
  children: /*#__PURE__*/jsx(PrimitivePrompt, {
155
152
  ref: surfaceRef,
156
153
  className: "wds-Snackbar-container",
@@ -1 +1 @@
1
- {"version":3,"file":"Snackbar.mjs","sources":["../../../src/Prompt/Snackbar/Snackbar.tsx"],"sourcesContent":["import { Tags } from '@transferwise/icons';\nimport { useEffect } from 'react';\nimport { useIntl } from 'react-intl';\nimport { CSSTransition } from 'react-transition-group';\n\nimport Button, { type ButtonReferenceType } from '../../Button';\nimport Body from '../../Body';\nimport { LiveRegion } from '../../common';\nimport type { ThemeDark, ThemeLight } from '../../common';\nimport { PrimitivePrompt } from '../PrimitivePrompt';\nimport ProcessIndicator from '../../ProcessIndicator';\nimport type { Sentiment } from '../../SentimentSurface';\nimport StatusIcon from '../../StatusIcon';\n\nimport { SNACKBAR_ENTER_DURATION, SNACKBAR_EXIT_DURATION } from './constants';\nimport messages from './Snackbar.messages';\nimport type { SnackbarAction, SnackbarDuration } from './Snackbar.types';\nimport useSnackbarAutoDismiss from './useSnackbarAutoDismiss';\nimport useSnackbarSwipeDismiss from './useSnackbarSwipeDismiss';\n\n/**\n * Props for the controlled Snackbar surface, including provider-managed lifecycle controls.\n * Use SnackbarCreationProps when creating notifications through SnackbarProvider/useSnackbar.\n */\nexport interface SnackbarProps {\n /** One optional callback or navigation action. Activating it dismisses after its callback runs. */\n action?: SnackbarAction;\n /** Changes for each new Snackbar so LiveRegion re-announces it. */\n announcementKey: number;\n /**\n * Controls auto-dismiss with a four-second, six-second or indefinite duration after entry finishes.\n * Takes precedence over the deprecated `timeout`.\n * When neither option is supplied, the default is 4000ms (previously 4500ms).\n * @default 'default'\n */\n duration?: SnackbarDuration;\n /**\n * Replaces the media with a progress indicator, uses neutral styling and prevents auto-dismiss.\n * Takes precedence over `media`, `sentiment`, `duration` and the deprecated `timeout`.\n * @default false\n */\n loading?: boolean;\n /** Overrides sentiment-derived media with content for the 24×24px media slot. */\n media?: React.ReactNode;\n /**\n * Called once after this Snackbar finishes exiting, including after an action (e.g. Undo)\n * or replacement by a newer Snackbar. The action callback runs first.\n * Not called for Snackbars discarded before being shown, such as earlier creates batched\n * before the first render.\n */\n onDismiss?: () => void;\n /** Requests an exit; the provider retains the surface until onExited confirms it has finished. */\n onDismissRequest: () => void;\n /** Called after the exit animation so the provider can unmount active or show its replacement. */\n onExited: () => void;\n /**\n * Controls the sentiment surface and default media.\n * @default 'neutral'\n */\n sentiment?: Sentiment;\n /** Message content. Empty strings or absent text dismiss without creating a blank replacement. */\n text: React.ReactNode;\n /** @deprecated Has no effect. Snackbar theming is based on ThemeProvider. */\n theme?: ThemeLight | ThemeDark;\n /**\n * @deprecated Use `duration` instead. Explicit millisecond values remain supported and are not\n * automatically remapped when no `duration` is supplied.\n * To migrate, use `default` for 0–5000ms, `extended` for values above 5000ms, and `indefinite`\n * for intentionally persistent notifications.\n */\n timeout?: number;\n /** @deprecated Has no effect when using SnackbarProvider, which manages Snackbar identity. */\n timestamp?: number;\n /** Controls entry/exit; the surface does not manage visibility itself. */\n visible: boolean;\n}\n\nexport const Snackbar = ({\n action,\n announcementKey,\n duration,\n loading = false,\n media,\n onDismissRequest,\n onExited,\n sentiment = 'neutral',\n text,\n timeout,\n visible,\n}: SnackbarProps) => {\n const { formatMessage } = useIntl();\n const {\n handleBlur,\n handleEntered,\n handleFocus,\n handleMouseEnter,\n handleMouseLeave,\n setSwiping,\n surfaceRef,\n } = useSnackbarAutoDismiss({\n duration,\n loading,\n onDismissRequest,\n timeout,\n visible,\n });\n const {\n clearSwipePosition,\n containerRef,\n handleClickCapture,\n handlePointerCancel,\n handlePointerDown,\n handlePointerMove,\n handlePointerUp,\n } = useSnackbarSwipeDismiss({ onDismissRequest, onSwipeChange: setSwiping, visible });\n\n useEffect(() => {\n if (!visible) {\n return undefined;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && !event.defaultPrevented && !event.isComposing) {\n onDismissRequest();\n }\n };\n\n // Let document-level overlays consume Escape before this fallback handles it.\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [visible, onDismissRequest]);\n\n const handleActionClick: React.MouseEventHandler<ButtonReferenceType> = (event) => {\n try {\n action?.onClick?.(event);\n } finally {\n onDismissRequest();\n }\n };\n\n const renderMedia = () => {\n if (loading) {\n return (\n <ProcessIndicator\n className=\"wds-Snackbar__process-indicator\"\n data-testid=\"Snackbar_ProcessIndicator\"\n size=\"xs\"\n />\n );\n }\n\n if (media) {\n return <span className=\"wds-Snackbar__media-asset\">{media}</span>;\n }\n\n if (sentiment === 'proposition') {\n return (\n <span className=\"wds-Snackbar__media-asset\">\n <Tags aria-hidden size={24} />\n </span>\n );\n }\n\n return <StatusIcon sentiment={sentiment} size={24} />;\n };\n\n return (\n <div\n ref={containerRef}\n className=\"wds-Snackbar\"\n style={\n {\n '--Snackbar-enter-duration': `${SNACKBAR_ENTER_DURATION}ms`,\n '--Snackbar-exit-duration': `${SNACKBAR_EXIT_DURATION}ms`,\n } as React.CSSProperties\n }\n >\n <CSSTransition\n appear\n nodeRef={surfaceRef}\n in={visible}\n classNames=\"wds-Snackbar-container\"\n timeout={{\n appear: SNACKBAR_ENTER_DURATION,\n enter: SNACKBAR_ENTER_DURATION,\n exit: SNACKBAR_EXIT_DURATION,\n }}\n unmountOnExit\n onEntered={handleEntered}\n onExited={() => {\n clearSwipePosition();\n onExited();\n }}\n >\n <PrimitivePrompt\n ref={surfaceRef}\n className=\"wds-Snackbar-container\"\n sentiment={loading ? 'neutral' : sentiment}\n emphasis=\"elevated\"\n media={renderMedia()}\n dismissButtonPriority=\"minimal\"\n onDismiss={onDismissRequest}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onClickCapture={handleClickCapture}\n onDragStart={(event) => event.preventDefault()}\n onPointerDown={visible ? handlePointerDown : undefined}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerCancel}\n >\n <div className=\"wds-Snackbar__content\">\n <LiveRegion\n aria-live=\"polite\"\n announceOnChange={announcementKey}\n className=\"wds-Snackbar__message\"\n >\n <Body as=\"span\" className=\"wds-Snackbar__body\">\n {text}\n <span className=\"sr-only\"> {formatMessage(messages.escapeDismissHint)}</span>\n </Body>\n </LiveRegion>\n {action ? (\n <Button\n className=\"wds-Snackbar__action\"\n v2\n size=\"sm\"\n priority=\"secondary\"\n href={action.href}\n target={action.target}\n onClick={handleActionClick}\n >\n {action.label}\n </Button>\n ) : null}\n </div>\n </PrimitivePrompt>\n </CSSTransition>\n </div>\n );\n};\n\nexport default Snackbar;\n"],"names":["Snackbar","action","announcementKey","duration","loading","media","onDismissRequest","onExited","sentiment","text","timeout","visible","formatMessage","useIntl","handleBlur","handleEntered","handleFocus","handleMouseEnter","handleMouseLeave","setSwiping","surfaceRef","useSnackbarAutoDismiss","clearSwipePosition","containerRef","handleClickCapture","handlePointerCancel","handlePointerDown","handlePointerMove","handlePointerUp","useSnackbarSwipeDismiss","onSwipeChange","useEffect","undefined","handleKeyDown","event","key","defaultPrevented","isComposing","window","addEventListener","removeEventListener","handleActionClick","onClick","renderMedia","_jsx","ProcessIndicator","className","size","children","Tags","StatusIcon","ref","style","SNACKBAR_ENTER_DURATION","SNACKBAR_EXIT_DURATION","CSSTransition","appear","nodeRef","in","classNames","enter","exit","unmountOnExit","onEntered","PrimitivePrompt","emphasis","dismissButtonPriority","onDismiss","onMouseEnter","onMouseLeave","onFocus","onBlur","onClickCapture","onDragStart","preventDefault","onPointerDown","onPointerMove","onPointerUp","onPointerCancel","_jsxs","LiveRegion","announceOnChange","Body","as","messages","escapeDismissHint","Button","v2","priority","href","target","label"],"mappings":"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"}
1
+ {"version":3,"file":"Snackbar.mjs","sources":["../../../src/Prompt/Snackbar/Snackbar.tsx"],"sourcesContent":["import { Tags } from '@transferwise/icons';\nimport { useEffect } from 'react';\nimport { useIntl } from 'react-intl';\nimport { CSSTransition } from 'react-transition-group';\n\nimport Button, { type ButtonReferenceType } from '../../Button';\nimport Body from '../../Body';\nimport { LiveRegion } from '../../common';\nimport type { ThemeDark, ThemeLight } from '../../common';\nimport { PrimitivePrompt } from '../PrimitivePrompt';\nimport ProcessIndicator from '../../ProcessIndicator';\nimport type { Sentiment } from '../../SentimentSurface';\nimport StatusIcon from '../../StatusIcon';\n\nimport { SNACKBAR_ENTER_DURATION, SNACKBAR_EXIT_DURATION } from './constants';\nimport messages from './Snackbar.messages';\nimport type { SnackbarAction, SnackbarDuration } from './Snackbar.types';\nimport useSnackbarAutoDismiss from './useSnackbarAutoDismiss';\nimport useSnackbarSwipeDismiss from './useSnackbarSwipeDismiss';\n\n/**\n * Props for the controlled Snackbar surface, including provider-managed lifecycle controls.\n * Use SnackbarCreationProps when creating notifications through SnackbarProvider/useSnackbar.\n */\nexport interface SnackbarProps {\n /** One optional callback or navigation action. Activating it dismisses after its callback runs. */\n action?: SnackbarAction;\n /** Changes for each new Snackbar so LiveRegion re-announces it. */\n announcementKey: number;\n /**\n * Controls auto-dismiss with a four-second, six-second or indefinite duration after entry finishes.\n * Takes precedence over the deprecated `timeout`.\n * When neither option is supplied, the default is 4000ms (previously 4500ms).\n * @default 'default'\n */\n duration?: SnackbarDuration;\n /**\n * Replaces the media with a progress indicator, uses neutral styling and prevents auto-dismiss.\n * Takes precedence over `media`, `sentiment`, `duration` and the deprecated `timeout`.\n * @default false\n */\n loading?: boolean;\n /** Overrides sentiment-derived media with content for the 24×24px media slot. */\n media?: React.ReactNode;\n /**\n * Called once after this Snackbar finishes exiting, including after an action (e.g. Undo)\n * or replacement by a newer Snackbar. The action callback runs first.\n * Not called for Snackbars discarded before being shown, such as earlier creates batched\n * before the first render.\n */\n onDismiss?: () => void;\n /** Requests an exit; the provider retains the surface until onExited confirms it has finished. */\n onDismissRequest: () => void;\n /** Called after the exit animation so the provider can unmount active or show its replacement. */\n onExited: () => void;\n /**\n * Controls the sentiment surface and default media.\n * @default 'neutral'\n */\n sentiment?: Sentiment;\n /** Message content. Empty strings or absent text dismiss without creating a blank replacement. */\n text: React.ReactNode;\n /** @deprecated Has no effect. Snackbar theming is based on ThemeProvider. */\n theme?: ThemeLight | ThemeDark;\n /**\n * @deprecated Use `duration` instead. Explicit millisecond values remain supported and are not\n * automatically remapped when no `duration` is supplied.\n * To migrate, use `default` for 0–5000ms, `extended` for values above 5000ms, and `indefinite`\n * for intentionally persistent notifications.\n */\n timeout?: number;\n /** @deprecated Has no effect when using SnackbarProvider, which manages Snackbar identity. */\n timestamp?: number;\n /** Controls entry/exit; the surface does not manage visibility itself. */\n visible: boolean;\n}\n\nexport const Snackbar = ({\n action,\n announcementKey,\n duration,\n loading = false,\n media,\n onDismissRequest,\n onExited,\n sentiment = 'neutral',\n text,\n timeout,\n visible,\n}: SnackbarProps) => {\n const { formatMessage } = useIntl();\n const {\n handleBlur,\n handleEntered,\n handleFocus,\n handleMouseEnter,\n handleMouseLeave,\n setSwiping,\n surfaceRef,\n } = useSnackbarAutoDismiss({\n duration,\n loading,\n onDismissRequest,\n timeout,\n visible,\n });\n const {\n cancelSwipe,\n containerRef,\n handleClickCapture,\n handlePointerCancel,\n handlePointerDown,\n handlePointerMove,\n handlePointerUp,\n } = useSnackbarSwipeDismiss({ onDismissRequest, onSwipeChange: setSwiping });\n\n useEffect(() => {\n if (!visible) {\n return undefined;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && !event.defaultPrevented && !event.isComposing) {\n onDismissRequest();\n }\n };\n\n // Let document-level overlays consume Escape before this fallback handles it.\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [visible, onDismissRequest]);\n\n const handleActionClick: React.MouseEventHandler<ButtonReferenceType> = (event) => {\n try {\n action?.onClick?.(event);\n } finally {\n onDismissRequest();\n }\n };\n\n const renderMedia = () => {\n if (loading) {\n return (\n <ProcessIndicator\n className=\"wds-Snackbar__process-indicator\"\n data-testid=\"Snackbar_ProcessIndicator\"\n size=\"xs\"\n />\n );\n }\n\n if (media) {\n return <span className=\"wds-Snackbar__media-asset\">{media}</span>;\n }\n\n if (sentiment === 'proposition') {\n return (\n <span className=\"wds-Snackbar__media-asset\">\n <Tags aria-hidden size={24} />\n </span>\n );\n }\n\n return <StatusIcon sentiment={sentiment} size={24} />;\n };\n\n return (\n <div\n ref={containerRef}\n className=\"wds-Snackbar\"\n style={\n {\n '--Snackbar-enter-duration': `${SNACKBAR_ENTER_DURATION}ms`,\n '--Snackbar-exit-duration': `${SNACKBAR_EXIT_DURATION}ms`,\n } as React.CSSProperties\n }\n >\n <CSSTransition\n appear\n nodeRef={surfaceRef}\n in={visible}\n classNames=\"wds-Snackbar-container\"\n timeout={{\n appear: SNACKBAR_ENTER_DURATION,\n enter: SNACKBAR_ENTER_DURATION,\n exit: SNACKBAR_EXIT_DURATION,\n }}\n unmountOnExit\n onEntered={handleEntered}\n onExit={cancelSwipe}\n onExited={onExited}\n >\n <PrimitivePrompt\n ref={surfaceRef}\n className=\"wds-Snackbar-container\"\n sentiment={loading ? 'neutral' : sentiment}\n emphasis=\"elevated\"\n media={renderMedia()}\n dismissButtonPriority=\"minimal\"\n onDismiss={onDismissRequest}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onClickCapture={handleClickCapture}\n onDragStart={(event) => event.preventDefault()}\n onPointerDown={visible ? handlePointerDown : undefined}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerCancel}\n >\n <div className=\"wds-Snackbar__content\">\n <LiveRegion\n aria-live=\"polite\"\n announceOnChange={announcementKey}\n className=\"wds-Snackbar__message\"\n >\n <Body as=\"span\" className=\"wds-Snackbar__body\">\n {text}\n <span className=\"sr-only\"> {formatMessage(messages.escapeDismissHint)}</span>\n </Body>\n </LiveRegion>\n {action ? (\n <Button\n className=\"wds-Snackbar__action\"\n v2\n size=\"sm\"\n priority=\"secondary\"\n href={action.href}\n target={action.target}\n onClick={handleActionClick}\n >\n {action.label}\n </Button>\n ) : null}\n </div>\n </PrimitivePrompt>\n </CSSTransition>\n </div>\n );\n};\n\nexport default Snackbar;\n"],"names":["Snackbar","action","announcementKey","duration","loading","media","onDismissRequest","onExited","sentiment","text","timeout","visible","formatMessage","useIntl","handleBlur","handleEntered","handleFocus","handleMouseEnter","handleMouseLeave","setSwiping","surfaceRef","useSnackbarAutoDismiss","cancelSwipe","containerRef","handleClickCapture","handlePointerCancel","handlePointerDown","handlePointerMove","handlePointerUp","useSnackbarSwipeDismiss","onSwipeChange","useEffect","undefined","handleKeyDown","event","key","defaultPrevented","isComposing","window","addEventListener","removeEventListener","handleActionClick","onClick","renderMedia","_jsx","ProcessIndicator","className","size","children","Tags","StatusIcon","ref","style","SNACKBAR_ENTER_DURATION","SNACKBAR_EXIT_DURATION","CSSTransition","appear","nodeRef","in","classNames","enter","exit","unmountOnExit","onEntered","onExit","PrimitivePrompt","emphasis","dismissButtonPriority","onDismiss","onMouseEnter","onMouseLeave","onFocus","onBlur","onClickCapture","onDragStart","preventDefault","onPointerDown","onPointerMove","onPointerUp","onPointerCancel","_jsxs","LiveRegion","announceOnChange","Body","as","messages","escapeDismissHint","Button","v2","priority","href","target","label"],"mappings":"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"}
@@ -8,39 +8,34 @@ var constants = require('./constants.js');
8
8
  const DISMISS_CLASS = 'wds-Snackbar--swipe-dismiss';
9
9
  const SETTLE_CLASS = 'wds-Snackbar--swipe-settle';
10
10
  /**
11
- * Captures one primary pointer and follows downward, mostly vertical movement without re-rendering.
12
- * Release dismisses at half the surface height; shorter/cancelled gestures settle back into place.
13
- * The outer wrapper moves independently of entry/exit motion, and a committed swipe consumes its
14
- * follow-up click so dragging from the action cannot activate it.
11
+ * Follows one primary pointer's downward, mostly vertical movement without re-rendering.
12
+ * Release dismisses at half the surface height; shorter or cancelled gestures settle back.
13
+ * A drag consumes its follow-up click, so dragging from the action cannot activate it.
15
14
  */
16
15
  const useSnackbarSwipeDismiss = ({
17
16
  onDismissRequest,
18
- onSwipeChange,
19
- visible
17
+ onSwipeChange
20
18
  }) => {
21
19
  const containerRef = React.useRef(null);
22
20
  const pointerRef = React.useRef(null);
23
21
  const suppressClick = React.useRef(false);
24
- const clearSwipePosition = React.useCallback(() => {
25
- const pointer = pointerRef.current;
22
+ const endGesture = () => {
26
23
  pointerRef.current = null;
27
- if (pointer) {
28
- if (pointer.target.hasPointerCapture?.(pointer.id)) {
29
- pointer.target.releasePointerCapture(pointer.id);
30
- }
31
- onSwipeChange(false);
32
- }
33
- suppressClick.current = false;
34
- containerRef.current?.classList.remove(DISMISS_CLASS, SETTLE_CLASS);
24
+ onSwipeChange(false);
25
+ };
26
+ const settle = () => {
27
+ containerRef.current?.classList.add(SETTLE_CLASS);
35
28
  containerRef.current?.style.removeProperty('transform');
36
- }, [onSwipeChange]);
29
+ };
37
30
  const handlePointerDown = event => {
38
31
  if (event.button !== 0 || !event.isPrimary || pointerRef.current) {
39
32
  return;
40
33
  }
41
- clearSwipePosition();
42
34
  const target = event.target;
35
+ // Keeps move/up events coming when a mouse leaves the Snackbar mid-drag.
43
36
  target.setPointerCapture?.(event.pointerId);
37
+ containerRef.current?.classList.remove(DISMISS_CLASS, SETTLE_CLASS);
38
+ suppressClick.current = false;
44
39
  pointerRef.current = {
45
40
  id: event.pointerId,
46
41
  target,
@@ -68,51 +63,43 @@ const useSnackbarSwipeDismiss = ({
68
63
  if (pointer?.id !== event.pointerId) {
69
64
  return;
70
65
  }
66
+ endGesture();
71
67
  const offsetY = event.clientY - pointer.startY;
72
68
  const offsetX = event.clientX - pointer.startX;
73
69
  const container = containerRef.current;
74
- const bounds = pointer.target.closest('a, button')?.getBoundingClientRect();
75
- clearSwipePosition();
76
70
  if (offsetY >= pointer.threshold && offsetY > Math.abs(offsetX)) {
71
+ suppressClick.current = true;
77
72
  if (container) {
78
73
  // Include wrapper padding and the safe area, not only the surface, to clear the viewport.
79
74
  container.classList.add(DISMISS_CLASS);
80
75
  container.style.setProperty('transform', `translateY(${Math.max(offsetY, container.offsetHeight)}px)`);
81
76
  }
82
- suppressClick.current = true;
83
77
  onDismissRequest();
84
78
  } else {
85
- // Capture retargets clicks to the pressed control even when released outside it.
79
+ // Capture retargets the click to the pressed control even when released outside it,
80
+ // unlike a native button; cancel it in that case.
81
+ const bounds = pointer.target.closest('a, button')?.getBoundingClientRect();
86
82
  suppressClick.current = !!bounds && (offsetX !== 0 || offsetY !== 0) && (event.clientX < bounds.left || event.clientX > bounds.right || event.clientY < bounds.top || event.clientY > bounds.bottom);
87
- container?.classList.add(SETTLE_CLASS);
83
+ settle();
88
84
  }
89
85
  };
90
- const handlePointerCancel = React.useCallback(event => {
86
+ const handlePointerCancel = event => {
91
87
  if (pointerRef.current?.id !== event.pointerId) {
92
88
  return;
93
89
  }
94
- clearSwipePosition();
95
- containerRef.current?.classList.add(SETTLE_CLASS);
96
- }, [clearSwipePosition]);
97
- React.useEffect(() => {
98
- if (visible) {
99
- clearSwipePosition();
100
- } else if (pointerRef.current) {
101
- // An exit starting mid-gesture (timeout, Escape, replacement) ends it without dismissing again.
102
- handlePointerCancel({
103
- pointerId: pointerRef.current.id
104
- });
90
+ endGesture();
91
+ settle();
92
+ };
93
+ /** Ends a gesture still in progress when the Snackbar starts exiting for another reason. */
94
+ const cancelSwipe = () => {
95
+ const pointer = pointerRef.current;
96
+ if (!pointer) {
97
+ return;
105
98
  }
106
- }, [visible, clearSwipePosition, handlePointerCancel]);
107
- React.useEffect(() => {
108
- // Removed descendants report capture loss on their document, not the Snackbar surface.
109
- const ownerDocument = containerRef.current?.ownerDocument;
110
- ownerDocument?.addEventListener('lostpointercapture', handlePointerCancel);
111
- return () => {
112
- ownerDocument?.removeEventListener('lostpointercapture', handlePointerCancel);
113
- clearSwipePosition();
114
- };
115
- }, [clearSwipePosition, handlePointerCancel]);
99
+ pointer.target.releasePointerCapture?.(pointer.id);
100
+ endGesture();
101
+ settle();
102
+ };
116
103
  const handleClickCapture = event => {
117
104
  if (suppressClick.current && event.detail > 0) {
118
105
  suppressClick.current = false;
@@ -121,7 +108,7 @@ const useSnackbarSwipeDismiss = ({
121
108
  }
122
109
  };
123
110
  return {
124
- clearSwipePosition,
111
+ cancelSwipe,
125
112
  containerRef,
126
113
  handleClickCapture,
127
114
  handlePointerCancel,
@@ -1 +1 @@
1
- {"version":3,"file":"useSnackbarSwipeDismiss.js","sources":["../../../src/Prompt/Snackbar/useSnackbarSwipeDismiss.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\n\nimport { SNACKBAR_SWIPE_DISMISS_THRESHOLD } from './constants';\n\nconst DISMISS_CLASS = 'wds-Snackbar--swipe-dismiss';\nconst SETTLE_CLASS = 'wds-Snackbar--swipe-settle';\n\ntype SwipePointer = {\n id: number;\n target: Element;\n startX: number;\n startY: number;\n threshold: number;\n};\n\n/**\n * Captures one primary pointer and follows downward, mostly vertical movement without re-rendering.\n * Release dismisses at half the surface height; shorter/cancelled gestures settle back into place.\n * The outer wrapper moves independently of entry/exit motion, and a committed swipe consumes its\n * follow-up click so dragging from the action cannot activate it.\n */\nconst useSnackbarSwipeDismiss = ({\n onDismissRequest,\n onSwipeChange,\n visible,\n}: {\n onDismissRequest: () => void;\n /** Reports when a gesture starts and ends so auto-dismiss can pause beneath the pointer. */\n onSwipeChange: (swiping: boolean) => void;\n visible: boolean;\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const pointerRef = useRef<SwipePointer | null>(null);\n const suppressClick = useRef(false);\n\n const clearSwipePosition = useCallback(() => {\n const pointer = pointerRef.current;\n pointerRef.current = null;\n if (pointer) {\n if (pointer.target.hasPointerCapture?.(pointer.id)) {\n pointer.target.releasePointerCapture(pointer.id);\n }\n onSwipeChange(false);\n }\n suppressClick.current = false;\n containerRef.current?.classList.remove(DISMISS_CLASS, SETTLE_CLASS);\n containerRef.current?.style.removeProperty('transform');\n }, [onSwipeChange]);\n\n const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (event.button !== 0 || !event.isPrimary || pointerRef.current) {\n return;\n }\n\n clearSwipePosition();\n const target = event.target as Element;\n target.setPointerCapture?.(event.pointerId);\n pointerRef.current = {\n id: event.pointerId,\n target,\n startX: event.clientX,\n startY: event.clientY,\n threshold: event.currentTarget.offsetHeight * SNACKBAR_SWIPE_DISMISS_THRESHOLD,\n };\n onSwipeChange(true);\n };\n\n const handlePointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n const pointer = pointerRef.current;\n if (pointer?.id !== event.pointerId) {\n return;\n }\n\n const offsetY = event.clientY - pointer.startY;\n const offsetX = event.clientX - pointer.startX;\n if (offsetY > 0 && offsetY > Math.abs(offsetX)) {\n containerRef.current?.style.setProperty('transform', `translateY(${offsetY}px)`);\n } else {\n containerRef.current?.style.removeProperty('transform');\n }\n };\n\n const handlePointerUp = (event: React.PointerEvent<HTMLDivElement>) => {\n const pointer = pointerRef.current;\n if (pointer?.id !== event.pointerId) {\n return;\n }\n\n const offsetY = event.clientY - pointer.startY;\n const offsetX = event.clientX - pointer.startX;\n const container = containerRef.current;\n const bounds = pointer.target.closest('a, button')?.getBoundingClientRect();\n clearSwipePosition();\n\n if (offsetY >= pointer.threshold && offsetY > Math.abs(offsetX)) {\n if (container) {\n // Include wrapper padding and the safe area, not only the surface, to clear the viewport.\n container.classList.add(DISMISS_CLASS);\n container.style.setProperty(\n 'transform',\n `translateY(${Math.max(offsetY, container.offsetHeight)}px)`,\n );\n }\n suppressClick.current = true;\n onDismissRequest();\n } else {\n // Capture retargets clicks to the pressed control even when released outside it.\n suppressClick.current =\n !!bounds &&\n (offsetX !== 0 || offsetY !== 0) &&\n (event.clientX < bounds.left ||\n event.clientX > bounds.right ||\n event.clientY < bounds.top ||\n event.clientY > bounds.bottom);\n container?.classList.add(SETTLE_CLASS);\n }\n };\n\n const handlePointerCancel = useCallback(\n (event: Pick<PointerEvent, 'pointerId'>) => {\n if (pointerRef.current?.id !== event.pointerId) {\n return;\n }\n\n clearSwipePosition();\n containerRef.current?.classList.add(SETTLE_CLASS);\n },\n [clearSwipePosition],\n );\n\n useEffect(() => {\n if (visible) {\n clearSwipePosition();\n } else if (pointerRef.current) {\n // An exit starting mid-gesture (timeout, Escape, replacement) ends it without dismissing again.\n handlePointerCancel({ pointerId: pointerRef.current.id });\n }\n }, [visible, clearSwipePosition, handlePointerCancel]);\n\n useEffect(() => {\n // Removed descendants report capture loss on their document, not the Snackbar surface.\n const ownerDocument = containerRef.current?.ownerDocument;\n ownerDocument?.addEventListener('lostpointercapture', handlePointerCancel);\n return () => {\n ownerDocument?.removeEventListener('lostpointercapture', handlePointerCancel);\n clearSwipePosition();\n };\n }, [clearSwipePosition, handlePointerCancel]);\n\n const handleClickCapture = (event: React.MouseEvent<HTMLDivElement>) => {\n if (suppressClick.current && event.detail > 0) {\n suppressClick.current = false;\n event.preventDefault();\n event.stopPropagation();\n }\n };\n\n return {\n clearSwipePosition,\n containerRef,\n handleClickCapture,\n handlePointerCancel,\n handlePointerDown,\n handlePointerMove,\n handlePointerUp,\n };\n};\n\nexport default useSnackbarSwipeDismiss;\n"],"names":["DISMISS_CLASS","SETTLE_CLASS","useSnackbarSwipeDismiss","onDismissRequest","onSwipeChange","visible","containerRef","useRef","pointerRef","suppressClick","clearSwipePosition","useCallback","pointer","current","target","hasPointerCapture","id","releasePointerCapture","classList","remove","style","removeProperty","handlePointerDown","event","button","isPrimary","setPointerCapture","pointerId","startX","clientX","startY","clientY","threshold","currentTarget","offsetHeight","SNACKBAR_SWIPE_DISMISS_THRESHOLD","handlePointerMove","offsetY","offsetX","Math","abs","setProperty","handlePointerUp","container","bounds","closest","getBoundingClientRect","add","max","left","right","top","bottom","handlePointerCancel","useEffect","ownerDocument","addEventListener","removeEventListener","handleClickCapture","detail","preventDefault","stopPropagation"],"mappings":"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"}
1
+ {"version":3,"file":"useSnackbarSwipeDismiss.js","sources":["../../../src/Prompt/Snackbar/useSnackbarSwipeDismiss.ts"],"sourcesContent":["import { useRef } from 'react';\n\nimport { SNACKBAR_SWIPE_DISMISS_THRESHOLD } from './constants';\n\nconst DISMISS_CLASS = 'wds-Snackbar--swipe-dismiss';\nconst SETTLE_CLASS = 'wds-Snackbar--swipe-settle';\n\ntype SwipePointer = {\n id: number;\n target: Element;\n startX: number;\n startY: number;\n threshold: number;\n};\n\n/**\n * Follows one primary pointer's downward, mostly vertical movement without re-rendering.\n * Release dismisses at half the surface height; shorter or cancelled gestures settle back.\n * A drag consumes its follow-up click, so dragging from the action cannot activate it.\n */\nconst useSnackbarSwipeDismiss = ({\n onDismissRequest,\n onSwipeChange,\n}: {\n onDismissRequest: () => void;\n /** Reports when a gesture starts and ends so auto-dismiss can pause beneath the pointer. */\n onSwipeChange: (swiping: boolean) => void;\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const pointerRef = useRef<SwipePointer | null>(null);\n const suppressClick = useRef(false);\n\n const endGesture = () => {\n pointerRef.current = null;\n onSwipeChange(false);\n };\n\n const settle = () => {\n containerRef.current?.classList.add(SETTLE_CLASS);\n containerRef.current?.style.removeProperty('transform');\n };\n\n const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (event.button !== 0 || !event.isPrimary || pointerRef.current) {\n return;\n }\n\n const target = event.target as Element;\n // Keeps move/up events coming when a mouse leaves the Snackbar mid-drag.\n target.setPointerCapture?.(event.pointerId);\n containerRef.current?.classList.remove(DISMISS_CLASS, SETTLE_CLASS);\n suppressClick.current = false;\n pointerRef.current = {\n id: event.pointerId,\n target,\n startX: event.clientX,\n startY: event.clientY,\n threshold: event.currentTarget.offsetHeight * SNACKBAR_SWIPE_DISMISS_THRESHOLD,\n };\n onSwipeChange(true);\n };\n\n const handlePointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n const pointer = pointerRef.current;\n if (pointer?.id !== event.pointerId) {\n return;\n }\n\n const offsetY = event.clientY - pointer.startY;\n const offsetX = event.clientX - pointer.startX;\n if (offsetY > 0 && offsetY > Math.abs(offsetX)) {\n containerRef.current?.style.setProperty('transform', `translateY(${offsetY}px)`);\n } else {\n containerRef.current?.style.removeProperty('transform');\n }\n };\n\n const handlePointerUp = (event: React.PointerEvent<HTMLDivElement>) => {\n const pointer = pointerRef.current;\n if (pointer?.id !== event.pointerId) {\n return;\n }\n\n endGesture();\n const offsetY = event.clientY - pointer.startY;\n const offsetX = event.clientX - pointer.startX;\n const container = containerRef.current;\n if (offsetY >= pointer.threshold && offsetY > Math.abs(offsetX)) {\n suppressClick.current = true;\n if (container) {\n // Include wrapper padding and the safe area, not only the surface, to clear the viewport.\n container.classList.add(DISMISS_CLASS);\n container.style.setProperty(\n 'transform',\n `translateY(${Math.max(offsetY, container.offsetHeight)}px)`,\n );\n }\n onDismissRequest();\n } else {\n // Capture retargets the click to the pressed control even when released outside it,\n // unlike a native button; cancel it in that case.\n const bounds = pointer.target.closest('a, button')?.getBoundingClientRect();\n suppressClick.current =\n !!bounds &&\n (offsetX !== 0 || offsetY !== 0) &&\n (event.clientX < bounds.left ||\n event.clientX > bounds.right ||\n event.clientY < bounds.top ||\n event.clientY > bounds.bottom);\n settle();\n }\n };\n\n const handlePointerCancel = (event: React.PointerEvent<HTMLDivElement>) => {\n if (pointerRef.current?.id !== event.pointerId) {\n return;\n }\n\n endGesture();\n settle();\n };\n\n /** Ends a gesture still in progress when the Snackbar starts exiting for another reason. */\n const cancelSwipe = () => {\n const pointer = pointerRef.current;\n if (!pointer) {\n return;\n }\n\n pointer.target.releasePointerCapture?.(pointer.id);\n endGesture();\n settle();\n };\n\n const handleClickCapture = (event: React.MouseEvent<HTMLDivElement>) => {\n if (suppressClick.current && event.detail > 0) {\n suppressClick.current = false;\n event.preventDefault();\n event.stopPropagation();\n }\n };\n\n return {\n cancelSwipe,\n containerRef,\n handleClickCapture,\n handlePointerCancel,\n handlePointerDown,\n handlePointerMove,\n handlePointerUp,\n };\n};\n\nexport default useSnackbarSwipeDismiss;\n"],"names":["DISMISS_CLASS","SETTLE_CLASS","useSnackbarSwipeDismiss","onDismissRequest","onSwipeChange","containerRef","useRef","pointerRef","suppressClick","endGesture","current","settle","classList","add","style","removeProperty","handlePointerDown","event","button","isPrimary","target","setPointerCapture","pointerId","remove","id","startX","clientX","startY","clientY","threshold","currentTarget","offsetHeight","SNACKBAR_SWIPE_DISMISS_THRESHOLD","handlePointerMove","pointer","offsetY","offsetX","Math","abs","setProperty","handlePointerUp","container","max","bounds","closest","getBoundingClientRect","left","right","top","bottom","handlePointerCancel","cancelSwipe","releasePointerCapture","handleClickCapture","detail","preventDefault","stopPropagation"],"mappings":"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"}
@@ -1,42 +1,37 @@
1
- import { useRef, useCallback, useEffect } from 'react';
1
+ import { useRef } from 'react';
2
2
  import { SNACKBAR_SWIPE_DISMISS_THRESHOLD } from './constants.mjs';
3
3
 
4
4
  const DISMISS_CLASS = 'wds-Snackbar--swipe-dismiss';
5
5
  const SETTLE_CLASS = 'wds-Snackbar--swipe-settle';
6
6
  /**
7
- * Captures one primary pointer and follows downward, mostly vertical movement without re-rendering.
8
- * Release dismisses at half the surface height; shorter/cancelled gestures settle back into place.
9
- * The outer wrapper moves independently of entry/exit motion, and a committed swipe consumes its
10
- * follow-up click so dragging from the action cannot activate it.
7
+ * Follows one primary pointer's downward, mostly vertical movement without re-rendering.
8
+ * Release dismisses at half the surface height; shorter or cancelled gestures settle back.
9
+ * A drag consumes its follow-up click, so dragging from the action cannot activate it.
11
10
  */
12
11
  const useSnackbarSwipeDismiss = ({
13
12
  onDismissRequest,
14
- onSwipeChange,
15
- visible
13
+ onSwipeChange
16
14
  }) => {
17
15
  const containerRef = useRef(null);
18
16
  const pointerRef = useRef(null);
19
17
  const suppressClick = useRef(false);
20
- const clearSwipePosition = useCallback(() => {
21
- const pointer = pointerRef.current;
18
+ const endGesture = () => {
22
19
  pointerRef.current = null;
23
- if (pointer) {
24
- if (pointer.target.hasPointerCapture?.(pointer.id)) {
25
- pointer.target.releasePointerCapture(pointer.id);
26
- }
27
- onSwipeChange(false);
28
- }
29
- suppressClick.current = false;
30
- containerRef.current?.classList.remove(DISMISS_CLASS, SETTLE_CLASS);
20
+ onSwipeChange(false);
21
+ };
22
+ const settle = () => {
23
+ containerRef.current?.classList.add(SETTLE_CLASS);
31
24
  containerRef.current?.style.removeProperty('transform');
32
- }, [onSwipeChange]);
25
+ };
33
26
  const handlePointerDown = event => {
34
27
  if (event.button !== 0 || !event.isPrimary || pointerRef.current) {
35
28
  return;
36
29
  }
37
- clearSwipePosition();
38
30
  const target = event.target;
31
+ // Keeps move/up events coming when a mouse leaves the Snackbar mid-drag.
39
32
  target.setPointerCapture?.(event.pointerId);
33
+ containerRef.current?.classList.remove(DISMISS_CLASS, SETTLE_CLASS);
34
+ suppressClick.current = false;
40
35
  pointerRef.current = {
41
36
  id: event.pointerId,
42
37
  target,
@@ -64,51 +59,43 @@ const useSnackbarSwipeDismiss = ({
64
59
  if (pointer?.id !== event.pointerId) {
65
60
  return;
66
61
  }
62
+ endGesture();
67
63
  const offsetY = event.clientY - pointer.startY;
68
64
  const offsetX = event.clientX - pointer.startX;
69
65
  const container = containerRef.current;
70
- const bounds = pointer.target.closest('a, button')?.getBoundingClientRect();
71
- clearSwipePosition();
72
66
  if (offsetY >= pointer.threshold && offsetY > Math.abs(offsetX)) {
67
+ suppressClick.current = true;
73
68
  if (container) {
74
69
  // Include wrapper padding and the safe area, not only the surface, to clear the viewport.
75
70
  container.classList.add(DISMISS_CLASS);
76
71
  container.style.setProperty('transform', `translateY(${Math.max(offsetY, container.offsetHeight)}px)`);
77
72
  }
78
- suppressClick.current = true;
79
73
  onDismissRequest();
80
74
  } else {
81
- // Capture retargets clicks to the pressed control even when released outside it.
75
+ // Capture retargets the click to the pressed control even when released outside it,
76
+ // unlike a native button; cancel it in that case.
77
+ const bounds = pointer.target.closest('a, button')?.getBoundingClientRect();
82
78
  suppressClick.current = !!bounds && (offsetX !== 0 || offsetY !== 0) && (event.clientX < bounds.left || event.clientX > bounds.right || event.clientY < bounds.top || event.clientY > bounds.bottom);
83
- container?.classList.add(SETTLE_CLASS);
79
+ settle();
84
80
  }
85
81
  };
86
- const handlePointerCancel = useCallback(event => {
82
+ const handlePointerCancel = event => {
87
83
  if (pointerRef.current?.id !== event.pointerId) {
88
84
  return;
89
85
  }
90
- clearSwipePosition();
91
- containerRef.current?.classList.add(SETTLE_CLASS);
92
- }, [clearSwipePosition]);
93
- useEffect(() => {
94
- if (visible) {
95
- clearSwipePosition();
96
- } else if (pointerRef.current) {
97
- // An exit starting mid-gesture (timeout, Escape, replacement) ends it without dismissing again.
98
- handlePointerCancel({
99
- pointerId: pointerRef.current.id
100
- });
86
+ endGesture();
87
+ settle();
88
+ };
89
+ /** Ends a gesture still in progress when the Snackbar starts exiting for another reason. */
90
+ const cancelSwipe = () => {
91
+ const pointer = pointerRef.current;
92
+ if (!pointer) {
93
+ return;
101
94
  }
102
- }, [visible, clearSwipePosition, handlePointerCancel]);
103
- useEffect(() => {
104
- // Removed descendants report capture loss on their document, not the Snackbar surface.
105
- const ownerDocument = containerRef.current?.ownerDocument;
106
- ownerDocument?.addEventListener('lostpointercapture', handlePointerCancel);
107
- return () => {
108
- ownerDocument?.removeEventListener('lostpointercapture', handlePointerCancel);
109
- clearSwipePosition();
110
- };
111
- }, [clearSwipePosition, handlePointerCancel]);
95
+ pointer.target.releasePointerCapture?.(pointer.id);
96
+ endGesture();
97
+ settle();
98
+ };
112
99
  const handleClickCapture = event => {
113
100
  if (suppressClick.current && event.detail > 0) {
114
101
  suppressClick.current = false;
@@ -117,7 +104,7 @@ const useSnackbarSwipeDismiss = ({
117
104
  }
118
105
  };
119
106
  return {
120
- clearSwipePosition,
107
+ cancelSwipe,
121
108
  containerRef,
122
109
  handleClickCapture,
123
110
  handlePointerCancel,
@@ -1 +1 @@
1
- {"version":3,"file":"useSnackbarSwipeDismiss.mjs","sources":["../../../src/Prompt/Snackbar/useSnackbarSwipeDismiss.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\n\nimport { SNACKBAR_SWIPE_DISMISS_THRESHOLD } from './constants';\n\nconst DISMISS_CLASS = 'wds-Snackbar--swipe-dismiss';\nconst SETTLE_CLASS = 'wds-Snackbar--swipe-settle';\n\ntype SwipePointer = {\n id: number;\n target: Element;\n startX: number;\n startY: number;\n threshold: number;\n};\n\n/**\n * Captures one primary pointer and follows downward, mostly vertical movement without re-rendering.\n * Release dismisses at half the surface height; shorter/cancelled gestures settle back into place.\n * The outer wrapper moves independently of entry/exit motion, and a committed swipe consumes its\n * follow-up click so dragging from the action cannot activate it.\n */\nconst useSnackbarSwipeDismiss = ({\n onDismissRequest,\n onSwipeChange,\n visible,\n}: {\n onDismissRequest: () => void;\n /** Reports when a gesture starts and ends so auto-dismiss can pause beneath the pointer. */\n onSwipeChange: (swiping: boolean) => void;\n visible: boolean;\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const pointerRef = useRef<SwipePointer | null>(null);\n const suppressClick = useRef(false);\n\n const clearSwipePosition = useCallback(() => {\n const pointer = pointerRef.current;\n pointerRef.current = null;\n if (pointer) {\n if (pointer.target.hasPointerCapture?.(pointer.id)) {\n pointer.target.releasePointerCapture(pointer.id);\n }\n onSwipeChange(false);\n }\n suppressClick.current = false;\n containerRef.current?.classList.remove(DISMISS_CLASS, SETTLE_CLASS);\n containerRef.current?.style.removeProperty('transform');\n }, [onSwipeChange]);\n\n const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (event.button !== 0 || !event.isPrimary || pointerRef.current) {\n return;\n }\n\n clearSwipePosition();\n const target = event.target as Element;\n target.setPointerCapture?.(event.pointerId);\n pointerRef.current = {\n id: event.pointerId,\n target,\n startX: event.clientX,\n startY: event.clientY,\n threshold: event.currentTarget.offsetHeight * SNACKBAR_SWIPE_DISMISS_THRESHOLD,\n };\n onSwipeChange(true);\n };\n\n const handlePointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n const pointer = pointerRef.current;\n if (pointer?.id !== event.pointerId) {\n return;\n }\n\n const offsetY = event.clientY - pointer.startY;\n const offsetX = event.clientX - pointer.startX;\n if (offsetY > 0 && offsetY > Math.abs(offsetX)) {\n containerRef.current?.style.setProperty('transform', `translateY(${offsetY}px)`);\n } else {\n containerRef.current?.style.removeProperty('transform');\n }\n };\n\n const handlePointerUp = (event: React.PointerEvent<HTMLDivElement>) => {\n const pointer = pointerRef.current;\n if (pointer?.id !== event.pointerId) {\n return;\n }\n\n const offsetY = event.clientY - pointer.startY;\n const offsetX = event.clientX - pointer.startX;\n const container = containerRef.current;\n const bounds = pointer.target.closest('a, button')?.getBoundingClientRect();\n clearSwipePosition();\n\n if (offsetY >= pointer.threshold && offsetY > Math.abs(offsetX)) {\n if (container) {\n // Include wrapper padding and the safe area, not only the surface, to clear the viewport.\n container.classList.add(DISMISS_CLASS);\n container.style.setProperty(\n 'transform',\n `translateY(${Math.max(offsetY, container.offsetHeight)}px)`,\n );\n }\n suppressClick.current = true;\n onDismissRequest();\n } else {\n // Capture retargets clicks to the pressed control even when released outside it.\n suppressClick.current =\n !!bounds &&\n (offsetX !== 0 || offsetY !== 0) &&\n (event.clientX < bounds.left ||\n event.clientX > bounds.right ||\n event.clientY < bounds.top ||\n event.clientY > bounds.bottom);\n container?.classList.add(SETTLE_CLASS);\n }\n };\n\n const handlePointerCancel = useCallback(\n (event: Pick<PointerEvent, 'pointerId'>) => {\n if (pointerRef.current?.id !== event.pointerId) {\n return;\n }\n\n clearSwipePosition();\n containerRef.current?.classList.add(SETTLE_CLASS);\n },\n [clearSwipePosition],\n );\n\n useEffect(() => {\n if (visible) {\n clearSwipePosition();\n } else if (pointerRef.current) {\n // An exit starting mid-gesture (timeout, Escape, replacement) ends it without dismissing again.\n handlePointerCancel({ pointerId: pointerRef.current.id });\n }\n }, [visible, clearSwipePosition, handlePointerCancel]);\n\n useEffect(() => {\n // Removed descendants report capture loss on their document, not the Snackbar surface.\n const ownerDocument = containerRef.current?.ownerDocument;\n ownerDocument?.addEventListener('lostpointercapture', handlePointerCancel);\n return () => {\n ownerDocument?.removeEventListener('lostpointercapture', handlePointerCancel);\n clearSwipePosition();\n };\n }, [clearSwipePosition, handlePointerCancel]);\n\n const handleClickCapture = (event: React.MouseEvent<HTMLDivElement>) => {\n if (suppressClick.current && event.detail > 0) {\n suppressClick.current = false;\n event.preventDefault();\n event.stopPropagation();\n }\n };\n\n return {\n clearSwipePosition,\n containerRef,\n handleClickCapture,\n handlePointerCancel,\n handlePointerDown,\n handlePointerMove,\n handlePointerUp,\n };\n};\n\nexport default useSnackbarSwipeDismiss;\n"],"names":["DISMISS_CLASS","SETTLE_CLASS","useSnackbarSwipeDismiss","onDismissRequest","onSwipeChange","visible","containerRef","useRef","pointerRef","suppressClick","clearSwipePosition","useCallback","pointer","current","target","hasPointerCapture","id","releasePointerCapture","classList","remove","style","removeProperty","handlePointerDown","event","button","isPrimary","setPointerCapture","pointerId","startX","clientX","startY","clientY","threshold","currentTarget","offsetHeight","SNACKBAR_SWIPE_DISMISS_THRESHOLD","handlePointerMove","offsetY","offsetX","Math","abs","setProperty","handlePointerUp","container","bounds","closest","getBoundingClientRect","add","max","left","right","top","bottom","handlePointerCancel","useEffect","ownerDocument","addEventListener","removeEventListener","handleClickCapture","detail","preventDefault","stopPropagation"],"mappings":"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"}
1
+ {"version":3,"file":"useSnackbarSwipeDismiss.mjs","sources":["../../../src/Prompt/Snackbar/useSnackbarSwipeDismiss.ts"],"sourcesContent":["import { useRef } from 'react';\n\nimport { SNACKBAR_SWIPE_DISMISS_THRESHOLD } from './constants';\n\nconst DISMISS_CLASS = 'wds-Snackbar--swipe-dismiss';\nconst SETTLE_CLASS = 'wds-Snackbar--swipe-settle';\n\ntype SwipePointer = {\n id: number;\n target: Element;\n startX: number;\n startY: number;\n threshold: number;\n};\n\n/**\n * Follows one primary pointer's downward, mostly vertical movement without re-rendering.\n * Release dismisses at half the surface height; shorter or cancelled gestures settle back.\n * A drag consumes its follow-up click, so dragging from the action cannot activate it.\n */\nconst useSnackbarSwipeDismiss = ({\n onDismissRequest,\n onSwipeChange,\n}: {\n onDismissRequest: () => void;\n /** Reports when a gesture starts and ends so auto-dismiss can pause beneath the pointer. */\n onSwipeChange: (swiping: boolean) => void;\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const pointerRef = useRef<SwipePointer | null>(null);\n const suppressClick = useRef(false);\n\n const endGesture = () => {\n pointerRef.current = null;\n onSwipeChange(false);\n };\n\n const settle = () => {\n containerRef.current?.classList.add(SETTLE_CLASS);\n containerRef.current?.style.removeProperty('transform');\n };\n\n const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (event.button !== 0 || !event.isPrimary || pointerRef.current) {\n return;\n }\n\n const target = event.target as Element;\n // Keeps move/up events coming when a mouse leaves the Snackbar mid-drag.\n target.setPointerCapture?.(event.pointerId);\n containerRef.current?.classList.remove(DISMISS_CLASS, SETTLE_CLASS);\n suppressClick.current = false;\n pointerRef.current = {\n id: event.pointerId,\n target,\n startX: event.clientX,\n startY: event.clientY,\n threshold: event.currentTarget.offsetHeight * SNACKBAR_SWIPE_DISMISS_THRESHOLD,\n };\n onSwipeChange(true);\n };\n\n const handlePointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n const pointer = pointerRef.current;\n if (pointer?.id !== event.pointerId) {\n return;\n }\n\n const offsetY = event.clientY - pointer.startY;\n const offsetX = event.clientX - pointer.startX;\n if (offsetY > 0 && offsetY > Math.abs(offsetX)) {\n containerRef.current?.style.setProperty('transform', `translateY(${offsetY}px)`);\n } else {\n containerRef.current?.style.removeProperty('transform');\n }\n };\n\n const handlePointerUp = (event: React.PointerEvent<HTMLDivElement>) => {\n const pointer = pointerRef.current;\n if (pointer?.id !== event.pointerId) {\n return;\n }\n\n endGesture();\n const offsetY = event.clientY - pointer.startY;\n const offsetX = event.clientX - pointer.startX;\n const container = containerRef.current;\n if (offsetY >= pointer.threshold && offsetY > Math.abs(offsetX)) {\n suppressClick.current = true;\n if (container) {\n // Include wrapper padding and the safe area, not only the surface, to clear the viewport.\n container.classList.add(DISMISS_CLASS);\n container.style.setProperty(\n 'transform',\n `translateY(${Math.max(offsetY, container.offsetHeight)}px)`,\n );\n }\n onDismissRequest();\n } else {\n // Capture retargets the click to the pressed control even when released outside it,\n // unlike a native button; cancel it in that case.\n const bounds = pointer.target.closest('a, button')?.getBoundingClientRect();\n suppressClick.current =\n !!bounds &&\n (offsetX !== 0 || offsetY !== 0) &&\n (event.clientX < bounds.left ||\n event.clientX > bounds.right ||\n event.clientY < bounds.top ||\n event.clientY > bounds.bottom);\n settle();\n }\n };\n\n const handlePointerCancel = (event: React.PointerEvent<HTMLDivElement>) => {\n if (pointerRef.current?.id !== event.pointerId) {\n return;\n }\n\n endGesture();\n settle();\n };\n\n /** Ends a gesture still in progress when the Snackbar starts exiting for another reason. */\n const cancelSwipe = () => {\n const pointer = pointerRef.current;\n if (!pointer) {\n return;\n }\n\n pointer.target.releasePointerCapture?.(pointer.id);\n endGesture();\n settle();\n };\n\n const handleClickCapture = (event: React.MouseEvent<HTMLDivElement>) => {\n if (suppressClick.current && event.detail > 0) {\n suppressClick.current = false;\n event.preventDefault();\n event.stopPropagation();\n }\n };\n\n return {\n cancelSwipe,\n containerRef,\n handleClickCapture,\n handlePointerCancel,\n handlePointerDown,\n handlePointerMove,\n handlePointerUp,\n };\n};\n\nexport default useSnackbarSwipeDismiss;\n"],"names":["DISMISS_CLASS","SETTLE_CLASS","useSnackbarSwipeDismiss","onDismissRequest","onSwipeChange","containerRef","useRef","pointerRef","suppressClick","endGesture","current","settle","classList","add","style","removeProperty","handlePointerDown","event","button","isPrimary","target","setPointerCapture","pointerId","remove","id","startX","clientX","startY","clientY","threshold","currentTarget","offsetHeight","SNACKBAR_SWIPE_DISMISS_THRESHOLD","handlePointerMove","pointer","offsetY","offsetX","Math","abs","setProperty","handlePointerUp","container","max","bounds","closest","getBoundingClientRect","left","right","top","bottom","handlePointerCancel","cancelSwipe","releasePointerCapture","handleClickCapture","detail","preventDefault","stopPropagation"],"mappings":"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"}
@@ -3,10 +3,33 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var reactIntl = require('react-intl');
6
+ require('../common/theme.js');
7
+ require('../common/direction.js');
8
+ require('@transferwise/neptune-tokens');
9
+ require('../common/PropsValues/control.js');
10
+ require('../common/PropsValues/size.js');
11
+ require('../common/PropsValues/typography.js');
12
+ require('../common/PropsValues/width.js');
13
+ require('../common/PropsValues/type.js');
14
+ require('../common/PropsValues/dateMode.js');
15
+ require('../common/PropsValues/monthFormat.js');
16
+ require('../common/PropsValues/position.js');
17
+ require('../common/PropsValues/layouts.js');
18
+ require('../common/PropsValues/status.js');
19
+ require('../common/PropsValues/sentiment.js');
20
+ require('../common/PropsValues/profileType.js');
21
+ require('../common/PropsValues/variant.js');
22
+ require('../common/PropsValues/scroll.js');
23
+ require('../common/PropsValues/markdownNodeType.js');
24
+ require('../common/fileType.js');
6
25
  var index = require('../common/Locale/index.js');
26
+ require('@transferwise/icons');
27
+ require('clsx');
28
+ require('react');
29
+ require('../common/CloseButton/CloseButton.messages.js');
30
+ var jsxRuntime = require('react/jsx-runtime');
7
31
  var en = require('../i18n/en.json.js');
8
32
  var DirectionProvider = require('./Direction/DirectionProvider.js');
9
- var jsxRuntime = require('react/jsx-runtime');
10
33
 
11
34
  function Provider({
12
35
  i18n,
@@ -1 +1 @@
1
- {"version":3,"file":"Provider.js","sources":["../../src/Provider/Provider.tsx"],"sourcesContent":["import { IntlProvider, ResolvedIntlConfig } from 'react-intl';\n\nimport { adjustLocale, DEFAULT_LOCALE, getDirectionFromLocale } from '../common/Locale';\nimport en from '../i18n/en.json';\n\nimport { DirectionProvider } from './Direction';\n\nexport interface ProviderProps {\n i18n: Pick<ResolvedIntlConfig, 'locale' | 'messages'> &\n Partial<Pick<ResolvedIntlConfig, 'defaultRichTextElements'>>;\n children?: React.ReactNode;\n}\n\nexport default function Provider({ i18n, children }: ProviderProps) {\n const { locale, messages, defaultRichTextElements } = i18n;\n const adjustedLocale = adjustLocale(locale);\n let intlConfig;\n\n if (adjustedLocale === null) {\n // eslint-disable-next-line no-console\n console.warn(\n `Unsupported locale value was provided: '${locale}', defaulting to '${DEFAULT_LOCALE}'`,\n );\n\n intlConfig = { locale: DEFAULT_LOCALE, messages: { ...en, ...messages } };\n } else {\n intlConfig = { locale: adjustedLocale, messages };\n }\n\n return (\n <DirectionProvider direction={getDirectionFromLocale(locale)}>\n <IntlProvider\n defaultLocale={DEFAULT_LOCALE}\n locale={intlConfig.locale}\n messages={intlConfig.messages}\n defaultRichTextElements={defaultRichTextElements}\n >\n {children}\n </IntlProvider>\n </DirectionProvider>\n );\n}\n"],"names":["Provider","i18n","children","locale","messages","defaultRichTextElements","adjustedLocale","adjustLocale","intlConfig","console","warn","DEFAULT_LOCALE","en","_jsx","DirectionProvider","direction","getDirectionFromLocale","IntlProvider","defaultLocale"],"mappings":";;;;;;;;;;AAac,SAAUA,QAAQA,CAAC;EAAEC,IAAI;AAAEC,EAAAA;AAAQ,CAAiB,EAAA;EAChE,MAAM;IAAEC,MAAM;IAAEC,QAAQ;AAAEC,IAAAA;AAAuB,GAAE,GAAGJ,IAAI;AAC1D,EAAA,MAAMK,cAAc,GAAGC,kBAAY,CAACJ,MAAM,CAAC;AAC3C,EAAA,IAAIK,UAAU;EAEd,IAAIF,cAAc,KAAK,IAAI,EAAE;AAC3B;IACAG,OAAO,CAACC,IAAI,CACV,CAAA,wCAAA,EAA2CP,MAAM,CAAA,kBAAA,EAAqBQ,oBAAc,GAAG,CACxF;AAEDH,IAAAA,UAAU,GAAG;AAAEL,MAAAA,MAAM,EAAEQ,oBAAc;AAAEP,MAAAA,QAAQ,EAAE;AAAE,QAAA,GAAGQ,UAAE;QAAE,GAAGR;AAAQ;KAAI;AAC3E,EAAA,CAAC,MAAM;AACLI,IAAAA,UAAU,GAAG;AAAEL,MAAAA,MAAM,EAAEG,cAAc;AAAEF,MAAAA;KAAU;AACnD,EAAA;EAEA,oBACES,cAAA,CAACC,mCAAiB,EAAA;AAACC,IAAAA,SAAS,EAAEC,4BAAsB,CAACb,MAAM,CAAE;IAAAD,QAAA,eAC3DW,cAAA,CAACI,sBAAY,EAAA;AACXC,MAAAA,aAAa,EAAEP,oBAAe;MAC9BR,MAAM,EAAEK,UAAU,CAACL,MAAO;MAC1BC,QAAQ,EAAEI,UAAU,CAACJ,QAAS;AAC9BC,MAAAA,uBAAuB,EAAEA,uBAAwB;AAAAH,MAAAA,QAAA,EAEhDA;KACW;AAChB,GAAmB,CAAC;AAExB;;"}
1
+ {"version":3,"file":"Provider.js","sources":["../../src/Provider/Provider.tsx"],"sourcesContent":["import { IntlProvider, ResolvedIntlConfig } from 'react-intl';\n\nimport { adjustLocale, DEFAULT_LOCALE, getDirectionFromLocale } from '../common';\nimport en from '../i18n/en.json';\n\nimport { DirectionProvider } from './Direction';\n\nexport interface ProviderProps {\n i18n: Pick<ResolvedIntlConfig, 'locale' | 'messages'> &\n Partial<Pick<ResolvedIntlConfig, 'defaultRichTextElements'>>;\n children?: React.ReactNode;\n}\n\nexport default function Provider({ i18n, children }: ProviderProps) {\n const { locale, messages, defaultRichTextElements } = i18n;\n const adjustedLocale = adjustLocale(locale);\n let intlConfig;\n\n if (adjustedLocale === null) {\n // eslint-disable-next-line no-console\n console.warn(\n `Unsupported locale value was provided: '${locale}', defaulting to '${DEFAULT_LOCALE}'`,\n );\n\n intlConfig = { locale: DEFAULT_LOCALE, messages: { ...en, ...messages } };\n } else {\n intlConfig = { locale: adjustedLocale, messages };\n }\n\n return (\n <DirectionProvider direction={getDirectionFromLocale(locale)}>\n <IntlProvider\n defaultLocale={DEFAULT_LOCALE}\n locale={intlConfig.locale}\n messages={intlConfig.messages}\n defaultRichTextElements={defaultRichTextElements}\n >\n {children}\n </IntlProvider>\n </DirectionProvider>\n );\n}\n"],"names":["Provider","i18n","children","locale","messages","defaultRichTextElements","adjustedLocale","adjustLocale","intlConfig","console","warn","DEFAULT_LOCALE","en","_jsx","DirectionProvider","direction","getDirectionFromLocale","IntlProvider","defaultLocale"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAac,SAAUA,QAAQA,CAAC;EAAEC,IAAI;AAAEC,EAAAA;AAAQ,CAAiB,EAAA;EAChE,MAAM;IAAEC,MAAM;IAAEC,QAAQ;AAAEC,IAAAA;AAAuB,GAAE,GAAGJ,IAAI;AAC1D,EAAA,MAAMK,cAAc,GAAGC,kBAAY,CAACJ,MAAM,CAAC;AAC3C,EAAA,IAAIK,UAAU;EAEd,IAAIF,cAAc,KAAK,IAAI,EAAE;AAC3B;IACAG,OAAO,CAACC,IAAI,CACV,CAAA,wCAAA,EAA2CP,MAAM,CAAA,kBAAA,EAAqBQ,oBAAc,GAAG,CACxF;AAEDH,IAAAA,UAAU,GAAG;AAAEL,MAAAA,MAAM,EAAEQ,oBAAc;AAAEP,MAAAA,QAAQ,EAAE;AAAE,QAAA,GAAGQ,UAAE;QAAE,GAAGR;AAAQ;KAAI;AAC3E,EAAA,CAAC,MAAM;AACLI,IAAAA,UAAU,GAAG;AAAEL,MAAAA,MAAM,EAAEG,cAAc;AAAEF,MAAAA;KAAU;AACnD,EAAA;EAEA,oBACES,cAAA,CAACC,mCAAiB,EAAA;AAACC,IAAAA,SAAS,EAAEC,4BAAsB,CAACb,MAAM,CAAE;IAAAD,QAAA,eAC3DW,cAAA,CAACI,sBAAY,EAAA;AACXC,MAAAA,aAAa,EAAEP,oBAAe;MAC9BR,MAAM,EAAEK,UAAU,CAACL,MAAO;MAC1BC,QAAQ,EAAEI,UAAU,CAACJ,QAAS;AAC9BC,MAAAA,uBAAuB,EAAEA,uBAAwB;AAAAH,MAAAA,QAAA,EAEhDA;KACW;AAChB,GAAmB,CAAC;AAExB;;"}
@@ -1,8 +1,31 @@
1
1
  import { IntlProvider } from 'react-intl';
2
+ import '../common/theme.mjs';
3
+ import '../common/direction.mjs';
4
+ import '@transferwise/neptune-tokens';
5
+ import '../common/PropsValues/control.mjs';
6
+ import '../common/PropsValues/size.mjs';
7
+ import '../common/PropsValues/typography.mjs';
8
+ import '../common/PropsValues/width.mjs';
9
+ import '../common/PropsValues/type.mjs';
10
+ import '../common/PropsValues/dateMode.mjs';
11
+ import '../common/PropsValues/monthFormat.mjs';
12
+ import '../common/PropsValues/position.mjs';
13
+ import '../common/PropsValues/layouts.mjs';
14
+ import '../common/PropsValues/status.mjs';
15
+ import '../common/PropsValues/sentiment.mjs';
16
+ import '../common/PropsValues/profileType.mjs';
17
+ import '../common/PropsValues/variant.mjs';
18
+ import '../common/PropsValues/scroll.mjs';
19
+ import '../common/PropsValues/markdownNodeType.mjs';
20
+ import '../common/fileType.mjs';
2
21
  import { adjustLocale, DEFAULT_LOCALE, getDirectionFromLocale } from '../common/Locale/index.mjs';
22
+ import '@transferwise/icons';
23
+ import 'clsx';
24
+ import 'react';
25
+ import '../common/CloseButton/CloseButton.messages.mjs';
26
+ import { jsx } from 'react/jsx-runtime';
3
27
  import en from '../i18n/en.json.mjs';
4
28
  import { DirectionProvider } from './Direction/DirectionProvider.mjs';
5
- import { jsx } from 'react/jsx-runtime';
6
29
 
7
30
  function Provider({
8
31
  i18n,
@@ -1 +1 @@
1
- {"version":3,"file":"Provider.mjs","sources":["../../src/Provider/Provider.tsx"],"sourcesContent":["import { IntlProvider, ResolvedIntlConfig } from 'react-intl';\n\nimport { adjustLocale, DEFAULT_LOCALE, getDirectionFromLocale } from '../common/Locale';\nimport en from '../i18n/en.json';\n\nimport { DirectionProvider } from './Direction';\n\nexport interface ProviderProps {\n i18n: Pick<ResolvedIntlConfig, 'locale' | 'messages'> &\n Partial<Pick<ResolvedIntlConfig, 'defaultRichTextElements'>>;\n children?: React.ReactNode;\n}\n\nexport default function Provider({ i18n, children }: ProviderProps) {\n const { locale, messages, defaultRichTextElements } = i18n;\n const adjustedLocale = adjustLocale(locale);\n let intlConfig;\n\n if (adjustedLocale === null) {\n // eslint-disable-next-line no-console\n console.warn(\n `Unsupported locale value was provided: '${locale}', defaulting to '${DEFAULT_LOCALE}'`,\n );\n\n intlConfig = { locale: DEFAULT_LOCALE, messages: { ...en, ...messages } };\n } else {\n intlConfig = { locale: adjustedLocale, messages };\n }\n\n return (\n <DirectionProvider direction={getDirectionFromLocale(locale)}>\n <IntlProvider\n defaultLocale={DEFAULT_LOCALE}\n locale={intlConfig.locale}\n messages={intlConfig.messages}\n defaultRichTextElements={defaultRichTextElements}\n >\n {children}\n </IntlProvider>\n </DirectionProvider>\n );\n}\n"],"names":["Provider","i18n","children","locale","messages","defaultRichTextElements","adjustedLocale","adjustLocale","intlConfig","console","warn","DEFAULT_LOCALE","en","_jsx","DirectionProvider","direction","getDirectionFromLocale","IntlProvider","defaultLocale"],"mappings":";;;;;;AAac,SAAUA,QAAQA,CAAC;EAAEC,IAAI;AAAEC,EAAAA;AAAQ,CAAiB,EAAA;EAChE,MAAM;IAAEC,MAAM;IAAEC,QAAQ;AAAEC,IAAAA;AAAuB,GAAE,GAAGJ,IAAI;AAC1D,EAAA,MAAMK,cAAc,GAAGC,YAAY,CAACJ,MAAM,CAAC;AAC3C,EAAA,IAAIK,UAAU;EAEd,IAAIF,cAAc,KAAK,IAAI,EAAE;AAC3B;IACAG,OAAO,CAACC,IAAI,CACV,CAAA,wCAAA,EAA2CP,MAAM,CAAA,kBAAA,EAAqBQ,cAAc,GAAG,CACxF;AAEDH,IAAAA,UAAU,GAAG;AAAEL,MAAAA,MAAM,EAAEQ,cAAc;AAAEP,MAAAA,QAAQ,EAAE;AAAE,QAAA,GAAGQ,EAAE;QAAE,GAAGR;AAAQ;KAAI;AAC3E,EAAA,CAAC,MAAM;AACLI,IAAAA,UAAU,GAAG;AAAEL,MAAAA,MAAM,EAAEG,cAAc;AAAEF,MAAAA;KAAU;AACnD,EAAA;EAEA,oBACES,GAAA,CAACC,iBAAiB,EAAA;AAACC,IAAAA,SAAS,EAAEC,sBAAsB,CAACb,MAAM,CAAE;IAAAD,QAAA,eAC3DW,GAAA,CAACI,YAAY,EAAA;AACXC,MAAAA,aAAa,EAAEP,cAAe;MAC9BR,MAAM,EAAEK,UAAU,CAACL,MAAO;MAC1BC,QAAQ,EAAEI,UAAU,CAACJ,QAAS;AAC9BC,MAAAA,uBAAuB,EAAEA,uBAAwB;AAAAH,MAAAA,QAAA,EAEhDA;KACW;AAChB,GAAmB,CAAC;AAExB;;"}
1
+ {"version":3,"file":"Provider.mjs","sources":["../../src/Provider/Provider.tsx"],"sourcesContent":["import { IntlProvider, ResolvedIntlConfig } from 'react-intl';\n\nimport { adjustLocale, DEFAULT_LOCALE, getDirectionFromLocale } from '../common';\nimport en from '../i18n/en.json';\n\nimport { DirectionProvider } from './Direction';\n\nexport interface ProviderProps {\n i18n: Pick<ResolvedIntlConfig, 'locale' | 'messages'> &\n Partial<Pick<ResolvedIntlConfig, 'defaultRichTextElements'>>;\n children?: React.ReactNode;\n}\n\nexport default function Provider({ i18n, children }: ProviderProps) {\n const { locale, messages, defaultRichTextElements } = i18n;\n const adjustedLocale = adjustLocale(locale);\n let intlConfig;\n\n if (adjustedLocale === null) {\n // eslint-disable-next-line no-console\n console.warn(\n `Unsupported locale value was provided: '${locale}', defaulting to '${DEFAULT_LOCALE}'`,\n );\n\n intlConfig = { locale: DEFAULT_LOCALE, messages: { ...en, ...messages } };\n } else {\n intlConfig = { locale: adjustedLocale, messages };\n }\n\n return (\n <DirectionProvider direction={getDirectionFromLocale(locale)}>\n <IntlProvider\n defaultLocale={DEFAULT_LOCALE}\n locale={intlConfig.locale}\n messages={intlConfig.messages}\n defaultRichTextElements={defaultRichTextElements}\n >\n {children}\n </IntlProvider>\n </DirectionProvider>\n );\n}\n"],"names":["Provider","i18n","children","locale","messages","defaultRichTextElements","adjustedLocale","adjustLocale","intlConfig","console","warn","DEFAULT_LOCALE","en","_jsx","DirectionProvider","direction","getDirectionFromLocale","IntlProvider","defaultLocale"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAac,SAAUA,QAAQA,CAAC;EAAEC,IAAI;AAAEC,EAAAA;AAAQ,CAAiB,EAAA;EAChE,MAAM;IAAEC,MAAM;IAAEC,QAAQ;AAAEC,IAAAA;AAAuB,GAAE,GAAGJ,IAAI;AAC1D,EAAA,MAAMK,cAAc,GAAGC,YAAY,CAACJ,MAAM,CAAC;AAC3C,EAAA,IAAIK,UAAU;EAEd,IAAIF,cAAc,KAAK,IAAI,EAAE;AAC3B;IACAG,OAAO,CAACC,IAAI,CACV,CAAA,wCAAA,EAA2CP,MAAM,CAAA,kBAAA,EAAqBQ,cAAc,GAAG,CACxF;AAEDH,IAAAA,UAAU,GAAG;AAAEL,MAAAA,MAAM,EAAEQ,cAAc;AAAEP,MAAAA,QAAQ,EAAE;AAAE,QAAA,GAAGQ,EAAE;QAAE,GAAGR;AAAQ;KAAI;AAC3E,EAAA,CAAC,MAAM;AACLI,IAAAA,UAAU,GAAG;AAAEL,MAAAA,MAAM,EAAEG,cAAc;AAAEF,MAAAA;KAAU;AACnD,EAAA;EAEA,oBACES,GAAA,CAACC,iBAAiB,EAAA;AAACC,IAAAA,SAAS,EAAEC,sBAAsB,CAACb,MAAM,CAAE;IAAAD,QAAA,eAC3DW,GAAA,CAACI,YAAY,EAAA;AACXC,MAAAA,aAAa,EAAEP,cAAe;MAC9BR,MAAM,EAAEK,UAAU,CAACL,MAAO;MAC1BC,QAAQ,EAAEI,UAAU,CAACJ,QAAS;AAC9BC,MAAAA,uBAAuB,EAAEA,uBAAwB;AAAAH,MAAAA,QAAA,EAEhDA;KACW;AAChB,GAAmB,CAAC;AAExB;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Snackbar.d.ts","sourceRoot":"","sources":["../../../../src/Prompt/Snackbar/Snackbar.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAKxD,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAIzE;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,mGAAmG;IACnG,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,mEAAmE;IACnE,eAAe,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iFAAiF;IACjF,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,kGAAkG;IAClG,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,kGAAkG;IAClG,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,kGAAkG;IAClG,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,QAAQ,GAAI,uHAYtB,aAAa,gCAyJf,CAAC;AAEF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"Snackbar.d.ts","sourceRoot":"","sources":["../../../../src/Prompt/Snackbar/Snackbar.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAKxD,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAIzE;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,mGAAmG;IACnG,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,mEAAmE;IACnE,eAAe,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iFAAiF;IACjF,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,kGAAkG;IAClG,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,kGAAkG;IAClG,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,kGAAkG;IAClG,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,QAAQ,GAAI,uHAYtB,aAAa,gCAuJf,CAAC;AAEF,eAAe,QAAQ,CAAC"}
@@ -1,19 +1,17 @@
1
1
  /**
2
- * Captures one primary pointer and follows downward, mostly vertical movement without re-rendering.
3
- * Release dismisses at half the surface height; shorter/cancelled gestures settle back into place.
4
- * The outer wrapper moves independently of entry/exit motion, and a committed swipe consumes its
5
- * follow-up click so dragging from the action cannot activate it.
2
+ * Follows one primary pointer's downward, mostly vertical movement without re-rendering.
3
+ * Release dismisses at half the surface height; shorter or cancelled gestures settle back.
4
+ * A drag consumes its follow-up click, so dragging from the action cannot activate it.
6
5
  */
7
- declare const useSnackbarSwipeDismiss: ({ onDismissRequest, onSwipeChange, visible, }: {
6
+ declare const useSnackbarSwipeDismiss: ({ onDismissRequest, onSwipeChange, }: {
8
7
  onDismissRequest: () => void;
9
8
  /** Reports when a gesture starts and ends so auto-dismiss can pause beneath the pointer. */
10
9
  onSwipeChange: (swiping: boolean) => void;
11
- visible: boolean;
12
10
  }) => {
13
- clearSwipePosition: () => void;
11
+ cancelSwipe: () => void;
14
12
  containerRef: import("react").RefObject<HTMLDivElement>;
15
13
  handleClickCapture: (event: React.MouseEvent<HTMLDivElement>) => void;
16
- handlePointerCancel: (event: Pick<PointerEvent, "pointerId">) => void;
14
+ handlePointerCancel: (event: React.PointerEvent<HTMLDivElement>) => void;
17
15
  handlePointerDown: (event: React.PointerEvent<HTMLDivElement>) => void;
18
16
  handlePointerMove: (event: React.PointerEvent<HTMLDivElement>) => void;
19
17
  handlePointerUp: (event: React.PointerEvent<HTMLDivElement>) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"useSnackbarSwipeDismiss.d.ts","sourceRoot":"","sources":["../../../../src/Prompt/Snackbar/useSnackbarSwipeDismiss.ts"],"names":[],"mappings":"AAeA;;;;;GAKG;AACH,QAAA,MAAM,uBAAuB,GAAI,+CAI9B;IACD,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,4FAA4F;IAC5F,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,OAAO,EAAE,OAAO,CAAC;CAClB;;;gCAuHoC,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC;iCA9BzD,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC;+BAtEP,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC;+BAkBlC,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC;6BAepC,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC;CAoFnE,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"useSnackbarSwipeDismiss.d.ts","sourceRoot":"","sources":["../../../../src/Prompt/Snackbar/useSnackbarSwipeDismiss.ts"],"names":[],"mappings":"AAeA;;;;GAIG;AACH,QAAA,MAAM,uBAAuB,GAAI,sCAG9B;IACD,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,4FAA4F;IAC5F,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CAC3C;;;gCA2GoC,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC;iCArB/B,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC;+BAvEpC,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC;+BAoBlC,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC;6BAepC,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC;CA0EnE,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transferwise/components",
3
- "version": "0.0.0-experimental-1ce1b08",
3
+ "version": "0.0.0-experimental-02e6e73",
4
4
  "description": "Neptune React components",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -770,7 +770,6 @@ describe('Snackbar swipe dismissal', () => {
770
770
 
771
771
  await user.pointer({ keys: '[/MouseLeft]', coords: { clientX: 0, clientY: 200 } });
772
772
 
773
- expect(capture.releasePointerCapture).toHaveBeenCalledWith(1);
774
773
  expect(snackbarProps.onDismissRequest).toHaveBeenCalledTimes(1);
775
774
  expect(container).toHaveStyle({ transform: 'translateY(200px)' });
776
775
  });
@@ -892,7 +891,7 @@ describe('Snackbar swipe dismissal', () => {
892
891
  expect(snackbarProps.onDismissRequest).not.toHaveBeenCalled();
893
892
  });
894
893
 
895
- it.each(['pointercancel', 'lostpointercapture'])('restores the position on %s', async (type) => {
894
+ it.each(['pointercancel'])('restores the position on %s', async (type) => {
896
895
  const { surface, container, snackbarProps } = setupSwipe();
897
896
  mockPointerCapture(surface);
898
897
  await user.pointer([
@@ -911,59 +910,6 @@ describe('Snackbar swipe dismissal', () => {
911
910
  expect(snackbarProps.onDismissRequest).not.toHaveBeenCalled();
912
911
  });
913
912
 
914
- it('recovers when a captured child is removed and capture loss fires on its document', async () => {
915
- const { surface, container, rerender, snackbarProps } = setupSwipe({
916
- media: <span>Drag me</span>,
917
- });
918
- const child = screen.getByText('Drag me');
919
- mockPointerCapture(child);
920
- await user.pointer([
921
- { keys: '[MouseLeft>]', target: child, coords: { clientX: 0, clientY: 0 } },
922
- { coords: { clientX: 0, clientY: 30 } },
923
- ]);
924
- expect(container).toHaveStyle({ transform: 'translateY(30px)' });
925
-
926
- // An unrelated pointer losing capture must not cancel the active gesture.
927
- const unrelatedLoss = new Event('lostpointercapture', { bubbles: true });
928
- Object.defineProperty(unrelatedLoss, 'pointerId', { value: 2 });
929
- fireEvent(surface.ownerDocument, unrelatedLoss);
930
- expect(container).toHaveStyle({ transform: 'translateY(30px)' });
931
-
932
- rerender(<Snackbar {...snackbarProps} media={undefined} />);
933
- expect(child).not.toBeInTheDocument();
934
- const captureLoss = new Event('lostpointercapture', { bubbles: true });
935
- Object.defineProperty(captureLoss, 'pointerId', { value: 1 });
936
- fireEvent(surface.ownerDocument, captureLoss);
937
-
938
- expect(container).toHaveStyle({ transform: '' });
939
- expect(container).toHaveClass('wds-Snackbar--swipe-settle');
940
- expect(snackbarProps.onDismissRequest).not.toHaveBeenCalled();
941
- await user.pointer({ keys: '[/MouseLeft]', target: document.body });
942
- await user.pointer([
943
- { keys: '[MouseLeft>]', target: surface, coords: { clientX: 0, clientY: 0 } },
944
- { coords: { clientX: 0, clientY: 50 } },
945
- '[/MouseLeft]',
946
- ]);
947
- expect(snackbarProps.onDismissRequest).toHaveBeenCalledTimes(1);
948
- });
949
-
950
- it('removes its document capture-loss listener on unmount', () => {
951
- const addListener = jest.spyOn(document, 'addEventListener');
952
- const removeListener = jest.spyOn(document, 'removeEventListener');
953
- try {
954
- const { unmount } = setupSwipe();
955
- const listener = addListener.mock.calls.find(([type]) => type === 'lostpointercapture')?.[1];
956
- expect(listener).toEqual(expect.any(Function));
957
-
958
- unmount();
959
-
960
- expect(removeListener).toHaveBeenCalledWith('lostpointercapture', listener);
961
- } finally {
962
- addListener.mockRestore();
963
- removeListener.mockRestore();
964
- }
965
- });
966
-
967
913
  it('ignores secondary pointers while retaining the primary gesture', async () => {
968
914
  const { surface, container, snackbarProps } = setupSwipe();
969
915
  const capture = mockPointerCapture(surface);
@@ -995,20 +941,6 @@ describe('Snackbar swipe dismissal', () => {
995
941
  expect(snackbarProps.onDismissRequest).not.toHaveBeenCalled();
996
942
  });
997
943
 
998
- it('clears the drag state after the exit finishes', async () => {
999
- const { surface, container, rerender, snackbarProps } = setupSwipe();
1000
- await user.pointer([
1001
- { keys: '[MouseLeft>]', target: surface, coords: { clientX: 0, clientY: 0 } },
1002
- { coords: { clientX: 0, clientY: 50 } },
1003
- '[/MouseLeft]',
1004
- ]);
1005
- rerender(<Snackbar {...snackbarProps} visible={false} />);
1006
- advanceTimers(SNACKBAR_EXIT_DURATION);
1007
- expect(container).toHaveStyle({ transform: '' });
1008
- expect(container).not.toHaveClass('wds-Snackbar--swipe-dismiss');
1009
- expect(snackbarProps.onExited).toHaveBeenCalledTimes(1);
1010
- });
1011
-
1012
944
  it('keeps dragging across a render and uses the latest dismissal callback', async () => {
1013
945
  const { surface, container, rerender, snackbarProps } = setupSwipe();
1014
946
  await user.pointer([
@@ -105,14 +105,14 @@ export const Snackbar = ({
105
105
  visible,
106
106
  });
107
107
  const {
108
- clearSwipePosition,
108
+ cancelSwipe,
109
109
  containerRef,
110
110
  handleClickCapture,
111
111
  handlePointerCancel,
112
112
  handlePointerDown,
113
113
  handlePointerMove,
114
114
  handlePointerUp,
115
- } = useSnackbarSwipeDismiss({ onDismissRequest, onSwipeChange: setSwiping, visible });
115
+ } = useSnackbarSwipeDismiss({ onDismissRequest, onSwipeChange: setSwiping });
116
116
 
117
117
  useEffect(() => {
118
118
  if (!visible) {
@@ -187,10 +187,8 @@ export const Snackbar = ({
187
187
  }}
188
188
  unmountOnExit
189
189
  onEntered={handleEntered}
190
- onExited={() => {
191
- clearSwipePosition();
192
- onExited();
193
- }}
190
+ onExit={cancelSwipe}
191
+ onExited={onExited}
194
192
  >
195
193
  <PrimitivePrompt
196
194
  ref={surfaceRef}
@@ -1,4 +1,4 @@
1
- import { useCallback, useEffect, useRef } from 'react';
1
+ import { useRef } from 'react';
2
2
 
3
3
  import { SNACKBAR_SWIPE_DISMISS_THRESHOLD } from './constants';
4
4
 
@@ -14,47 +14,42 @@ type SwipePointer = {
14
14
  };
15
15
 
16
16
  /**
17
- * Captures one primary pointer and follows downward, mostly vertical movement without re-rendering.
18
- * Release dismisses at half the surface height; shorter/cancelled gestures settle back into place.
19
- * The outer wrapper moves independently of entry/exit motion, and a committed swipe consumes its
20
- * follow-up click so dragging from the action cannot activate it.
17
+ * Follows one primary pointer's downward, mostly vertical movement without re-rendering.
18
+ * Release dismisses at half the surface height; shorter or cancelled gestures settle back.
19
+ * A drag consumes its follow-up click, so dragging from the action cannot activate it.
21
20
  */
22
21
  const useSnackbarSwipeDismiss = ({
23
22
  onDismissRequest,
24
23
  onSwipeChange,
25
- visible,
26
24
  }: {
27
25
  onDismissRequest: () => void;
28
26
  /** Reports when a gesture starts and ends so auto-dismiss can pause beneath the pointer. */
29
27
  onSwipeChange: (swiping: boolean) => void;
30
- visible: boolean;
31
28
  }) => {
32
29
  const containerRef = useRef<HTMLDivElement>(null);
33
30
  const pointerRef = useRef<SwipePointer | null>(null);
34
31
  const suppressClick = useRef(false);
35
32
 
36
- const clearSwipePosition = useCallback(() => {
37
- const pointer = pointerRef.current;
33
+ const endGesture = () => {
38
34
  pointerRef.current = null;
39
- if (pointer) {
40
- if (pointer.target.hasPointerCapture?.(pointer.id)) {
41
- pointer.target.releasePointerCapture(pointer.id);
42
- }
43
- onSwipeChange(false);
44
- }
45
- suppressClick.current = false;
46
- containerRef.current?.classList.remove(DISMISS_CLASS, SETTLE_CLASS);
35
+ onSwipeChange(false);
36
+ };
37
+
38
+ const settle = () => {
39
+ containerRef.current?.classList.add(SETTLE_CLASS);
47
40
  containerRef.current?.style.removeProperty('transform');
48
- }, [onSwipeChange]);
41
+ };
49
42
 
50
43
  const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {
51
44
  if (event.button !== 0 || !event.isPrimary || pointerRef.current) {
52
45
  return;
53
46
  }
54
47
 
55
- clearSwipePosition();
56
48
  const target = event.target as Element;
49
+ // Keeps move/up events coming when a mouse leaves the Snackbar mid-drag.
57
50
  target.setPointerCapture?.(event.pointerId);
51
+ containerRef.current?.classList.remove(DISMISS_CLASS, SETTLE_CLASS);
52
+ suppressClick.current = false;
58
53
  pointerRef.current = {
59
54
  id: event.pointerId,
60
55
  target,
@@ -86,13 +81,12 @@ const useSnackbarSwipeDismiss = ({
86
81
  return;
87
82
  }
88
83
 
84
+ endGesture();
89
85
  const offsetY = event.clientY - pointer.startY;
90
86
  const offsetX = event.clientX - pointer.startX;
91
87
  const container = containerRef.current;
92
- const bounds = pointer.target.closest('a, button')?.getBoundingClientRect();
93
- clearSwipePosition();
94
-
95
88
  if (offsetY >= pointer.threshold && offsetY > Math.abs(offsetX)) {
89
+ suppressClick.current = true;
96
90
  if (container) {
97
91
  // Include wrapper padding and the safe area, not only the surface, to clear the viewport.
98
92
  container.classList.add(DISMISS_CLASS);
@@ -101,10 +95,11 @@ const useSnackbarSwipeDismiss = ({
101
95
  `translateY(${Math.max(offsetY, container.offsetHeight)}px)`,
102
96
  );
103
97
  }
104
- suppressClick.current = true;
105
98
  onDismissRequest();
106
99
  } else {
107
- // Capture retargets clicks to the pressed control even when released outside it.
100
+ // Capture retargets the click to the pressed control even when released outside it,
101
+ // unlike a native button; cancel it in that case.
102
+ const bounds = pointer.target.closest('a, button')?.getBoundingClientRect();
108
103
  suppressClick.current =
109
104
  !!bounds &&
110
105
  (offsetX !== 0 || offsetY !== 0) &&
@@ -112,40 +107,30 @@ const useSnackbarSwipeDismiss = ({
112
107
  event.clientX > bounds.right ||
113
108
  event.clientY < bounds.top ||
114
109
  event.clientY > bounds.bottom);
115
- container?.classList.add(SETTLE_CLASS);
110
+ settle();
116
111
  }
117
112
  };
118
113
 
119
- const handlePointerCancel = useCallback(
120
- (event: Pick<PointerEvent, 'pointerId'>) => {
121
- if (pointerRef.current?.id !== event.pointerId) {
122
- return;
123
- }
114
+ const handlePointerCancel = (event: React.PointerEvent<HTMLDivElement>) => {
115
+ if (pointerRef.current?.id !== event.pointerId) {
116
+ return;
117
+ }
118
+
119
+ endGesture();
120
+ settle();
121
+ };
124
122
 
125
- clearSwipePosition();
126
- containerRef.current?.classList.add(SETTLE_CLASS);
127
- },
128
- [clearSwipePosition],
129
- );
130
-
131
- useEffect(() => {
132
- if (visible) {
133
- clearSwipePosition();
134
- } else if (pointerRef.current) {
135
- // An exit starting mid-gesture (timeout, Escape, replacement) ends it without dismissing again.
136
- handlePointerCancel({ pointerId: pointerRef.current.id });
123
+ /** Ends a gesture still in progress when the Snackbar starts exiting for another reason. */
124
+ const cancelSwipe = () => {
125
+ const pointer = pointerRef.current;
126
+ if (!pointer) {
127
+ return;
137
128
  }
138
- }, [visible, clearSwipePosition, handlePointerCancel]);
139
-
140
- useEffect(() => {
141
- // Removed descendants report capture loss on their document, not the Snackbar surface.
142
- const ownerDocument = containerRef.current?.ownerDocument;
143
- ownerDocument?.addEventListener('lostpointercapture', handlePointerCancel);
144
- return () => {
145
- ownerDocument?.removeEventListener('lostpointercapture', handlePointerCancel);
146
- clearSwipePosition();
147
- };
148
- }, [clearSwipePosition, handlePointerCancel]);
129
+
130
+ pointer.target.releasePointerCapture?.(pointer.id);
131
+ endGesture();
132
+ settle();
133
+ };
149
134
 
150
135
  const handleClickCapture = (event: React.MouseEvent<HTMLDivElement>) => {
151
136
  if (suppressClick.current && event.detail > 0) {
@@ -156,7 +141,7 @@ const useSnackbarSwipeDismiss = ({
156
141
  };
157
142
 
158
143
  return {
159
- clearSwipePosition,
144
+ cancelSwipe,
160
145
  containerRef,
161
146
  handleClickCapture,
162
147
  handlePointerCancel,
@@ -1,6 +1,6 @@
1
1
  import { IntlProvider, ResolvedIntlConfig } from 'react-intl';
2
2
 
3
- import { adjustLocale, DEFAULT_LOCALE, getDirectionFromLocale } from '../common/Locale';
3
+ import { adjustLocale, DEFAULT_LOCALE, getDirectionFromLocale } from '../common';
4
4
  import en from '../i18n/en.json';
5
5
 
6
6
  import { DirectionProvider } from './Direction';