@coinbase/cds-web 8.13.2 → 8.13.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dts/tabs/SegmentedTab.d.ts +38 -36
- package/dts/tabs/SegmentedTab.d.ts.map +1 -1
- package/dts/tour/Tour.d.ts.map +1 -1
- package/esm/tabs/SegmentedTab.js +25 -4
- package/esm/tour/Tour.js +102 -72
- package/esm/tour/TourStep.js +5 -4
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,26 @@ All notable changes to this project will be documented in this file.
|
|
|
8
8
|
|
|
9
9
|
<!-- template-start -->
|
|
10
10
|
|
|
11
|
+
## 8.13.6 ((10/3/2025, 01:54 PM PST))
|
|
12
|
+
|
|
13
|
+
This is an artificial version bump with no new change.
|
|
14
|
+
|
|
15
|
+
## 8.13.5 (10/3/2025 PST)
|
|
16
|
+
|
|
17
|
+
#### 🐞 Fixes
|
|
18
|
+
|
|
19
|
+
- Support custom font in SegmentedTab. [[#65](https://github.com/coinbase/cds/pull/65)]
|
|
20
|
+
|
|
21
|
+
## 8.13.4 (10/1/2025 PST)
|
|
22
|
+
|
|
23
|
+
#### 🐞 Fixes
|
|
24
|
+
|
|
25
|
+
- Fix tour position flickering issue.
|
|
26
|
+
|
|
27
|
+
## 8.13.3 ((10/1/2025, 03:05 PM PST))
|
|
28
|
+
|
|
29
|
+
This is an artificial version bump with no new change.
|
|
30
|
+
|
|
11
31
|
## 8.13.2 (10/1/2025 PST)
|
|
12
32
|
|
|
13
33
|
#### 🐞 Fixes
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { ThemeVars } from '@coinbase/cds-common/core/theme';
|
|
3
3
|
import { type TabValue } from '@coinbase/cds-common/tabs/useTabs';
|
|
4
|
-
import type
|
|
5
|
-
export type SegmentedTabProps<T extends string = string> =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
SharedProps;
|
|
4
|
+
import { type PressableBaseProps } from '../system/Pressable';
|
|
5
|
+
export type SegmentedTabProps<T extends string = string> = PressableBaseProps &
|
|
6
|
+
TabValue<T> & {
|
|
7
|
+
/**
|
|
8
|
+
* Text color when the SegmentedTab is active.
|
|
9
|
+
* @default negativeForeground
|
|
10
|
+
*/
|
|
11
|
+
activeColor?: ThemeVars.Color;
|
|
12
|
+
/**
|
|
13
|
+
* Text color when the SegmentedTab is inactive.
|
|
14
|
+
* @default foreground
|
|
15
|
+
*/
|
|
16
|
+
color?: ThemeVars.Color;
|
|
17
|
+
/** Callback that is fired when the SegmentedTab is clicked. */
|
|
18
|
+
onClick?: (id: T, event: React.MouseEvent) => void;
|
|
19
|
+
};
|
|
21
20
|
type SegmentedTabComponent = <T extends string = string>(
|
|
22
21
|
props: SegmentedTabProps<T> & {
|
|
23
22
|
ref?: React.ForwardedRef<HTMLButtonElement>;
|
|
@@ -25,26 +24,29 @@ type SegmentedTabComponent = <T extends string = string>(
|
|
|
25
24
|
) => React.ReactElement;
|
|
26
25
|
declare const SegmentedTabComponent: React.MemoExoticComponent<
|
|
27
26
|
React.ForwardRefExoticComponent<
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
* @default foreground
|
|
37
|
-
*/
|
|
38
|
-
color?: ThemeVars.Color;
|
|
39
|
-
/** Callback that is fired when the SegmentedTab is clicked. */
|
|
40
|
-
onClick?: ((id: string, event: React.MouseEvent) => void) | undefined;
|
|
41
|
-
} & TabValue<string> &
|
|
42
|
-
Omit<
|
|
43
|
-
React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>,
|
|
44
|
-
'ref'
|
|
27
|
+
import('@coinbase/cds-common').ComponentEventHandlerProps & {
|
|
28
|
+
noScaleOnPress?: boolean;
|
|
29
|
+
focusable?: boolean;
|
|
30
|
+
} & Omit<
|
|
31
|
+
import('../system').InteractableBaseProps,
|
|
32
|
+
| 'focusable'
|
|
33
|
+
| keyof import('@coinbase/cds-common').ComponentEventHandlerProps
|
|
34
|
+
| 'noScaleOnPress'
|
|
45
35
|
> &
|
|
46
|
-
|
|
47
|
-
|
|
36
|
+
TabValue<string> & {
|
|
37
|
+
/**
|
|
38
|
+
* Text color when the SegmentedTab is active.
|
|
39
|
+
* @default negativeForeground
|
|
40
|
+
*/
|
|
41
|
+
activeColor?: ThemeVars.Color;
|
|
42
|
+
/**
|
|
43
|
+
* Text color when the SegmentedTab is inactive.
|
|
44
|
+
* @default foreground
|
|
45
|
+
*/
|
|
46
|
+
color?: ThemeVars.Color;
|
|
47
|
+
/** Callback that is fired when the SegmentedTab is clicked. */
|
|
48
|
+
onClick?: ((id: string, event: React.MouseEvent) => void) | undefined;
|
|
49
|
+
} & React.RefAttributes<HTMLButtonElement>
|
|
48
50
|
>
|
|
49
51
|
>;
|
|
50
52
|
export declare const SegmentedTab: SegmentedTabComponent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SegmentedTab.d.ts","sourceRoot":"","sources":["../../src/tabs/SegmentedTab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAEjE,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"SegmentedTab.d.ts","sourceRoot":"","sources":["../../src/tabs/SegmentedTab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAEjE,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAOlE,OAAO,EAAa,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAkCzE,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,kBAAkB,GAC3E,QAAQ,CAAC,CAAC,CAAC,GAAG;IACZ;;;OAGG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC;IAC9B;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC;IACxB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;CACpD,CAAC;AAMJ,KAAK,qBAAqB,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EACrD,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAA;CAAE,KAC1E,KAAK,CAAC,YAAY,CAAC;AAExB,QAAA,MAAM,qBAAqB;;;;IAtBvB;;;OAGG;kBACW,SAAS,CAAC,KAAK;IAC7B;;;OAGG;YACK,SAAS,CAAC,KAAK;IACvB,+DAA+D;mCACtC,KAAK,CAAC,UAAU,KAAK,IAAI;4CAuGrD,CAAC;AAIF,eAAO,MAAM,YAAY,EAA4B,qBAAqB,CAAC"}
|
package/dts/tour/Tour.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tour.d.ts","sourceRoot":"","sources":["../../src/tour/Tour.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Tour.d.ts","sourceRoot":"","sources":["../../src/tour/Tour.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAM9D,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,sBAAsB,EAEvB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qDAAqD,CAAC;AACpG,OAAO,EAGL,KAAK,oBAAoB,EAGzB,KAAK,aAAa,EAElB,KAAK,YAAY,EAElB,MAAM,wBAAwB,CAAC;AA0BhC,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,wBAAwB,EAAE,IAAI,CAAC;IAC/B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC;AAEjE,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG;IAClE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IAChD;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,cAAc,CAAC,EAAE,aAAa,CAAC;IAC/B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,oBAAoB,CAAC;IAC7C;;OAEG;IACH,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvC;;OAEG;IACH,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,GAAG,IAAI,CAAC,wBAAwB,EAAE,oBAAoB,GAAG,yBAAyB,GAAG,IAAI,CAAC,GACzF,WAAW,CAAC;AAsDd,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;AA8KzF,eAAO,MAAM,IAAI,EAAoB,MAAM,CAAC"}
|
package/esm/tabs/SegmentedTab.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const _excluded = ["id", "label", "disabled", "onClick", "color", "activeColor", "className", "testID"];
|
|
1
|
+
const _excluded = ["id", "label", "disabled", "onClick", "color", "activeColor", "className", "testID", "font", "fontFamily", "fontSize", "fontWeight", "lineHeight", "textAlign", "textTransform"];
|
|
2
2
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
3
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
4
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
@@ -11,6 +11,7 @@ import { useTabsContext } from '@coinbase/cds-common/tabs/TabsContext';
|
|
|
11
11
|
import { m as motion } from 'framer-motion';
|
|
12
12
|
import { cx } from '../cx';
|
|
13
13
|
import { Box } from '../layout/Box';
|
|
14
|
+
import { Pressable } from '../system/Pressable';
|
|
14
15
|
import { Text } from '../typography/Text';
|
|
15
16
|
import { tabsTransitionConfig } from './Tabs';
|
|
16
17
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
@@ -28,7 +29,14 @@ const SegmentedTabComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
|
|
|
28
29
|
color = 'fg',
|
|
29
30
|
activeColor = 'fgInverse',
|
|
30
31
|
className,
|
|
31
|
-
testID
|
|
32
|
+
testID,
|
|
33
|
+
font = 'headline',
|
|
34
|
+
fontFamily,
|
|
35
|
+
fontSize,
|
|
36
|
+
fontWeight,
|
|
37
|
+
lineHeight,
|
|
38
|
+
textAlign,
|
|
39
|
+
textTransform
|
|
32
40
|
} = _ref,
|
|
33
41
|
props = _objectWithoutProperties(_ref, _excluded);
|
|
34
42
|
const {
|
|
@@ -49,15 +57,22 @@ const SegmentedTabComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
|
|
|
49
57
|
transition: tabsTransitionConfig,
|
|
50
58
|
initial: false
|
|
51
59
|
}), [activeColor, color, isActive]);
|
|
52
|
-
return /*#__PURE__*/_jsx(
|
|
60
|
+
return /*#__PURE__*/_jsx(Pressable, _objectSpread(_objectSpread({
|
|
53
61
|
ref: ref,
|
|
54
62
|
"aria-checked": isActive,
|
|
55
63
|
className: cx(insetFocusRingCss, buttonCss, isDisabled && buttonDisabledCss, disabledProp && !allTabsDisabled && disabledCss, className),
|
|
56
64
|
"data-testid": testID,
|
|
57
65
|
disabled: isDisabled,
|
|
66
|
+
font: font,
|
|
67
|
+
fontFamily: fontFamily,
|
|
68
|
+
fontSize: fontSize,
|
|
69
|
+
fontWeight: fontWeight,
|
|
58
70
|
id: id,
|
|
71
|
+
lineHeight: lineHeight,
|
|
59
72
|
onClick: handlePress,
|
|
60
73
|
role: "radio",
|
|
74
|
+
textAlign: textAlign,
|
|
75
|
+
textTransform: textTransform,
|
|
61
76
|
type: "button"
|
|
62
77
|
}, props), {}, {
|
|
63
78
|
children: /*#__PURE__*/_jsx(Box, {
|
|
@@ -66,7 +81,13 @@ const SegmentedTabComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, r
|
|
|
66
81
|
paddingX: 2,
|
|
67
82
|
paddingY: 1,
|
|
68
83
|
children: typeof label === 'string' ? /*#__PURE__*/_jsx(MotionText, _objectSpread(_objectSpread({
|
|
69
|
-
font:
|
|
84
|
+
font: font,
|
|
85
|
+
fontFamily: fontFamily,
|
|
86
|
+
fontSize: fontSize,
|
|
87
|
+
fontWeight: fontWeight,
|
|
88
|
+
lineHeight: lineHeight,
|
|
89
|
+
textAlign: textAlign,
|
|
90
|
+
textTransform: textTransform
|
|
70
91
|
}, motionProps), {}, {
|
|
71
92
|
children: label
|
|
72
93
|
})) : label
|
package/esm/tour/Tour.js
CHANGED
|
@@ -4,9 +4,7 @@ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object
|
|
|
4
4
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
5
5
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
6
6
|
import React, { useCallback, useEffect, useRef } from 'react';
|
|
7
|
-
import { useRefMap } from '@coinbase/cds-common/hooks/useRefMap';
|
|
8
7
|
import { OverlayContentContext } from '@coinbase/cds-common/overlays/OverlayContentContext';
|
|
9
|
-
import { RefMapContext } from '@coinbase/cds-common/system/RefMapContext';
|
|
10
8
|
import { TourContext } from '@coinbase/cds-common/tour/TourContext';
|
|
11
9
|
import { useTour } from '@coinbase/cds-common/tour/useTour';
|
|
12
10
|
import { arrow as arrowMiddleware, autoPlacement, autoUpdate, offset, shift, useFloating } from '@floating-ui/react-dom';
|
|
@@ -70,6 +68,8 @@ const scrollIntoView = async (element, scrollOptions) => {
|
|
|
70
68
|
});
|
|
71
69
|
await waitForScroll();
|
|
72
70
|
};
|
|
71
|
+
const defaultTourStepOffset = 24;
|
|
72
|
+
const defaultTourStepShiftPadding = 32;
|
|
73
73
|
const TourComponent = _ref => {
|
|
74
74
|
var _activeTourStep$Arrow, _activeTourStep$hideO, _activeTourStep$tourM, _activeTourStep$tourM2;
|
|
75
75
|
let {
|
|
@@ -80,7 +80,7 @@ const TourComponent = _ref => {
|
|
|
80
80
|
TourMaskComponent = DefaultTourMask,
|
|
81
81
|
TourStepArrowComponent = DefaultTourStepArrow,
|
|
82
82
|
hideOverlay,
|
|
83
|
-
tourStepOffset =
|
|
83
|
+
tourStepOffset = defaultTourStepOffset,
|
|
84
84
|
tourStepShift,
|
|
85
85
|
tourStepAutoPlacement,
|
|
86
86
|
tourMaskPadding,
|
|
@@ -93,12 +93,20 @@ const TourComponent = _ref => {
|
|
|
93
93
|
id,
|
|
94
94
|
testID
|
|
95
95
|
} = _ref;
|
|
96
|
-
const refMap = useRefMap();
|
|
97
96
|
const tourStepArrowRef = useRef(null);
|
|
98
97
|
const RenderedTourStep = activeTourStep === null || activeTourStep === void 0 ? void 0 : activeTourStep.Component;
|
|
99
98
|
const RenderedTourStepArrow = (_activeTourStep$Arrow = activeTourStep === null || activeTourStep === void 0 ? void 0 : activeTourStep.ArrowComponent) !== null && _activeTourStep$Arrow !== void 0 ? _activeTourStep$Arrow : TourStepArrowComponent;
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
|
|
100
|
+
// This state is used to store the active tour step target element.
|
|
101
|
+
// const [activeTourStepTarget, setActiveTourStepTarget] = useState<HTMLElement | null>(null);
|
|
102
|
+
|
|
103
|
+
const blockScroll = useScrollBlocker();
|
|
104
|
+
const [animation, animationApi] = useSpring(() => ({
|
|
105
|
+
from: {
|
|
106
|
+
opacity: 0
|
|
107
|
+
},
|
|
108
|
+
config: springConfig.slow
|
|
109
|
+
}), []);
|
|
102
110
|
const {
|
|
103
111
|
refs,
|
|
104
112
|
floatingStyles,
|
|
@@ -114,88 +122,110 @@ const TourComponent = _ref => {
|
|
|
114
122
|
})],
|
|
115
123
|
whileElementsMounted: autoUpdate
|
|
116
124
|
});
|
|
117
|
-
const [animation, animationApi] = useSpring(() => ({
|
|
118
|
-
from: {
|
|
119
|
-
opacity: 0
|
|
120
|
-
},
|
|
121
|
-
config: springConfig.slow
|
|
122
|
-
}), []);
|
|
123
125
|
const handleChange = useCallback(tourStep => {
|
|
124
|
-
// If the opacity is already 0, animating it to 0 does not trigger `onRest`
|
|
125
|
-
if (animation.opacity.get() === 0) return onChange(tourStep);
|
|
126
126
|
void animationApi.start({
|
|
127
127
|
to: {
|
|
128
128
|
opacity: 0
|
|
129
129
|
},
|
|
130
130
|
config: springConfig.stiff,
|
|
131
|
-
|
|
131
|
+
onResolve: () => onChange(tourStep)
|
|
132
132
|
});
|
|
133
|
-
}, [
|
|
134
|
-
const revealTourStep = useCallback(async () => {
|
|
135
|
-
var _activeTourStep$scrol;
|
|
136
|
-
if (!disableAutoScroll && !(activeTourStep !== null && activeTourStep !== void 0 && activeTourStep.disableAutoScroll)) await scrollIntoView(activeTourStepTarget, (_activeTourStep$scrol = activeTourStep === null || activeTourStep === void 0 ? void 0 : activeTourStep.scrollOptions) !== null && _activeTourStep$scrol !== void 0 ? _activeTourStep$scrol : scrollOptions);
|
|
137
|
-
refs.setReference(activeTourStepTarget);
|
|
138
|
-
void animationApi.start({
|
|
139
|
-
to: {
|
|
140
|
-
opacity: 1
|
|
141
|
-
},
|
|
142
|
-
config: springConfig.slow
|
|
143
|
-
});
|
|
144
|
-
}, [activeTourStep, activeTourStepTarget, refs, animationApi, disableAutoScroll, scrollOptions]);
|
|
133
|
+
}, [animationApi, onChange]);
|
|
145
134
|
const api = useTour({
|
|
146
135
|
steps,
|
|
147
136
|
activeTourStep,
|
|
148
137
|
onChange: handleChange
|
|
149
138
|
});
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
139
|
+
const {
|
|
140
|
+
activeTourStepTarget,
|
|
141
|
+
setActiveTourStepTarget
|
|
142
|
+
} = api;
|
|
143
|
+
|
|
144
|
+
// Component Lifecycle & Side Effects
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
// This component's visual side effects (scrolling and animations) are driven
|
|
147
|
+
// by a single callback, `handleSetActiveTourStepTarget`.
|
|
148
|
+
//
|
|
149
|
+
// This function is called from the `TourStep` component's ref callback
|
|
150
|
+
// whenever the active step changes. Because the ref callback is tied to the
|
|
151
|
+
// lifecycle of the `TourStep`, it reliably fires whenever a new step becomes
|
|
152
|
+
// active, regardless of whether the change was triggered internally (by a
|
|
153
|
+
// "Next" button) or externally (by a direct prop change).
|
|
154
|
+
//
|
|
155
|
+
// This centralizes the logic for revealing a step: we get the target element,
|
|
156
|
+
// scroll it into view, and then kick off the fade-in animation, all in one
|
|
157
|
+
// sequential, event-driven flow.
|
|
158
|
+
|
|
159
|
+
const handleActiveTourStepTargetChange = useCallback(target => {
|
|
160
|
+
refs.setReference(target);
|
|
161
|
+
setActiveTourStepTarget(target);
|
|
162
|
+
const revealTourStep = async () => {
|
|
163
|
+
// Scroll the new target into view.
|
|
164
|
+
if (!disableAutoScroll && !(activeTourStep !== null && activeTourStep !== void 0 && activeTourStep.disableAutoScroll)) {
|
|
165
|
+
var _activeTourStep$scrol;
|
|
166
|
+
await scrollIntoView(target, (_activeTourStep$scrol = activeTourStep === null || activeTourStep === void 0 ? void 0 : activeTourStep.scrollOptions) !== null && _activeTourStep$scrol !== void 0 ? _activeTourStep$scrol : scrollOptions);
|
|
167
|
+
}
|
|
168
|
+
void animationApi.start({
|
|
169
|
+
to: {
|
|
170
|
+
opacity: 1
|
|
171
|
+
},
|
|
172
|
+
config: springConfig.slow
|
|
173
|
+
});
|
|
174
|
+
};
|
|
154
175
|
void revealTourStep();
|
|
155
|
-
|
|
156
|
-
|
|
176
|
+
}, [refs, setActiveTourStepTarget, disableAutoScroll, activeTourStep === null || activeTourStep === void 0 ? void 0 : activeTourStep.disableAutoScroll, activeTourStep === null || activeTourStep === void 0 ? void 0 : activeTourStep.scrollOptions, animationApi, scrollOptions]);
|
|
177
|
+
|
|
178
|
+
// Manages scroll locking for the tour's duration. `useEffect` is used to
|
|
179
|
+
// guarantee that scroll is re-enabled when the tour is closed or unmounted.
|
|
180
|
+
useEffect(() => {
|
|
181
|
+
if (activeTourStep !== null && activeTourStep !== void 0 && activeTourStep.id) {
|
|
182
|
+
blockScroll(true);
|
|
183
|
+
}
|
|
184
|
+
return () => {
|
|
185
|
+
blockScroll(false);
|
|
186
|
+
};
|
|
187
|
+
}, [activeTourStep, animationApi, blockScroll, disableAutoScroll, scrollOptions]);
|
|
157
188
|
return /*#__PURE__*/_jsx(OverlayContentContext.Provider, {
|
|
158
189
|
value: overlayContentContextValue,
|
|
159
|
-
children: /*#__PURE__*/
|
|
160
|
-
value:
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
})
|
|
190
|
+
children: /*#__PURE__*/_jsxs(TourContext.Provider, {
|
|
191
|
+
value: _objectSpread(_objectSpread({}, api), {}, {
|
|
192
|
+
setActiveTourStepTarget: handleActiveTourStepTargetChange
|
|
193
|
+
}),
|
|
194
|
+
children: [children, !!RenderedTourStep && /*#__PURE__*/_jsx(Portal, {
|
|
195
|
+
containerId: modalContainerId,
|
|
196
|
+
disablePortal: disablePortal,
|
|
197
|
+
children: /*#__PURE__*/_jsxs("div", {
|
|
198
|
+
"aria-label": accessibilityLabel,
|
|
199
|
+
"aria-labelledby": accessibilityLabelledBy,
|
|
200
|
+
"aria-modal": "true",
|
|
201
|
+
className: containerCss,
|
|
202
|
+
"data-testid": testID,
|
|
203
|
+
id: id,
|
|
204
|
+
role: "dialog",
|
|
205
|
+
children: [!((_activeTourStep$hideO = activeTourStep.hideOverlay) !== null && _activeTourStep$hideO !== void 0 ? _activeTourStep$hideO : hideOverlay) && activeTourStepTarget && /*#__PURE__*/_jsx(animated.div, {
|
|
206
|
+
style: animation,
|
|
207
|
+
children: /*#__PURE__*/_jsx(TourMaskComponent, {
|
|
208
|
+
activeTourStepTargetRect: activeTourStepTarget.getBoundingClientRect(),
|
|
209
|
+
borderRadius: (_activeTourStep$tourM = activeTourStep.tourMaskBorderRadius) !== null && _activeTourStep$tourM !== void 0 ? _activeTourStep$tourM : tourMaskBorderRadius,
|
|
210
|
+
padding: (_activeTourStep$tourM2 = activeTourStep.tourMaskPadding) !== null && _activeTourStep$tourM2 !== void 0 ? _activeTourStep$tourM2 : tourMaskPadding
|
|
211
|
+
})
|
|
212
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
213
|
+
ref: refs.setFloating,
|
|
214
|
+
style: floatingStyles,
|
|
215
|
+
children: /*#__PURE__*/_jsx(FocusTrap, {
|
|
216
|
+
children: /*#__PURE__*/_jsxs(animated.div, {
|
|
217
|
+
style: animation,
|
|
218
|
+
children: [/*#__PURE__*/_jsx(RenderedTourStepArrow, {
|
|
219
|
+
ref: tourStepArrowRef,
|
|
220
|
+
arrow: arrow,
|
|
221
|
+
placement: placement,
|
|
222
|
+
style: activeTourStep === null || activeTourStep === void 0 ? void 0 : activeTourStep.arrowStyle
|
|
223
|
+
}), /*#__PURE__*/_jsx(RenderedTourStep, _objectSpread({}, activeTourStep))]
|
|
194
224
|
})
|
|
195
|
-
})
|
|
196
|
-
})
|
|
197
|
-
})
|
|
198
|
-
})
|
|
225
|
+
})
|
|
226
|
+
})]
|
|
227
|
+
})
|
|
228
|
+
})]
|
|
199
229
|
})
|
|
200
230
|
});
|
|
201
231
|
};
|
package/esm/tour/TourStep.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useCallback } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { useTourContext } from '@coinbase/cds-common/tour/TourContext';
|
|
3
3
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
4
4
|
/**
|
|
5
5
|
* The TourStep component wraps the target element (children) that you want to highlight during a step
|
|
@@ -12,9 +12,10 @@ export const TourStep = _ref => {
|
|
|
12
12
|
children
|
|
13
13
|
} = _ref;
|
|
14
14
|
const {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
activeTourStep,
|
|
16
|
+
setActiveTourStepTarget
|
|
17
|
+
} = useTourContext();
|
|
18
|
+
const refCallback = useCallback(ref => (activeTourStep === null || activeTourStep === void 0 ? void 0 : activeTourStep.id) === id && ref && setActiveTourStepTarget(ref), [activeTourStep, id, setActiveTourStepTarget]);
|
|
18
19
|
return /*#__PURE__*/_jsx("div", {
|
|
19
20
|
ref: refCallback,
|
|
20
21
|
children: children
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coinbase/cds-web",
|
|
3
|
-
"version": "8.13.
|
|
3
|
+
"version": "8.13.6",
|
|
4
4
|
"description": "Coinbase Design System - Web",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -147,9 +147,9 @@
|
|
|
147
147
|
"react-dom": "^18.3.1"
|
|
148
148
|
},
|
|
149
149
|
"dependencies": {
|
|
150
|
-
"@coinbase/cds-common": "^8.13.
|
|
150
|
+
"@coinbase/cds-common": "^8.13.6",
|
|
151
151
|
"@coinbase/cds-icons": "^5.4.1",
|
|
152
|
-
"@coinbase/cds-illustrations": "^4.
|
|
152
|
+
"@coinbase/cds-illustrations": "^4.23.0",
|
|
153
153
|
"@coinbase/cds-lottie-files": "^3.3.1",
|
|
154
154
|
"@coinbase/cds-utils": "^2.3.2",
|
|
155
155
|
"@floating-ui/react-dom": "^2.1.1",
|