@sproutsocial/seeds-react-tooltip 1.1.20 → 1.1.27
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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +57 -0
- package/dist/esm/index.js +131 -123
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +17 -8
- package/dist/index.d.ts +17 -8
- package/dist/index.js +129 -121
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
- package/src/Tooltip.stories.tsx +125 -0
- package/src/Tooltip.tsx +141 -128
- package/src/TooltipTypes.ts +32 -6
- package/src/__tests__/Tooltip.test.tsx +43 -153
- package/src/__tests__/mapPlacement.test.ts +56 -0
package/dist/index.js
CHANGED
|
@@ -39,7 +39,9 @@ module.exports = __toCommonJS(index_exports);
|
|
|
39
39
|
var React = __toESM(require("react"));
|
|
40
40
|
var import_react = require("react");
|
|
41
41
|
var import_unitless = __toESM(require("@sproutsocial/seeds-motion/unitless"));
|
|
42
|
-
var
|
|
42
|
+
var import_tooltip = require("@base-ui/react/tooltip");
|
|
43
|
+
var import_seeds_react_portal = require("@sproutsocial/seeds-react-portal");
|
|
44
|
+
var import_seeds_react_box2 = __toESM(require("@sproutsocial/seeds-react-box"));
|
|
43
45
|
|
|
44
46
|
// src/styles.ts
|
|
45
47
|
var import_styled_components = __toESM(require("styled-components"));
|
|
@@ -56,46 +58,33 @@ var idCounter = 0;
|
|
|
56
58
|
var hasAttribute = (child, attribute) => {
|
|
57
59
|
return React.isValidElement(child) && child.props[attribute] !== void 0;
|
|
58
60
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
borderColor: "container.border.base",
|
|
87
|
-
...legacyMouseInteraction && {
|
|
88
|
-
onFocus: handleFocus,
|
|
89
|
-
onBlur: handleBlur,
|
|
90
|
-
onMouseEnter: handleFocus,
|
|
91
|
-
onMouseLeave: handleBlur
|
|
92
|
-
},
|
|
93
|
-
tabIndex: 0,
|
|
94
|
-
...rest,
|
|
95
|
-
children
|
|
96
|
-
}
|
|
97
|
-
);
|
|
98
|
-
};
|
|
61
|
+
function mapPlacement(placement) {
|
|
62
|
+
const parts = placement.split("-");
|
|
63
|
+
let side;
|
|
64
|
+
let align = "center";
|
|
65
|
+
switch (parts[0]) {
|
|
66
|
+
case "bottom":
|
|
67
|
+
side = "bottom";
|
|
68
|
+
break;
|
|
69
|
+
case "left":
|
|
70
|
+
side = "left";
|
|
71
|
+
break;
|
|
72
|
+
case "right":
|
|
73
|
+
side = "right";
|
|
74
|
+
break;
|
|
75
|
+
case "top":
|
|
76
|
+
case "auto":
|
|
77
|
+
default:
|
|
78
|
+
side = "top";
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
if (parts[1] === "start") {
|
|
82
|
+
align = "start";
|
|
83
|
+
} else if (parts[1] === "end") {
|
|
84
|
+
align = "end";
|
|
85
|
+
}
|
|
86
|
+
return { side, align };
|
|
87
|
+
}
|
|
99
88
|
var Tooltip = ({
|
|
100
89
|
content,
|
|
101
90
|
children,
|
|
@@ -106,101 +95,120 @@ var Tooltip = ({
|
|
|
106
95
|
zIndex = 7,
|
|
107
96
|
qa,
|
|
108
97
|
popoutProps,
|
|
98
|
+
triggerProps,
|
|
109
99
|
truncated = false,
|
|
110
100
|
onFocus,
|
|
111
101
|
onBlur,
|
|
112
102
|
legacyMouseInteraction,
|
|
113
103
|
...rest
|
|
114
104
|
}) => {
|
|
115
|
-
const [
|
|
116
|
-
const [isOpen, setIsOpen] = (0, import_react.useState)(false);
|
|
105
|
+
const [open, setOpen] = (0, import_react.useState)(false);
|
|
117
106
|
const [id] = (0, import_react.useState)(`Racine-tooltip-${idCounter++}`);
|
|
107
|
+
const triggerRef = (0, import_react.useRef)(null);
|
|
118
108
|
const isInvalidContent = content === null || content === void 0;
|
|
109
|
+
const disablePortalToBody = (0, import_react.useContext)(import_seeds_react_portal.DisablePortalToBodyContext);
|
|
110
|
+
const [portalContainer, setPortalContainer] = (0, import_react.useState)(void 0);
|
|
119
111
|
const resolvedExitDelay = exitDelay !== void 0 ? exitDelay : legacyMouseInteraction ? import_unitless.default.MOTION_DURATION_FAST * 1e3 : 0;
|
|
120
|
-
const show = (e) => {
|
|
121
|
-
onFocus?.(e);
|
|
122
|
-
setShouldShow(true);
|
|
123
|
-
};
|
|
124
|
-
const hide = (e) => {
|
|
125
|
-
onBlur?.(e);
|
|
126
|
-
setShouldShow(false);
|
|
127
|
-
};
|
|
128
112
|
const defaultAppearance = appearance || (typeof content === "object" ? "box" : "pill");
|
|
113
|
+
const { side, align } = mapPlacement(placement);
|
|
114
|
+
const mergedWrapperProps = {
|
|
115
|
+
...popoutProps,
|
|
116
|
+
...triggerProps
|
|
117
|
+
};
|
|
118
|
+
const hasWrapperProps = Object.keys(mergedWrapperProps).length > 0;
|
|
129
119
|
(0, import_react.useEffect)(() => {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (["Escape", "Esc"].includes(e.key)) {
|
|
134
|
-
setIsOpen(false);
|
|
135
|
-
setShouldShow(false);
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
if (shouldShow) {
|
|
139
|
-
timeout = setTimeout(() => setIsOpen(true), enterDelay);
|
|
140
|
-
} else {
|
|
141
|
-
timeout = setTimeout(() => {
|
|
142
|
-
setIsOpen(false);
|
|
143
|
-
}, resolvedExitDelay);
|
|
120
|
+
if (disablePortalToBody && triggerRef.current) {
|
|
121
|
+
const dialogContent = triggerRef.current.closest("[role='dialog']");
|
|
122
|
+
setPortalContainer(dialogContent ?? void 0);
|
|
144
123
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
id,
|
|
162
|
-
...rest,
|
|
163
|
-
children: content
|
|
164
|
-
}
|
|
165
|
-
);
|
|
166
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
167
|
-
import_seeds_react_popout.default,
|
|
124
|
+
}, [disablePortalToBody]);
|
|
125
|
+
if (isInvalidContent) {
|
|
126
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
127
|
+
"span",
|
|
128
|
+
{
|
|
129
|
+
style: truncated ? {
|
|
130
|
+
overflow: "hidden",
|
|
131
|
+
textOverflow: "ellipsis",
|
|
132
|
+
whiteSpace: "nowrap"
|
|
133
|
+
} : {},
|
|
134
|
+
children
|
|
135
|
+
}
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
const tooltipTree = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
139
|
+
import_tooltip.Tooltip.Root,
|
|
168
140
|
{
|
|
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
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
141
|
+
open,
|
|
142
|
+
onOpenChange: setOpen,
|
|
143
|
+
disabled: isInvalidContent,
|
|
144
|
+
disableHoverablePopup: !legacyMouseInteraction,
|
|
145
|
+
children: [
|
|
146
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
147
|
+
import_tooltip.Tooltip.Trigger,
|
|
148
|
+
{
|
|
149
|
+
delay: enterDelay,
|
|
150
|
+
closeDelay: resolvedExitDelay,
|
|
151
|
+
render: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
152
|
+
"span",
|
|
153
|
+
{
|
|
154
|
+
ref: triggerRef,
|
|
155
|
+
onFocus,
|
|
156
|
+
onBlur,
|
|
157
|
+
"data-qa-popout-isopen": open ? "true" : "false",
|
|
158
|
+
"data-qa-tooltip": id,
|
|
159
|
+
...qa || {},
|
|
160
|
+
style: truncated ? {
|
|
161
|
+
overflow: "hidden",
|
|
162
|
+
textOverflow: "ellipsis",
|
|
163
|
+
whiteSpace: "nowrap",
|
|
164
|
+
display: "inline-flex"
|
|
165
|
+
} : void 0
|
|
166
|
+
}
|
|
167
|
+
),
|
|
168
|
+
children: React.isValidElement(children) ? React.cloneElement(children, {
|
|
169
|
+
"aria-expanded": hasAttribute(children, "aria-expanded") ? children.props["aria-expanded"] : void 0,
|
|
170
|
+
"aria-describedby": open ? id : void 0
|
|
171
|
+
}) : children
|
|
172
|
+
}
|
|
173
|
+
),
|
|
174
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tooltip.Tooltip.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
175
|
+
import_tooltip.Tooltip.Positioner,
|
|
176
|
+
{
|
|
177
|
+
side,
|
|
178
|
+
align,
|
|
179
|
+
sideOffset: 4,
|
|
180
|
+
style: { zIndex },
|
|
181
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
182
|
+
import_tooltip.Tooltip.Popup,
|
|
183
|
+
{
|
|
184
|
+
id,
|
|
185
|
+
render: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
186
|
+
StyledTooltipContent,
|
|
187
|
+
{
|
|
188
|
+
role: "tooltip",
|
|
189
|
+
appearance: defaultAppearance,
|
|
190
|
+
borderRadius: defaultAppearance === "box" ? 500 : "5000em",
|
|
191
|
+
px: 400,
|
|
192
|
+
py: defaultAppearance === "box" ? 400 : 200,
|
|
193
|
+
m: 200,
|
|
194
|
+
color: "text.body",
|
|
195
|
+
bg: "container.background.base",
|
|
196
|
+
boxShadow: "medium",
|
|
197
|
+
border: 500,
|
|
198
|
+
borderColor: "container.border.base",
|
|
199
|
+
tabIndex: legacyMouseInteraction ? 0 : void 0,
|
|
200
|
+
...rest
|
|
201
|
+
}
|
|
202
|
+
),
|
|
203
|
+
children: content
|
|
204
|
+
}
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
) })
|
|
208
|
+
]
|
|
202
209
|
}
|
|
203
210
|
);
|
|
211
|
+
return hasWrapperProps ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_box2.default, { ...mergedWrapperProps, children: tooltipTree }) : tooltipTree;
|
|
204
212
|
};
|
|
205
213
|
var Tooltip_default = Tooltip;
|
|
206
214
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/Tooltip.tsx","../src/styles.ts","../src/TooltipTypes.ts"],"sourcesContent":["import Tooltip from \"./Tooltip\";\n\nexport default Tooltip;\nexport { Tooltip };\nexport * from \"./TooltipTypes\";\n","import * as React from \"react\";\nimport { useState, useEffect } from \"react\";\nimport MOTION from \"@sproutsocial/seeds-motion/unitless\";\nimport Popout from \"@sproutsocial/seeds-react-popout\";\nimport { StyledTooltipContent } from \"./styles\";\nimport type { TypeTooltipProps, TypeTooltipContent } from \"./TooltipTypes\";\n\nlet idCounter = 0;\n\nconst hasAttribute = (child: React.ReactNode, attribute: string) => {\n return React.isValidElement(child) && child.props[attribute] !== undefined;\n};\n\n/** Tooltip Styled Popout wrapper for handling events */\nconst TooltipBubble = ({\n appearance = \"pill\",\n children,\n onFocus,\n onBlur,\n legacyMouseInteraction,\n ...rest\n}: TypeTooltipContent) => {\n // @ts-ignore Will fix during refactor\n const handleFocus = (e) => {\n onFocus(e);\n };\n // @ts-ignore Will fix during refactor\n const handleBlur = (e) => {\n onBlur(e);\n };\n return (\n <StyledTooltipContent\n role=\"tooltip\"\n appearance={appearance}\n borderRadius={appearance === \"box\" ? 500 : \"5000em\"}\n px={400}\n py={appearance === \"box\" ? 400 : 200}\n m={200}\n color=\"text.body\"\n bg=\"container.background.base\"\n boxShadow=\"medium\"\n border={500}\n borderColor=\"container.border.base\"\n {...(legacyMouseInteraction && {\n onFocus: handleFocus,\n onBlur: handleBlur,\n onMouseEnter: handleFocus,\n onMouseLeave: handleBlur,\n })}\n tabIndex={0}\n {...rest}\n >\n {children}\n </StyledTooltipContent>\n );\n};\n\n/** Core component */\nconst Tooltip = ({\n content,\n children,\n enterDelay = MOTION.MOTION_DURATION_FAST * 1000,\n exitDelay,\n placement = \"auto\",\n appearance,\n zIndex = 7,\n qa,\n popoutProps,\n truncated = false,\n onFocus,\n onBlur,\n legacyMouseInteraction,\n ...rest\n}: TypeTooltipProps) => {\n const [shouldShow, setShouldShow] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [id] = useState(`Racine-tooltip-${idCounter++}`);\n const isInvalidContent = content === null || content === undefined;\n\n // Compute exitDelay based on legacyMouseInteraction if not explicitly provided\n const resolvedExitDelay =\n exitDelay !== undefined\n ? exitDelay\n : legacyMouseInteraction\n ? MOTION.MOTION_DURATION_FAST * 1000\n : 0;\n\n // @ts-ignore Will fix during refactor\n const show = (e) => {\n onFocus?.(e);\n setShouldShow(true);\n };\n // @ts-ignore Will fix during refactor\n const hide = (e) => {\n onBlur?.(e);\n setShouldShow(false);\n };\n\n const defaultAppearance =\n appearance || (typeof content === \"object\" ? \"box\" : \"pill\");\n\n /** Handles all the logic around whether to display/not display */\n useEffect(() => {\n const documentBody = document.body;\n let timeout;\n const onEsc = (e: KeyboardEvent): void => {\n // older browsers use \"Esc\"\n if ([\"Escape\", \"Esc\"].includes(e.key)) {\n setIsOpen(false);\n setShouldShow(false);\n }\n };\n\n if (shouldShow) {\n timeout = setTimeout(() => setIsOpen(true), enterDelay);\n } else {\n timeout = setTimeout(() => {\n setIsOpen(false);\n }, resolvedExitDelay);\n }\n\n // We only want listeners from the tooltip if its open in the first place\n if (isOpen) {\n documentBody.addEventListener(\"keydown\", onEsc, { capture: true });\n }\n return () => {\n documentBody.removeEventListener(\"keydown\", onEsc, { capture: true });\n clearTimeout(timeout);\n };\n }, [isOpen, setShouldShow, shouldShow, enterDelay, resolvedExitDelay]);\n\n /** The wrapped content of whats inside the Tooltip */\n const TooltipContent = () => (\n <TooltipBubble\n appearance={defaultAppearance}\n onFocus={show}\n onBlur={hide}\n legacyMouseInteraction={legacyMouseInteraction}\n aria-expanded={isOpen}\n id={id}\n {...rest}\n >\n {content}\n </TooltipBubble>\n );\n\n return (\n <Popout\n content={!isInvalidContent ? TooltipContent : undefined}\n isOpen={isOpen}\n placement={placement}\n qa={{\n \"data-qa-tooltip\": id,\n ...qa,\n }}\n id={id + \"-wrapper\"}\n focusOnContent={false}\n zIndex={zIndex}\n aria-haspopup=\"false\"\n display={truncated ? \"flex\" : undefined}\n disableWrapperAria={true} // required so that the child span doesnt take in redundant aria props\n {...popoutProps}\n >\n <span\n onBlur={hide}\n onFocus={show}\n onMouseEnter={show}\n onMouseLeave={hide}\n style={\n truncated\n ? {\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }\n : {}\n }\n >\n {React.isValidElement(children)\n ? React.cloneElement(children as React.ReactElement, {\n //** There may be cases where the Tooltip's child needs to properly describe its role as expanding a drawer, in which case that property takes priority */\n \"aria-expanded\": hasAttribute(children, \"aria-expanded\")\n ? children.props[\"aria-expanded\"]\n : undefined,\n \"aria-describedby\": isOpen ? id : undefined,\n })\n : children}\n </span>\n </Popout>\n );\n};\n\nexport default Tooltip;\n","import styled from \"styled-components\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport type { TypeTooltipContent } from \"./TooltipTypes\";\n\nexport const StyledTooltipContent = styled(Box)<\n Pick<TypeTooltipContent, \"appearance\">\n>`\n font-family: ${(props) => props.theme.fontFamily};\n ${(props) => props.theme.typography[200]}\n text-align: ${(props) => (props.appearance === \"box\" ? \"left\" : \"center\")};\n`;\n","import * as React from \"react\";\nimport type { TypePopoutProps } from \"@sproutsocial/seeds-react-popout\";\nimport type { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\n\nexport interface TypeTooltipProps\n extends Omit<\n TypeBoxProps,\n \"children\" | \"content\" | \"onMouseEnter\" | \"onMouseLeave\"\n > {\n /** The content that the tooltip should be attached to. Hovering or focusing this element will cause the tooltip to appear */\n children: React.ReactNode;\n\n /** The content to be displayed within the tooltip. If there is no content, just the children are rendered */\n content: React.ReactNode;\n\n /** The placement of the tooltip in relation to the children */\n placement?: TypePopoutProps[\"placement\"];\n\n /** The time (in ms) that a user has to be hovered/focused before the tooltip will appear */\n enterDelay?: number;\n\n /** The time (in ms) that a user has to leave hovered/focused before the tooltip will disappear */\n exitDelay?: number;\n\n /**\n * When true, enables mouse interaction on tooltip content and sets exitDelay\n * to MOTION_DURATION_FAST * 1000 by default (instead of 0).\n */\n legacyMouseInteraction?: boolean;\n\n /** Used to override the appearance of the Tooltip content. By default, strings will have the 'pill' appearance, and more complex content will have the 'box' appearance. You can change those defaults by setting this prop. */\n appearance?: \"pill\" | \"box\";\n qa?: object;\n zIndex?: number;\n\n /** Props to be spread onto the underlying Popout component */\n popoutProps?: Partial<TypePopoutProps>;\n\n /** Truncates text into a single line with ellipsis */\n truncated?: boolean;\n\n ariaProps?: Record<string, string>;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface TypeTooltipContent\n extends Pick<TypeTooltipProps, \"appearance\" | \"children\"> {\n onFocus: (e: React.FocusEvent<HTMLDivElement, FocusEvent>) => void;\n onBlur: (e: React.FocusEvent<HTMLDivElement, FocusEvent>) => void;\n legacyMouseInteraction?: boolean;\n}\n"],"mappings":"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","names":["styled","Box","MOTION","Popout","React"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/Tooltip.tsx","../src/styles.ts","../src/TooltipTypes.ts"],"sourcesContent":["import Tooltip from \"./Tooltip\";\n\nexport default Tooltip;\nexport { Tooltip };\nexport * from \"./TooltipTypes\";\n","import * as React from \"react\";\nimport { useState, useRef, useEffect, useContext } from \"react\";\nimport MOTION from \"@sproutsocial/seeds-motion/unitless\";\nimport { Tooltip as BaseTooltip } from \"@base-ui/react/tooltip\";\nimport { DisablePortalToBodyContext } from \"@sproutsocial/seeds-react-portal\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport { StyledTooltipContent } from \"./styles\";\nimport type { TypeTooltipProps } from \"./TooltipTypes\";\n\nlet idCounter = 0;\n\nconst hasAttribute = (child: React.ReactNode, attribute: string) => {\n return React.isValidElement(child) && child.props[attribute] !== undefined;\n};\n\ntype Side = \"top\" | \"bottom\" | \"left\" | \"right\";\ntype Align = \"start\" | \"center\" | \"end\";\n\n// `auto`, `auto-start`, and `auto-end` resolve to `side: \"top\"` (with align\n// taken from the suffix) and rely on base-ui's Positioner collision flipping at\n// runtime, rather than Popper's old best-initial-side selection. Exported for\n// unit testing of this mapping.\nexport function mapPlacement(placement: string): { side: Side; align: Align } {\n const parts = placement.split(\"-\");\n let side: Side;\n let align: Align = \"center\";\n\n switch (parts[0]) {\n case \"bottom\":\n side = \"bottom\";\n break;\n case \"left\":\n side = \"left\";\n break;\n case \"right\":\n side = \"right\";\n break;\n case \"top\":\n case \"auto\":\n default:\n side = \"top\";\n break;\n }\n\n if (parts[1] === \"start\") {\n align = \"start\";\n } else if (parts[1] === \"end\") {\n align = \"end\";\n }\n\n return { side, align };\n}\n\nconst Tooltip = ({\n content,\n children,\n enterDelay = MOTION.MOTION_DURATION_FAST * 1000,\n exitDelay,\n placement = \"auto\",\n appearance,\n zIndex = 7,\n qa,\n popoutProps,\n triggerProps,\n truncated = false,\n onFocus,\n onBlur,\n legacyMouseInteraction,\n ...rest\n}: TypeTooltipProps) => {\n const [open, setOpen] = useState(false);\n const [id] = useState(`Racine-tooltip-${idCounter++}`);\n const triggerRef = useRef<HTMLSpanElement>(null);\n const isInvalidContent = content === null || content === undefined;\n const disablePortalToBody = useContext(DisablePortalToBodyContext);\n const [portalContainer, setPortalContainer] = useState<\n HTMLElement | undefined\n >(undefined);\n\n const resolvedExitDelay =\n exitDelay !== undefined\n ? exitDelay\n : legacyMouseInteraction\n ? MOTION.MOTION_DURATION_FAST * 1000\n : 0;\n\n const defaultAppearance =\n appearance || (typeof content === \"object\" ? \"box\" : \"pill\");\n\n const { side, align } = mapPlacement(placement);\n\n const mergedWrapperProps = {\n ...popoutProps,\n ...triggerProps,\n };\n\n const hasWrapperProps = Object.keys(mergedWrapperProps).length > 0;\n\n useEffect(() => {\n if (disablePortalToBody && triggerRef.current) {\n const dialogContent =\n triggerRef.current.closest<HTMLElement>(\"[role='dialog']\");\n setPortalContainer(dialogContent ?? undefined);\n }\n }, [disablePortalToBody]);\n\n if (isInvalidContent) {\n return (\n <span\n style={\n truncated\n ? {\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }\n : {}\n }\n >\n {children}\n </span>\n );\n }\n\n const tooltipTree = (\n <BaseTooltip.Root\n open={open}\n onOpenChange={setOpen}\n disabled={isInvalidContent}\n disableHoverablePopup={!legacyMouseInteraction}\n >\n <BaseTooltip.Trigger\n delay={enterDelay}\n closeDelay={resolvedExitDelay}\n render={\n <span\n ref={triggerRef}\n onFocus={onFocus}\n onBlur={onBlur}\n data-qa-popout-isopen={open ? \"true\" : \"false\"}\n data-qa-tooltip={id}\n {...(qa || {})}\n style={\n truncated\n ? {\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n display: \"inline-flex\",\n }\n : undefined\n }\n />\n }\n >\n {React.isValidElement(children)\n ? React.cloneElement(children as React.ReactElement, {\n \"aria-expanded\": hasAttribute(children, \"aria-expanded\")\n ? children.props[\"aria-expanded\"]\n : undefined,\n \"aria-describedby\": open ? id : undefined,\n })\n : children}\n </BaseTooltip.Trigger>\n <BaseTooltip.Portal container={portalContainer}>\n <BaseTooltip.Positioner\n side={side}\n align={align}\n sideOffset={4}\n style={{ zIndex }}\n >\n <BaseTooltip.Popup\n id={id}\n render={\n <StyledTooltipContent\n role=\"tooltip\"\n appearance={defaultAppearance}\n borderRadius={defaultAppearance === \"box\" ? 500 : \"5000em\"}\n px={400}\n py={defaultAppearance === \"box\" ? 400 : 200}\n m={200}\n color=\"text.body\"\n bg=\"container.background.base\"\n boxShadow=\"medium\"\n border={500}\n borderColor=\"container.border.base\"\n tabIndex={legacyMouseInteraction ? 0 : undefined}\n {...rest}\n />\n }\n >\n {content}\n </BaseTooltip.Popup>\n </BaseTooltip.Positioner>\n </BaseTooltip.Portal>\n </BaseTooltip.Root>\n );\n\n return hasWrapperProps ? (\n <Box {...mergedWrapperProps}>{tooltipTree}</Box>\n ) : (\n tooltipTree\n );\n};\n\nexport default Tooltip;\n","import styled from \"styled-components\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport type { TypeTooltipContent } from \"./TooltipTypes\";\n\nexport const StyledTooltipContent = styled(Box)<\n Pick<TypeTooltipContent, \"appearance\">\n>`\n font-family: ${(props) => props.theme.fontFamily};\n ${(props) => props.theme.typography[200]}\n text-align: ${(props) => (props.appearance === \"box\" ? \"left\" : \"center\")};\n`;\n","import * as React from \"react\";\nimport type { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\n\nexport type TypeTooltipPlacement =\n | \"auto\"\n | \"auto-start\"\n | \"auto-end\"\n | \"top\"\n | \"top-start\"\n | \"top-end\"\n | \"bottom\"\n | \"bottom-start\"\n | \"bottom-end\"\n | \"left\"\n | \"left-start\"\n | \"left-end\"\n | \"right\"\n | \"right-start\"\n | \"right-end\";\n\nexport interface TypeTooltipProps\n extends Omit<\n TypeBoxProps,\n \"children\" | \"content\" | \"onMouseEnter\" | \"onMouseLeave\"\n > {\n /** The content that the tooltip should be attached to. Hovering or focusing this element will cause the tooltip to appear */\n children: React.ReactNode;\n\n /** The content to be displayed within the tooltip. If there is no content, just the children are rendered */\n content: React.ReactNode;\n\n /**\n * The placement of the tooltip in relation to the children.\n *\n * Note: `auto`, `auto-start`, and `auto-end` resolve to the `top` side (with\n * the requested alignment) and rely on base-ui's runtime collision flipping,\n * rather than the legacy Popper.js best-initial-side selection.\n */\n placement?: TypeTooltipPlacement;\n\n /** The time (in ms) that a user has to be hovered/focused before the tooltip will appear */\n enterDelay?: number;\n\n /** The time (in ms) that a user has to leave hovered/focused before the tooltip will disappear */\n exitDelay?: number;\n\n /**\n * When true, enables mouse interaction on tooltip content and sets exitDelay\n * to MOTION_DURATION_FAST * 1000 by default (instead of 0).\n */\n legacyMouseInteraction?: boolean;\n\n /** Used to override the appearance of the Tooltip content. By default, strings will have the 'pill' appearance, and more complex content will have the 'box' appearance. You can change those defaults by setting this prop. */\n appearance?: \"pill\" | \"box\";\n qa?: object;\n zIndex?: number;\n\n /**\n * @deprecated Use `triggerProps` instead. The Tooltip no longer uses Popout internally. This prop is accepted and merged with triggerProps\n */\n popoutProps?: Record<string, unknown>;\n\n /** Props spread onto an outer wrapper Box rendered around the tooltip. Use this to apply layout styles (e.g. `display`, `width`) or other Box props to the element that wraps the tooltip's children. */\n triggerProps?: TypeBoxProps;\n\n /** Truncates text into a single line with ellipsis */\n truncated?: boolean;\n\n ariaProps?: Record<string, string>;\n}\n\nexport interface TypeTooltipContent\n extends Pick<TypeTooltipProps, \"appearance\" | \"children\"> {\n onFocus: (e: React.FocusEvent<HTMLDivElement, FocusEvent>) => void;\n onBlur: (e: React.FocusEvent<HTMLDivElement, FocusEvent>) => void;\n legacyMouseInteraction?: boolean;\n}\n"],"mappings":"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","names":["import_seeds_react_box","styled","Box","MOTION","BaseTooltip","Box","React"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sproutsocial/seeds-react-tooltip",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.27",
|
|
4
4
|
"description": "Seeds React Tooltip",
|
|
5
5
|
"author": "Sprout Social, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,10 +18,11 @@
|
|
|
18
18
|
"test:watch": "jest --watch --coverage=false"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@
|
|
22
|
-
"@sproutsocial/seeds-react-
|
|
23
|
-
"@sproutsocial/seeds-react-
|
|
24
|
-
"@sproutsocial/seeds-react-box": "^1.1.
|
|
21
|
+
"@base-ui/react": "^1.3.0",
|
|
22
|
+
"@sproutsocial/seeds-react-theme": "^4.1.0",
|
|
23
|
+
"@sproutsocial/seeds-react-system-props": "^3.1.1",
|
|
24
|
+
"@sproutsocial/seeds-react-box": "^1.1.21",
|
|
25
|
+
"@sproutsocial/seeds-react-portal": "^1.2.0",
|
|
25
26
|
"@sproutsocial/seeds-motion": "^1.8.2"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
@@ -35,11 +36,10 @@
|
|
|
35
36
|
"@sproutsocial/seeds-tsconfig": "*",
|
|
36
37
|
"@sproutsocial/seeds-testing": "*",
|
|
37
38
|
"@sproutsocial/seeds-react-testing-library": "*",
|
|
38
|
-
"@sproutsocial/seeds-react-icon": "^2.
|
|
39
|
-
"@sproutsocial/seeds-react-banner": "^1.1.
|
|
40
|
-
"@sproutsocial/seeds-react-button": "^2.
|
|
41
|
-
"@sproutsocial/seeds-react-text": "^1.4.
|
|
42
|
-
"@sproutsocial/seeds-react-portal": "^1.2.0"
|
|
39
|
+
"@sproutsocial/seeds-react-icon": "^2.4.0",
|
|
40
|
+
"@sproutsocial/seeds-react-banner": "^1.1.22",
|
|
41
|
+
"@sproutsocial/seeds-react-button": "^2.2.1",
|
|
42
|
+
"@sproutsocial/seeds-react-text": "^1.4.3"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"styled-components": "^5.2.3"
|
package/src/Tooltip.stories.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
1
2
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
3
|
import Banner from "@sproutsocial/seeds-react-banner";
|
|
3
4
|
import Box from "@sproutsocial/seeds-react-box";
|
|
@@ -185,3 +186,127 @@ export const WithLegacyMouseInteraction: Story = {
|
|
|
185
186
|
</Box>
|
|
186
187
|
),
|
|
187
188
|
};
|
|
189
|
+
|
|
190
|
+
const InModalV1Template = () => {
|
|
191
|
+
const [isOpen, setIsOpen] = useState(true);
|
|
192
|
+
// Lazy-load Modal V1 to avoid circular deps in storybook
|
|
193
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
194
|
+
const Modal = require("@sproutsocial/seeds-react-modal").default;
|
|
195
|
+
|
|
196
|
+
return (
|
|
197
|
+
<Box>
|
|
198
|
+
<Button appearance="primary" onClick={() => setIsOpen(true)}>
|
|
199
|
+
Open Modal
|
|
200
|
+
</Button>
|
|
201
|
+
<Modal
|
|
202
|
+
appElementSelector="#storybook-root"
|
|
203
|
+
isOpen={isOpen}
|
|
204
|
+
onClose={() => setIsOpen(false)}
|
|
205
|
+
closeButtonLabel="Close modal"
|
|
206
|
+
label="Modal with Tooltip"
|
|
207
|
+
>
|
|
208
|
+
<Modal.Header title="Tooltip in Modal V1" />
|
|
209
|
+
<Modal.Content>
|
|
210
|
+
<Box p={400} display="flex" justifyContent="center">
|
|
211
|
+
<Tooltip content="This tooltip renders inside the Modal V1">
|
|
212
|
+
<Button appearance="primary">Hover me</Button>
|
|
213
|
+
</Tooltip>
|
|
214
|
+
</Box>
|
|
215
|
+
</Modal.Content>
|
|
216
|
+
</Modal>
|
|
217
|
+
</Box>
|
|
218
|
+
);
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
export const InModal: Story = {
|
|
222
|
+
render: () => <InModalV1Template />,
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
const InModalV2Template = () => {
|
|
226
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
227
|
+
const { ModalV2, ModalHeader, ModalBody } = require("@sproutsocial/seeds-react-modal");
|
|
228
|
+
|
|
229
|
+
return (
|
|
230
|
+
<ModalV2
|
|
231
|
+
aria-label="Modal V2 with Tooltip"
|
|
232
|
+
closeButtonAriaLabel="Close Modal"
|
|
233
|
+
modalTrigger={<Button appearance="primary">Open Modal V2</Button>}
|
|
234
|
+
>
|
|
235
|
+
<ModalHeader title="Tooltip in Modal V2" />
|
|
236
|
+
<ModalBody>
|
|
237
|
+
<Box p={400} display="flex" justifyContent="center">
|
|
238
|
+
<Tooltip content="This tooltip renders inside Modal V2">
|
|
239
|
+
<Button appearance="primary">Hover me</Button>
|
|
240
|
+
</Tooltip>
|
|
241
|
+
</Box>
|
|
242
|
+
</ModalBody>
|
|
243
|
+
</ModalV2>
|
|
244
|
+
);
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
export const InModalV2: Story = {
|
|
248
|
+
render: () => <InModalV2Template />,
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
const InPopoutTemplate = () => {
|
|
252
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
253
|
+
const Popout = require("@sproutsocial/seeds-react-popout").default;
|
|
254
|
+
const [isOpen, setIsOpen] = useState(true);
|
|
255
|
+
|
|
256
|
+
return (
|
|
257
|
+
<Box p={600} display="flex" justifyContent="center">
|
|
258
|
+
<Popout
|
|
259
|
+
content={() => (
|
|
260
|
+
<Box p={400}>
|
|
261
|
+
<Tooltip content="This tooltip renders inside a Popout">
|
|
262
|
+
<Button appearance="secondary">Hover me</Button>
|
|
263
|
+
</Tooltip>
|
|
264
|
+
</Box>
|
|
265
|
+
)}
|
|
266
|
+
isOpen={isOpen}
|
|
267
|
+
placement="bottom"
|
|
268
|
+
>
|
|
269
|
+
<Button appearance="primary" onClick={() => setIsOpen(!isOpen)}>
|
|
270
|
+
Toggle Popout
|
|
271
|
+
</Button>
|
|
272
|
+
</Popout>
|
|
273
|
+
</Box>
|
|
274
|
+
);
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
export const InPopout: Story = {
|
|
278
|
+
render: () => <InPopoutTemplate />,
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
const InDrawerTemplate = () => {
|
|
282
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
283
|
+
const Drawer = require("@sproutsocial/seeds-react-drawer").default;
|
|
284
|
+
const [isOpen, setIsOpen] = useState(true);
|
|
285
|
+
|
|
286
|
+
return (
|
|
287
|
+
<Box>
|
|
288
|
+
<Button appearance="primary" onClick={() => setIsOpen(true)}>
|
|
289
|
+
Open Drawer
|
|
290
|
+
</Button>
|
|
291
|
+
<Drawer
|
|
292
|
+
isOpen={isOpen}
|
|
293
|
+
onClose={() => setIsOpen(false)}
|
|
294
|
+
closeButtonLabel="Close drawer"
|
|
295
|
+
id="tooltip-drawer"
|
|
296
|
+
>
|
|
297
|
+
<Box p={400}>
|
|
298
|
+
<Text as="h3" fontSize={400} fontWeight="bold" mb={400}>
|
|
299
|
+
Tooltip in Drawer
|
|
300
|
+
</Text>
|
|
301
|
+
<Tooltip content="This tooltip renders inside a Drawer">
|
|
302
|
+
<Button appearance="primary">Hover me</Button>
|
|
303
|
+
</Tooltip>
|
|
304
|
+
</Box>
|
|
305
|
+
</Drawer>
|
|
306
|
+
</Box>
|
|
307
|
+
);
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
export const InDrawer: Story = {
|
|
311
|
+
render: () => <InDrawerTemplate />,
|
|
312
|
+
};
|