@clayui/tooltip 3.156.0 → 3.158.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,35 +1,39 @@
1
- /**
2
- * SPDX-FileCopyrightText: © 2019 Liferay, Inc. <https://liferay.com>
3
- * SPDX-License-Identifier: BSD-3-Clause
4
- */
5
-
6
- import { ClayPortal, Keys, delegate, useInteractionFocus } from '@clayui/shared';
7
- import React, { useCallback, useEffect, useReducer, useRef } from 'react';
8
- import warning from 'warning';
9
- import { Tooltip } from "./Tooltip.js";
10
- import { useAlign } from "./useAlign.js";
11
- import { useClosestTitle } from "./useClosestTitle.js";
12
- import { useTooltipState } from "./useTooltipState.js";
1
+ import {
2
+ ClayPortal,
3
+ Keys,
4
+ delegate,
5
+ useInteractionFocus
6
+ } from "@clayui/shared";
7
+ import React, { useCallback, useEffect, useReducer, useRef } from "react";
8
+ import warning from "warning";
9
+ import { Tooltip } from "./Tooltip";
10
+ import { useAlign } from "./useAlign";
11
+ import { useClosestTitle } from "./useClosestTitle";
12
+ import { useTooltipState } from "./useTooltipState";
13
13
  const initialState = {
14
- align: 'top',
14
+ align: "top",
15
15
  floating: false,
16
16
  setAsHTML: false,
17
- title: ''
17
+ title: ""
18
18
  };
19
- const TRIGGER_HIDE_EVENTS = ['dragstart', 'mouseout', 'mouseup', 'pointerup', 'touchend'];
20
- const TRIGGER_SHOW_EVENTS = ['mouseover', 'mouseup', 'pointerdown', 'touchstart'];
21
- const reducer = (state, _ref) => {
22
- let {
23
- type,
24
- ...payload
25
- } = _ref;
19
+ const TRIGGER_HIDE_EVENTS = [
20
+ "dragstart",
21
+ "mouseout",
22
+ "mouseup",
23
+ "pointerup",
24
+ "touchend"
25
+ ];
26
+ const TRIGGER_SHOW_EVENTS = [
27
+ "mouseover",
28
+ "mouseup",
29
+ "pointerdown",
30
+ "touchstart"
31
+ ];
32
+ function reducer(state, { type, ...payload }) {
26
33
  switch (type) {
27
- case 'update':
28
- return {
29
- ...state,
30
- ...payload
31
- };
32
- case 'reset':
34
+ case "update":
35
+ return { ...state, ...payload };
36
+ case "reset":
33
37
  return {
34
38
  ...state,
35
39
  align: initialState.align,
@@ -38,58 +42,36 @@ const reducer = (state, _ref) => {
38
42
  default:
39
43
  throw new TypeError();
40
44
  }
41
- };
42
- export const ClayTooltipProvider = _ref2 => {
43
- let {
44
- autoAlign = true,
45
- children,
46
- containerProps = {},
47
- contentRenderer = props => props.title,
48
- delay = 600,
49
- scope
50
- } = _ref2;
51
- const [{
52
- align,
53
- floating,
54
- setAsHTML,
55
- title = ''
56
- }, dispatch] = useReducer(reducer, initialState);
45
+ }
46
+ function ClayTooltipProvider({
47
+ autoAlign = true,
48
+ children,
49
+ containerProps = {},
50
+ contentRenderer = (props) => props.title,
51
+ delay = 600,
52
+ scope
53
+ }) {
54
+ const [{ align, floating, setAsHTML, title = "" }, dispatch] = useReducer(
55
+ reducer,
56
+ initialState
57
+ );
57
58
  const tooltipRef = useRef(null);
58
- const {
59
- getInteraction,
60
- isFocusVisible
61
- } = useInteractionFocus();
62
- const isHovered = useRef(false);
63
- const isFocused = useRef(false);
64
- const {
65
- close,
66
- isOpen,
67
- open
68
- } = useTooltipState({
69
- delay
70
- });
71
- const {
72
- forceHide,
73
- getProps,
74
- onHide,
75
- target,
76
- titleNode
77
- } = useClosestTitle({
59
+ const { getInteraction, isFocusVisible } = useInteractionFocus();
60
+ const isHoveredRef = useRef(false);
61
+ const isFocusedRef = useRef(false);
62
+ const { close, isOpen, open } = useTooltipState({ delay });
63
+ const { forceHide, getProps, onHide, target, titleNode } = useClosestTitle({
78
64
  forceHide: useCallback(() => {
79
- dispatch({
80
- type: 'reset'
81
- });
65
+ dispatch({ type: "reset" });
82
66
  close();
83
67
  }, []),
84
68
  onClick: useCallback(() => {
85
- isFocused.current = false;
86
- isHovered.current = false;
69
+ isFocusedRef.current = false;
70
+ isHoveredRef.current = false;
87
71
  }, []),
88
72
  onHide: useCallback(() => {
89
- if (!isHovered.current && !isFocused.current) {
90
- dispatch({
91
- type: 'reset'
92
- });
73
+ if (!isHoveredRef.current && !isFocusedRef.current) {
74
+ dispatch({ type: "reset" });
93
75
  close();
94
76
  }
95
77
  }, []),
@@ -100,109 +82,134 @@ export const ClayTooltipProvider = _ref2 => {
100
82
  autoAlign,
101
83
  floating,
102
84
  isOpen,
103
- onAlign: useCallback(align => dispatch({
104
- align,
105
- type: 'update'
106
- }), []),
85
+ onAlign: useCallback((align2) => dispatch({ align: align2, type: "update" }), []),
107
86
  sourceElement: tooltipRef,
108
87
  targetElement: titleNode,
109
88
  title
110
89
  });
111
- const onShow = useCallback(event => {
112
- if (isHovered.current || isFocused.current) {
113
- const props = getProps(event, isHovered.current);
114
- if (props) {
115
- dispatch({
116
- align: props.align ?? align,
117
- floating: props.floating,
118
- setAsHTML: props.setAsHTML,
119
- title: props.title,
120
- type: 'update'
121
- });
122
- open(isFocused.current, props.delay ? Number(props.delay) : undefined);
90
+ const onShow = useCallback(
91
+ (event) => {
92
+ if (isHoveredRef.current || isFocusedRef.current) {
93
+ const props = getProps(event, isHoveredRef.current);
94
+ if (props) {
95
+ dispatch({
96
+ align: props.align ?? align,
97
+ floating: props.floating,
98
+ setAsHTML: props.setAsHTML,
99
+ title: props.title,
100
+ type: "update"
101
+ });
102
+ open(
103
+ isFocusedRef.current,
104
+ props.delay ? Number(props.delay) : void 0
105
+ );
106
+ }
123
107
  }
124
- }
125
- }, [align]);
108
+ },
109
+ [align]
110
+ );
126
111
  useEffect(() => {
127
- const handleEsc = event => {
112
+ const handleEsc = (event) => {
128
113
  if (isOpen && event.key === Keys.Esc) {
129
114
  event.stopImmediatePropagation();
130
115
  forceHide();
131
116
  }
132
117
  };
133
- document.addEventListener('keyup', handleEsc, true);
134
- return () => document.removeEventListener('keyup', handleEsc, true);
118
+ document.addEventListener("keyup", handleEsc, true);
119
+ return () => document.removeEventListener("keyup", handleEsc, true);
135
120
  }, [isOpen]);
136
- const onHoverStart = event => {
137
- if (getInteraction() === 'pointer') {
138
- isHovered.current = true;
121
+ const onHoverStart = (event) => {
122
+ if (getInteraction() === "pointer") {
123
+ isHoveredRef.current = true;
139
124
  } else {
140
- isHovered.current = false;
125
+ isHoveredRef.current = false;
141
126
  }
142
127
  onShow(event);
143
128
  };
144
- const onHoverEnd = event => {
145
- isFocused.current = false;
146
- isHovered.current = false;
129
+ const onHoverEnd = (event) => {
130
+ isFocusedRef.current = false;
131
+ isHoveredRef.current = false;
147
132
  onHide(event);
148
133
  };
149
- const onFocus = event => {
134
+ const onFocus = (event) => {
150
135
  if (isFocusVisible()) {
151
- isFocused.current = true;
136
+ isFocusedRef.current = true;
152
137
  onShow(event);
153
138
  }
154
139
  };
155
- const onBlur = event => {
156
- isFocused.current = false;
157
- isHovered.current = false;
140
+ const onBlur = (event) => {
141
+ isFocusedRef.current = false;
142
+ isHoveredRef.current = false;
158
143
  onHide(event);
159
144
  };
160
145
  useEffect(() => {
161
146
  if (scope) {
162
- const disposeShowEvents = TRIGGER_SHOW_EVENTS.map(eventName => delegate(document.body, eventName, scope, onHoverStart));
163
- const disposeHideEvents = TRIGGER_HIDE_EVENTS.map(eventName => delegate(document.body, eventName, `${scope}, .tooltip`, onHoverEnd));
164
- const disposeShowFocus = delegate(document.body, 'focus', `${scope}, .tooltip`, onFocus, true);
165
- const disposeCloseBlur = delegate(document.body, 'blur', `${scope}, .tooltip`, onBlur, true);
147
+ const disposeShowEvents = TRIGGER_SHOW_EVENTS.map(
148
+ (eventName) => delegate(document.body, eventName, scope, onHoverStart)
149
+ );
150
+ const disposeHideEvents = TRIGGER_HIDE_EVENTS.map(
151
+ (eventName) => delegate(
152
+ document.body,
153
+ eventName,
154
+ `${scope}, .tooltip`,
155
+ onHoverEnd
156
+ )
157
+ );
158
+ const disposeShowFocus = delegate(
159
+ document.body,
160
+ "focus",
161
+ `${scope}, .tooltip`,
162
+ onFocus,
163
+ true
164
+ );
165
+ const disposeCloseBlur = delegate(
166
+ document.body,
167
+ "blur",
168
+ `${scope}, .tooltip`,
169
+ onBlur,
170
+ true
171
+ );
166
172
  return () => {
167
- disposeShowEvents.forEach(_ref3 => {
168
- let {
169
- dispose
170
- } = _ref3;
171
- return dispose();
172
- });
173
- disposeHideEvents.forEach(_ref4 => {
174
- let {
175
- dispose
176
- } = _ref4;
177
- return dispose();
178
- });
173
+ disposeShowEvents.forEach(({ dispose }) => dispose());
174
+ disposeHideEvents.forEach(({ dispose }) => dispose());
179
175
  disposeShowFocus.dispose();
180
176
  disposeCloseBlur.dispose();
181
177
  };
182
178
  }
183
179
  }, [onShow]);
184
- "production" !== "production" ? warning(typeof children === 'undefined' && typeof scope !== 'undefined' || typeof scope === 'undefined' && typeof children !== 'undefined', '<TooltipProvider />: You must use at least one of the following props: `children` or `scope`.') : void 0;
185
- "production" !== "production" ? warning(typeof children !== 'undefined' || typeof scope !== 'undefined', '<TooltipProvider />: If you want to use `scope`, use <TooltipProvider /> as a singleton and do not pass `children`.') : void 0;
186
- "production" !== "production" ? warning(children?.type !== React.Fragment, '<TooltipProvider />: React Fragment is not allowed as a child to TooltipProvider. Child must be a single HTML element that accepts `onMouseOver` and `onMouseOut`.') : void 0;
180
+ warning(
181
+ typeof children === "undefined" && typeof scope !== "undefined" || typeof scope === "undefined" && typeof children !== "undefined",
182
+ "<TooltipProvider />: You must use at least one of the following props: `children` or `scope`."
183
+ );
184
+ warning(
185
+ typeof children !== "undefined" || typeof scope !== "undefined",
186
+ "<TooltipProvider />: If you want to use `scope`, use <TooltipProvider /> as a singleton and do not pass `children`."
187
+ );
188
+ warning(
189
+ children?.type !== React.Fragment,
190
+ "<TooltipProvider />: React Fragment is not allowed as a child to TooltipProvider. Child must be a single HTML element that accepts `onMouseOver` and `onMouseOut`."
191
+ );
187
192
  const titleContent = contentRenderer({
188
193
  targetNode: target.current,
189
194
  title
190
195
  });
191
- const tooltip = isOpen && /*#__PURE__*/React.createElement(ClayPortal, containerProps, /*#__PURE__*/React.createElement(Tooltip, {
192
- alignPosition: align,
193
- ref: tooltipRef,
194
- show: true
195
- }, setAsHTML && typeof titleContent === 'string' ? /*#__PURE__*/React.createElement("span", {
196
- dangerouslySetInnerHTML: {
197
- __html: titleContent
196
+ const tooltip = isOpen && /* @__PURE__ */ React.createElement(ClayPortal, { ...containerProps }, /* @__PURE__ */ React.createElement(Tooltip, { alignPosition: align, ref: tooltipRef, show: true }, setAsHTML && typeof titleContent === "string" ? /* @__PURE__ */ React.createElement(
197
+ "span",
198
+ {
199
+ dangerouslySetInnerHTML: {
200
+ __html: titleContent
201
+ }
198
202
  }
199
- }) : titleContent));
200
- return /*#__PURE__*/React.createElement(React.Fragment, null, scope ? /*#__PURE__*/React.createElement(React.Fragment, null, tooltip, children) : children && /*#__PURE__*/React.cloneElement(children, {
203
+ ) : titleContent));
204
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, scope ? /* @__PURE__ */ React.createElement(React.Fragment, null, tooltip, children) : children && React.cloneElement(children, {
201
205
  ...children.props,
202
- children: /*#__PURE__*/React.createElement(React.Fragment, null, children.props.children, tooltip),
206
+ children: /* @__PURE__ */ React.createElement(React.Fragment, null, children.props.children, tooltip),
203
207
  onBlur,
204
208
  onFocus,
205
209
  onMouseOut: onHoverEnd,
206
210
  onMouseOver: onHoverStart
207
211
  }));
208
- };
212
+ }
213
+ export {
214
+ ClayTooltipProvider
215
+ };
package/lib/esm/index.js CHANGED
@@ -1,8 +1,8 @@
1
- /**
2
- * SPDX-FileCopyrightText: © 2019 Liferay, Inc. <https://liferay.com>
3
- * SPDX-License-Identifier: BSD-3-Clause
4
- */
5
- import { Tooltip } from "./Tooltip.js";
6
- import { ClayTooltipProvider } from "./TooltipProvider.js";
7
- export { Tooltip, ClayTooltipProvider };
8
- export default Tooltip;
1
+ import { Tooltip } from "./Tooltip";
2
+ import { ClayTooltipProvider } from "./TooltipProvider";
3
+ var src_default = Tooltip;
4
+ export {
5
+ ClayTooltipProvider,
6
+ Tooltip,
7
+ src_default as default
8
+ };
@@ -1,31 +1,35 @@
1
- /**
2
- * SPDX-FileCopyrightText: © 2019 Liferay, Inc. <https://liferay.com>
3
- * SPDX-License-Identifier: BSD-3-Clause
4
- */
5
-
6
- import { doAlign, useMousePosition } from '@clayui/shared';
7
- import { alignPoint } from 'dom-align';
8
- import { useEffect } from 'react';
9
- const ALIGNMENTS = ['top', 'top-right', 'right', 'bottom-right', 'bottom', 'bottom-left', 'left', 'top-left'];
1
+ import { doAlign, useMousePosition } from "@clayui/shared";
2
+ import { alignPoint } from "dom-align";
3
+ import { useEffect } from "react";
4
+ const ALIGNMENTS = [
5
+ "top",
6
+ "top-right",
7
+ "right",
8
+ "bottom-right",
9
+ "bottom",
10
+ "bottom-left",
11
+ "left",
12
+ "top-left"
13
+ ];
10
14
  const ALIGNMENTS_MAP = {
11
- bottom: ['tc', 'bc'],
12
- 'bottom-left': ['tl', 'bl'],
13
- 'bottom-right': ['tr', 'br'],
14
- left: ['cr', 'cl'],
15
- right: ['cl', 'cr'],
16
- top: ['bc', 'tc'],
17
- 'top-left': ['bl', 'tl'],
18
- 'top-right': ['br', 'tr']
15
+ "bottom": ["tc", "bc"],
16
+ "bottom-left": ["tl", "bl"],
17
+ "bottom-right": ["tr", "br"],
18
+ "left": ["cr", "cl"],
19
+ "right": ["cl", "cr"],
20
+ "top": ["bc", "tc"],
21
+ "top-left": ["bl", "tl"],
22
+ "top-right": ["br", "tr"]
19
23
  };
20
24
  const ALIGNMENTS_INVERSE_MAP = {
21
- bctc: 'top',
22
- bltl: 'top-left',
23
- brtr: 'top-right',
24
- clcr: 'right',
25
- crcl: 'left',
26
- tcbc: 'bottom',
27
- tlbl: 'bottom-left',
28
- trbr: 'bottom-right'
25
+ bctc: "top",
26
+ bltl: "top-left",
27
+ brtr: "top-right",
28
+ clcr: "right",
29
+ crcl: "left",
30
+ tcbc: "bottom",
31
+ tlbl: "bottom-left",
32
+ trbr: "bottom-right"
29
33
  };
30
34
  const BOTTOM_OFFSET = [0, 7];
31
35
  const LEFT_OFFSET = [-7, 0];
@@ -43,37 +47,40 @@ const OFFSET_MAP = {
43
47
  };
44
48
  const ALIGNMENTS_FORCE_MAP = {
45
49
  ...ALIGNMENTS_INVERSE_MAP,
46
- bctc: 'top-left',
47
- tcbc: 'bottom-left'
50
+ bctc: "top-left",
51
+ tcbc: "bottom-left"
48
52
  };
49
- export function useAlign(_ref) {
50
- let {
51
- align,
52
- autoAlign,
53
- floating,
54
- isOpen,
55
- onAlign,
56
- sourceElement,
57
- targetElement,
58
- title
59
- } = _ref;
53
+ function useAlign({
54
+ align,
55
+ autoAlign,
56
+ floating,
57
+ isOpen,
58
+ onAlign,
59
+ sourceElement,
60
+ targetElement,
61
+ title
62
+ }) {
60
63
  const mousePosition = useMousePosition(20);
61
64
  useEffect(() => {
62
65
  if (sourceElement.current && isOpen && floating) {
63
- const points = ALIGNMENTS_MAP[align || 'top'];
66
+ const points = ALIGNMENTS_MAP[align || "top"];
64
67
  const [clientX, clientY] = mousePosition;
65
- alignPoint(sourceElement.current, {
66
- clientX,
67
- clientY
68
- }, {
69
- offset: OFFSET_MAP[points.join('')],
70
- points
71
- });
68
+ alignPoint(
69
+ sourceElement.current,
70
+ {
71
+ clientX,
72
+ clientY
73
+ },
74
+ {
75
+ offset: OFFSET_MAP[points.join("")],
76
+ points
77
+ }
78
+ );
72
79
  }
73
80
  }, [isOpen, floating]);
74
81
  useEffect(() => {
75
82
  if (targetElement.current && sourceElement.current && isOpen && !floating) {
76
- const points = ALIGNMENTS_MAP[align || 'top'];
83
+ const points = ALIGNMENTS_MAP[align || "top"];
77
84
  const alignment = doAlign({
78
85
  overflow: {
79
86
  adjustX: autoAlign,
@@ -83,8 +90,10 @@ export function useAlign(_ref) {
83
90
  sourceElement: sourceElement.current,
84
91
  targetElement: targetElement.current
85
92
  });
86
- const alignmentString = alignment.points.join('');
87
- const pointsString = points.join('');
93
+ const alignmentString = alignment.points.join(
94
+ ""
95
+ );
96
+ const pointsString = points.join("");
88
97
  if (alignment.overflow.adjustX) {
89
98
  onAlign(ALIGNMENTS_FORCE_MAP[alignmentString]);
90
99
  } else if (pointsString !== alignmentString) {
@@ -92,4 +101,7 @@ export function useAlign(_ref) {
92
101
  }
93
102
  }
94
103
  }, [align, title, isOpen]);
95
- }
104
+ }
105
+ export {
106
+ useAlign
107
+ };