@stokr/components-library 3.0.72-beta.7 → 3.0.73

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.
@@ -7,7 +7,7 @@ const Chip = ({ children, isActive = false, onClick = () => {
7
7
  }, tooltip = null, tooltipProps, ...props }) => {
8
8
  return /* @__PURE__ */ jsxs(StyledChip, { onClick, isActive, ...props, children: [
9
9
  /* @__PURE__ */ jsx(ChipText, { children }),
10
- tooltip && /* @__PURE__ */ jsx(InfoIcon, { title: tooltip, position: "top", noMarginLeft: true, noMarginRight: true, ...tooltipProps })
10
+ tooltip && /* @__PURE__ */ jsx(InfoIcon, { title: tooltip, position: "top", noMarginLeft: true, noMarginRight: true, tooltipProps })
11
11
  ] });
12
12
  };
13
13
  Chip.propTypes = {
@@ -0,0 +1,47 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import { Tooltip } from "../Tooltip/Tooltip.js";
4
+ import { CopyToClipboardButton } from "../CryptoAddress/CryptoAddress.styles.js";
5
+ import { copyTextToClipboard } from "../../utils/copy-text-to-clipboard.js";
6
+ import { CopyTrigger } from "./CopyToClipboardTooltip.styles.js";
7
+ const CopyToClipboardTooltip = ({
8
+ value,
9
+ buttonStyle,
10
+ onCopy,
11
+ children,
12
+ copiedLabel = "Copied to clipboard!",
13
+ idleLabel = "Click to copy to clipboard.",
14
+ resetAfter = 1500
15
+ }) => {
16
+ const [copyNonce, setCopyNonce] = useState(0);
17
+ const copied = copyNonce > 0;
18
+ useEffect(() => {
19
+ if (!copyNonce) return void 0;
20
+ const timer = setTimeout(() => setCopyNonce(0), resetAfter);
21
+ return () => clearTimeout(timer);
22
+ }, [copyNonce, resetAfter]);
23
+ const copy = (event) => {
24
+ event.preventDefault();
25
+ event.stopPropagation();
26
+ copyTextToClipboard(value, () => {
27
+ setCopyNonce((n) => n + 1);
28
+ onCopy?.(value);
29
+ });
30
+ };
31
+ return /* @__PURE__ */ jsx(Tooltip, { placement: "top", content: copied ? copiedLabel : idleLabel, interactive: false, children: /* @__PURE__ */ jsx(
32
+ CopyTrigger,
33
+ {
34
+ role: "button",
35
+ tabIndex: 0,
36
+ "aria-label": idleLabel,
37
+ onClick: copy,
38
+ onKeyDown: (event) => {
39
+ if (event.key === "Enter" || event.key === " ") copy(event);
40
+ },
41
+ children: children || /* @__PURE__ */ jsx(CopyToClipboardButton, { style: buttonStyle })
42
+ }
43
+ ) });
44
+ };
45
+ export {
46
+ CopyToClipboardTooltip
47
+ };
@@ -0,0 +1,16 @@
1
+ import styled from "styled-components";
2
+ const CopyTrigger = styled.span`
3
+ display: inline-flex;
4
+ align-items: center;
5
+ cursor: pointer;
6
+ line-height: 0;
7
+
8
+ &:focus-visible {
9
+ outline: 2px solid currentColor;
10
+ outline-offset: 2px;
11
+ border-radius: 2px;
12
+ }
13
+ `;
14
+ export {
15
+ CopyTrigger
16
+ };
@@ -1,25 +1,13 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import React__default, { useState } from "react";
2
+ import React__default from "react";
3
3
  import PropTypes from "prop-types";
4
- import { Tooltip } from "react-tippy";
5
- import { CopyToClipboard } from "react-copy-to-clipboard";
6
- import { Container, DataWrapper, CheckMark, Head, Title, Status, TitleSide, AddressWrap, Address, Body, DataBox, Value, Equal, InfoBox, OptionsWrapper, CopyToClipboardButton } from "./CryptoAddress.styles.js";
4
+ import { Tooltip } from "../Tooltip/Tooltip.js";
5
+ import { CopyToClipboardTooltip } from "../CopyToClipboardTooltip/CopyToClipboardTooltip.js";
6
+ import { Container, DataWrapper, CheckMark, Head, Title, Status, TitleSide, AddressWrap, Address, Body, DataBox, Value, Equal, InfoBox, OptionsWrapper } from "./CryptoAddress.styles.js";
7
7
  import stdin_default$1 from "./RadioWrap.js";
8
8
  import stdin_default$2 from "./ComponentWrap.js";
9
9
  import getShortAddress from "../../utils/get-short-address.js";
10
- const copyToClipBoard = (value, isCopied, setCopy) => /* @__PURE__ */ jsx(
11
- Tooltip,
12
- {
13
- position: "top",
14
- title: isCopied ? "Copied to clipboard!" : "Click to copy to clipboard.",
15
- theme: "light",
16
- arrow: true,
17
- hideOnClick: false,
18
- onHidden: () => setCopy(false),
19
- duration: 200,
20
- children: /* @__PURE__ */ jsx(CopyToClipboard, { text: value, onCopy: () => setCopy(true), children: /* @__PURE__ */ jsx(CopyToClipboardButton, {}) })
21
- }
22
- );
10
+ const copyToClipBoard = (value) => /* @__PURE__ */ jsx(CopyToClipboardTooltip, { value });
23
11
  const defaultData = {
24
12
  value: "",
25
13
  unit: "",
@@ -57,7 +45,6 @@ const CryptoAddress = ({
57
45
  dataValueStyle,
58
46
  valueChildMarginLeft
59
47
  }) => {
60
- const [copiedAddressToClipboard, setCopiedAddressToClipboard] = useState(false);
61
48
  return /* @__PURE__ */ jsx(Container, { style: containerStyle, children: /* @__PURE__ */ jsx(stdin_default$1, { radio, hide: radio && radio.hide, children: /* @__PURE__ */ jsx(stdin_default$2, { wrapped, borderTop, borderBottom: !noBorderBottom && borderBottom, children: /* @__PURE__ */ jsxs(DataWrapper, { withOptions: !!sideOptions, style: wrapperStyle, children: [
62
49
  radio && !radio.hide && /* @__PURE__ */ jsx(CheckMark, {}),
63
50
  /* @__PURE__ */ jsxs(Head, { noBody, noHead, flexHead, style: headStyle, children: [
@@ -67,8 +54,8 @@ const CryptoAddress = ({
67
54
  ] }),
68
55
  /* @__PURE__ */ jsxs(TitleSide, { children: [
69
56
  address && /* @__PURE__ */ jsxs(AddressWrap, { children: [
70
- /* @__PURE__ */ jsx(Tooltip, { position: "top", title: address, theme: "light", arrow: true, duration: 200, children: /* @__PURE__ */ jsx(Address, { children: getShortAddress(address) }) }),
71
- /* @__PURE__ */ jsx("div", { onClick: (e) => e.preventDefault(), children: copyToClipBoard(address, copiedAddressToClipboard, setCopiedAddressToClipboard) })
57
+ /* @__PURE__ */ jsx(Tooltip, { placement: "top", content: address, children: /* @__PURE__ */ jsx(Address, { children: getShortAddress(address) }) }),
58
+ /* @__PURE__ */ jsx("div", { onClick: (e) => e.preventDefault(), children: copyToClipBoard(address) })
72
59
  ] }),
73
60
  src && /* @__PURE__ */ jsx("img", { src, alt: "project logo", height: "50", width: 100, style: { objectFit: "contain" } })
74
61
  ] })
@@ -77,19 +64,8 @@ const CryptoAddress = ({
77
64
  /* @__PURE__ */ jsxs(DataBox, { style: dataBoxStyle, children: [
78
65
  data.value && /* @__PURE__ */ jsxs(Value, { fontSize, style: dataValueStyle, childMarginLeft: valueChildMarginLeft, children: [
79
66
  data.unit && `${data.unit} `,
80
- data.shortAddress ? /* @__PURE__ */ jsx(
81
- Tooltip,
82
- {
83
- position: "top",
84
- title: data.value,
85
- theme: "light",
86
- arrow: true,
87
- duration: 200,
88
- style: { margin: 0 },
89
- children: getShortAddress(data.value)
90
- }
91
- ) : data.value,
92
- data.tooltip && /* @__PURE__ */ jsx("div", { children: copyToClipBoard(data.value, copiedAddressToClipboard, setCopiedAddressToClipboard) })
67
+ data.shortAddress ? /* @__PURE__ */ jsx(Tooltip, { placement: "top", content: data.value, children: getShortAddress(data.value) }) : data.value,
68
+ data.tooltip && /* @__PURE__ */ jsx("div", { children: copyToClipBoard(data.value) })
93
69
  ] }),
94
70
  data.eqValue && /* @__PURE__ */ jsxs(Equal, { fontSize: eqValueFontSize, style: { eqValueStyle }, children: [
95
71
  "= ",
@@ -1,12 +1,34 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import DOMPurify from "dompurify";
3
- import PropTypes from "prop-types";
4
- import { useId } from "react";
5
3
  import parse from "html-react-parser";
6
- import { Tooltip } from "react-tippy";
7
- import { colors } from "../../styles/colors.js";
8
4
  import { IoniconsStyles } from "../../styles/ioniconsStyles.js";
9
- import { Container, ArrowColorGlobalStyle, Icon } from "./InfoIcon.styles.js";
5
+ import { Tooltip } from "../Tooltip/Tooltip.js";
6
+ import { Container, Icon } from "./InfoIcon.styles.js";
7
+ const DEAD_TIPPY_PROPS = [
8
+ "animation",
9
+ "animateFill",
10
+ "arrowSize",
11
+ "distance",
12
+ "duration",
13
+ "followCursor",
14
+ "hideOnClick",
15
+ "inertia",
16
+ "interactiveBorder",
17
+ "offset",
18
+ "onHidden",
19
+ "onRequestClose",
20
+ "onShow",
21
+ "onShown",
22
+ "popperOptions",
23
+ "rawTemplate",
24
+ "size",
25
+ "sticky",
26
+ "stickyDuration",
27
+ "tag",
28
+ "touchHold",
29
+ "unmountHTMLWhenHide",
30
+ "useContext"
31
+ ];
10
32
  const InfoIcon = ({
11
33
  title = null,
12
34
  html = null,
@@ -14,67 +36,56 @@ const InfoIcon = ({
14
36
  noMargin = false,
15
37
  noMarginLeft = false,
16
38
  noMarginRight = false,
17
- noIcon,
18
- disabled,
19
- fullWidth,
39
+ noIcon = false,
40
+ disabled = false,
41
+ fullWidth = false,
20
42
  arrow = true,
21
- arrowColor = colors.blue,
22
- theme = "light",
43
+ showArrow,
44
+ arrowColor,
45
+ theme,
23
46
  trigger,
24
47
  outline = false,
25
48
  containerStyle,
26
- ...props
49
+ tooltipProps,
50
+ children,
51
+ style,
52
+ ...rest
27
53
  }) => {
28
- const htmlContent = typeof html === "string" ? parse(DOMPurify.sanitize(html)) : html;
29
- const instanceToken = `info-${useId().replace(/[^a-zA-Z0-9]/g, "")}`;
30
- const tippyTheme = arrowColor ? `${theme} ${instanceToken}` : theme;
54
+ const content = html != null ? typeof html === "string" ? parse(DOMPurify.sanitize(html)) : html : title;
55
+ const containerProps = {};
56
+ Object.keys(rest).forEach((key) => {
57
+ if (DEAD_TIPPY_PROPS.includes(key)) {
58
+ return;
59
+ }
60
+ containerProps[key] = rest[key];
61
+ });
31
62
  return /* @__PURE__ */ jsxs(Fragment, { children: [
32
63
  /* @__PURE__ */ jsx(IoniconsStyles, {}),
33
- /* @__PURE__ */ jsxs(
64
+ /* @__PURE__ */ jsx(
34
65
  Container,
35
66
  {
36
67
  noMargin,
37
68
  noMarginLeft,
38
69
  noMarginRight,
39
70
  fullWidth,
40
- style: containerStyle,
41
- children: [
42
- arrowColor && /* @__PURE__ */ jsx(ArrowColorGlobalStyle, { themeName: instanceToken, color: arrowColor }),
43
- /* @__PURE__ */ jsx(
44
- Tooltip,
45
- {
46
- ...props,
47
- position,
48
- title,
49
- trigger,
50
- html: htmlContent,
51
- useContext: htmlContent != null,
52
- theme: tippyTheme,
53
- arrow: arrowColor ? true : arrow,
54
- duration: 200,
55
- disabled,
56
- children: noIcon ? props.children : /* @__PURE__ */ jsx(Icon, { outline })
57
- }
58
- )
59
- ]
71
+ style: { ...style, ...containerStyle },
72
+ ...containerProps,
73
+ children: /* @__PURE__ */ jsx(
74
+ Tooltip,
75
+ {
76
+ content,
77
+ placement: position,
78
+ disabled,
79
+ showArrow: showArrow ?? arrow,
80
+ arrowColor,
81
+ ...tooltipProps,
82
+ children: noIcon ? children : /* @__PURE__ */ jsx(Icon, { outline })
83
+ }
84
+ )
60
85
  }
61
86
  )
62
87
  ] });
63
88
  };
64
- InfoIcon.propTypes = {
65
- title: PropTypes.string,
66
- html: PropTypes.node,
67
- position: PropTypes.oneOf(["top", "bottom", "left", "right"]),
68
- noMargin: PropTypes.bool,
69
- noMarginLeft: PropTypes.bool,
70
- noMarginRight: PropTypes.bool,
71
- outline: PropTypes.bool,
72
- children: PropTypes.node,
73
- theme: PropTypes.string,
74
- trigger: PropTypes.oneOf(["click", "focus"]),
75
- arrow: PropTypes.bool,
76
- arrowColor: PropTypes.string
77
- };
78
89
  export {
79
90
  InfoIcon,
80
91
  Container as InfoIconContainer,
@@ -1,21 +1,8 @@
1
- import styled, { createGlobalStyle } from "styled-components";
1
+ import styled from "styled-components";
2
2
  import theme from "../../styles/theme.js";
3
- const ArrowColorGlobalStyle = createGlobalStyle`
4
- .tippy-popper[x-placement^='top'] .tippy-tooltip.${(props) => props.themeName}-theme [x-arrow] {
5
- border-top-color: ${(props) => props.color} !important;
6
- }
7
- .tippy-popper[x-placement^='bottom'] .tippy-tooltip.${(props) => props.themeName}-theme [x-arrow] {
8
- border-bottom-color: ${(props) => props.color} !important;
9
- }
10
- .tippy-popper[x-placement^='left'] .tippy-tooltip.${(props) => props.themeName}-theme [x-arrow] {
11
- border-left-color: ${(props) => props.color} !important;
12
- }
13
- .tippy-popper[x-placement^='right'] .tippy-tooltip.${(props) => props.themeName}-theme [x-arrow] {
14
- border-right-color: ${(props) => props.color} !important;
15
- }
16
- `;
3
+ const CONTAINER_OWN_PROPS = ["noMargin", "noMarginLeft", "noMarginRight", "fullWidth"];
17
4
  const Container = styled.div.withConfig({
18
- shouldForwardProp: (props) => !["noMargin", "noMarginLeft", "noMarginRight", "fullWidth"].includes(props)
5
+ shouldForwardProp: (prop) => !CONTAINER_OWN_PROPS.includes(prop)
19
6
  })`
20
7
  display: inline-block;
21
8
  vertical-align: middle;
@@ -23,37 +10,20 @@ const Container = styled.div.withConfig({
23
10
  font-size: 0;
24
11
  line-height: 0;
25
12
 
26
- ${(props) => props.noMargin && `
27
- margin: 0;
28
- `}
29
- ${(props) => props.noMarginLeft && `
30
- margin-left: 0;
31
- `}
32
- ${(props) => props.noMarginRight && `
33
- margin-right: 0;
34
- `}
13
+ ${(props) => props.noMargin && `margin: 0;`}
14
+ ${(props) => props.noMarginLeft && `margin-left: 0;`}
15
+ ${(props) => props.noMarginRight && `margin-right: 0;`}
35
16
 
36
17
  ${(props) => props.fullWidth && `
37
18
  width: 100%;
38
19
  height: 100%;
20
+ display: flex;
21
+ align-items: center;
22
+ justify-content: center;
39
23
  `}
40
-
41
- & > div {
42
- position: relative;
43
- display: inline-block !important;
44
-
45
- ${(props) => props.fullWidth && `
46
- width: 100%;
47
- height: 100%;
48
- display: flex !important;
49
- align-content: center;
50
- flex-wrap: wrap;
51
- justify-content: center;
52
- `}
53
- }
54
24
  `;
55
25
  const Icon = styled.i.withConfig({
56
- shouldForwardProp: (props) => !["outline"].includes(props)
26
+ shouldForwardProp: (prop) => prop !== "outline"
57
27
  }).attrs((props) => ({
58
28
  className: props.outline ? "ion ion-md-information-circle-outline" : "ion ion-md-information-circle"
59
29
  }))`
@@ -64,7 +34,6 @@ const Icon = styled.i.withConfig({
64
34
  vertical-align: middle;
65
35
  font-size: 16px;
66
36
  line-height: 16px;
67
- vertical-align: middle;
68
37
  color: ${() => theme.cGrey2};
69
38
  transition: color 0.2s;
70
39
 
@@ -73,7 +42,6 @@ const Icon = styled.i.withConfig({
73
42
  }
74
43
  `;
75
44
  export {
76
- ArrowColorGlobalStyle,
77
45
  Container,
78
46
  Icon
79
47
  };
@@ -1,11 +1,9 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { useState } from "react";
2
+ import "react";
3
3
  import styled from "styled-components";
4
4
  import { ComponentWrapper } from "../ComponentWrapper/ComponentWrapper.styles.js";
5
5
  import { colors } from "../../styles/colors.js";
6
- import { CopyToClipboard } from "react-copy-to-clipboard";
7
- import { Tooltip } from "react-tippy";
8
- import { CopyToClipboardButton } from "../CryptoAddress/CryptoAddress.styles.js";
6
+ import { CopyToClipboardTooltip } from "../CopyToClipboardTooltip/CopyToClipboardTooltip.js";
9
7
  import stdin_default from "../QRCode/QRCode.js";
10
8
  import { SectionTitle } from "../SectionTitle/SectionTitle.styles.js";
11
9
  import { StatusDot } from "../StatusDot/StatusDot.js";
@@ -110,26 +108,6 @@ const AddressDescription = styled.p`
110
108
  text-align: center;
111
109
  color: ${colors.grey2};
112
110
  `;
113
- const CopyToClipBoardTooltip = ({ value, buttonStyle, onCopy }) => {
114
- const [copied, setCopied] = useState(false);
115
- const handleCopy = () => {
116
- setCopied(true);
117
- if (onCopy) onCopy(value);
118
- };
119
- return /* @__PURE__ */ jsx(
120
- Tooltip,
121
- {
122
- position: "top",
123
- title: copied ? "Copied to clipboard!" : "Click to copy to clipboard",
124
- theme: "light",
125
- arrow: true,
126
- hideOnClick: false,
127
- onHidden: () => setCopied(false),
128
- duration: 200,
129
- children: /* @__PURE__ */ jsx(CopyToClipboard, { text: value, onCopy: handleCopy, children: /* @__PURE__ */ jsx(CopyToClipboardButton, { style: buttonStyle }) })
130
- }
131
- );
132
- };
133
111
  const PaymentDisplay = ({
134
112
  amount,
135
113
  currency = "BTC",
@@ -181,7 +159,7 @@ const PaymentDisplay = ({
181
159
  /* @__PURE__ */ jsx(AmountCurrency, { style: amountTextStyle, children: currency })
182
160
  ] }),
183
161
  showCopyIcons && /* @__PURE__ */ jsx(
184
- CopyToClipBoardTooltip,
162
+ CopyToClipboardTooltip,
185
163
  {
186
164
  value: amount.toString(),
187
165
  buttonStyle: copyButtonStyle || { height: 22, width: 22 },
@@ -197,7 +175,7 @@ const PaymentDisplay = ({
197
175
  /* @__PURE__ */ jsxs(AddressRow, { children: [
198
176
  /* @__PURE__ */ jsx(AddressText, { style: addressTextStyle, children: address }),
199
177
  showCopyIcons && /* @__PURE__ */ jsx(
200
- CopyToClipBoardTooltip,
178
+ CopyToClipboardTooltip,
201
179
  {
202
180
  value: address,
203
181
  buttonStyle: copyButtonStyle || { height: 16, width: 16 },
@@ -29,6 +29,7 @@ const TextBlock = styled.div`
29
29
  `;
30
30
  const Title = styled.h2`
31
31
  margin: 0;
32
+ font-family: 'Open Sans';
32
33
  font-size: 22px;
33
34
  font-weight: 800;
34
35
  line-height: 28px;
@@ -96,7 +96,7 @@ const StatusTag = ({
96
96
  )
97
97
  ] }) });
98
98
  if (tooltip) {
99
- return /* @__PURE__ */ jsx(InfoIcon, { title: tooltip, position: "top", noIcon: true, noMarginLeft: true, noMarginRight: true, ...tooltipProps, children: content });
99
+ return /* @__PURE__ */ jsx(InfoIcon, { title: tooltip, position: "top", noIcon: true, noMarginLeft: true, noMarginRight: true, tooltipProps, children: content });
100
100
  }
101
101
  return content;
102
102
  };
@@ -6,7 +6,7 @@ import { ComponentWrapper } from "../ComponentWrapper/ComponentWrapper.styles.js
6
6
  import { Container, TitleContainer, PendingCounter, Title, Subtitle } from "./ToDoList.styles.js";
7
7
  import stdin_default from "./ToDoListTask.js";
8
8
  import { Icon } from "./ToDoListTask.styles.js";
9
- import { Tooltip } from "react-tippy";
9
+ import { Tooltip } from "../Tooltip/Tooltip.js";
10
10
  const ToDoTaskState = {
11
11
  REJECTED: "rejected",
12
12
  DENIED: "rejected",
@@ -98,14 +98,9 @@ const ToDoList = ({
98
98
  /* @__PURE__ */ jsx(
99
99
  Tooltip,
100
100
  {
101
- position: "right",
102
- title: "Before you invest you must have registered the wallet that can hold your purchased securities. Click below and register it to proceed with your investment.",
103
- theme: "light",
104
- arrow: true,
105
- duration: 200,
106
- size: 40,
107
- style: { cursor: "help", fontSize: 16 },
108
- children: /* @__PURE__ */ jsx(TooltipIcon, { onClick: (e) => e.preventDefault() })
101
+ placement: "right",
102
+ content: "Before you invest you must have registered the wallet that can hold your purchased securities. Click below and register it to proceed with your investment.",
103
+ children: /* @__PURE__ */ jsx(TooltipIcon, { onClick: (e) => e.preventDefault(), style: { fontSize: 16 } })
109
104
  }
110
105
  )
111
106
  ] }) }),
@@ -1,7 +1,7 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import React__default from "react";
3
3
  import PropTypes from "prop-types";
4
- import { Tooltip } from "react-tippy";
4
+ import { Tooltip } from "../Tooltip/Tooltip.js";
5
5
  import { Container, IconContainer, Icon, Content, TitleContainer, Title, State } from "./ToDoListTask.styles.js";
6
6
  import { TooltipIcon } from "../Icon/Icon.style.js";
7
7
  import setRedirectCookie from "../../utils/set-redirect-cookie.js";
@@ -42,7 +42,7 @@ const ToDoTask = ({
42
42
  /* @__PURE__ */ jsxs(Content, { children: [
43
43
  /* @__PURE__ */ jsxs(TitleContainer, { children: [
44
44
  /* @__PURE__ */ jsx(Title, { link: link || openModal, state, children: title }),
45
- tooltip && /* @__PURE__ */ jsx(Tooltip, { position: "right", title: tooltip, theme: "light", arrow: true, duration: 200, children: /* @__PURE__ */ jsx(TooltipIcon, { onClick: (e) => e.preventDefault() }) })
45
+ tooltip && /* @__PURE__ */ jsx(Tooltip, { placement: "right", content: tooltip, children: /* @__PURE__ */ jsx(TooltipIcon, { onClick: (e) => e.preventDefault() }) })
46
46
  ] }),
47
47
  message ? /* @__PURE__ */ jsx(State, { children: message }) : ""
48
48
  ] })
@@ -53,7 +53,7 @@ const ToDoTask = ({
53
53
  /* @__PURE__ */ jsxs(Content, { children: [
54
54
  /* @__PURE__ */ jsxs(TitleContainer, { children: [
55
55
  /* @__PURE__ */ jsx(Title, { state, children: title }),
56
- tooltip && /* @__PURE__ */ jsx(Tooltip, { position: "right", title: tooltip, theme: "light", arrow: true, duration: 200, children: /* @__PURE__ */ jsx(TooltipIcon, { onClick: (e) => e.preventDefault() }) })
56
+ tooltip && /* @__PURE__ */ jsx(Tooltip, { placement: "right", content: tooltip, children: /* @__PURE__ */ jsx(TooltipIcon, { onClick: (e) => e.preventDefault() }) })
57
57
  ] }),
58
58
  message ? /* @__PURE__ */ jsx(State, { children: message }) : ""
59
59
  ] })
@@ -0,0 +1,143 @@
1
+ import { jsx, Fragment, jsxs } from "react/jsx-runtime";
2
+ import { useState, useRef, isValidElement, cloneElement, useEffect, useLayoutEffect } from "react";
3
+ import { useFloating, autoUpdate, offset, flip, shift, arrow, useInteractions, useHover, safePolygon, useFocus, useClick, useDismiss, useRole, useTransitionStyles, useMergeRefs, FloatingPortal, FloatingArrow } from "@floating-ui/react";
4
+ import theme from "../../styles/theme.js";
5
+ import { TriggerWrapper, Bubble } from "./Tooltip.styles.js";
6
+ const useIsomorphicLayoutEffect = typeof document === "undefined" ? useEffect : useLayoutEffect;
7
+ const PLACEMENTS = ["top", "bottom", "left", "right"];
8
+ const FORWARD_REF = /* @__PURE__ */ Symbol.for("react.forward_ref");
9
+ const MEMO = /* @__PURE__ */ Symbol.for("react.memo");
10
+ const acceptsDomRef = (type) => {
11
+ if (typeof type === "string") return true;
12
+ const tag = type?.$$typeof;
13
+ if (tag === FORWARD_REF) return true;
14
+ if (tag === MEMO) return acceptsDomRef(type.type);
15
+ return false;
16
+ };
17
+ const ARROW_WIDTH = 12;
18
+ const ARROW_HEIGHT = 6;
19
+ const GAP = 4;
20
+ const Tooltip = ({
21
+ content,
22
+ children,
23
+ placement = "bottom",
24
+ disabled = false,
25
+ delay = { open: 100, close: 0 },
26
+ showArrow = true,
27
+ arrowColor,
28
+ maxWidth = 260,
29
+ interactive = false,
30
+ open: controlledOpen,
31
+ onOpenChange,
32
+ reference,
33
+ className,
34
+ style,
35
+ zIndex = 9999
36
+ }) => {
37
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
38
+ const arrowRef = useRef(null);
39
+ const isControlled = controlledOpen !== void 0;
40
+ const open = isControlled ? !!controlledOpen : uncontrolledOpen;
41
+ const hasContent = content !== null && content !== void 0 && content !== "";
42
+ const inert = disabled || !hasContent;
43
+ const safePlacement = PLACEMENTS.includes(placement) ? placement : "bottom";
44
+ const { refs, floatingStyles, context } = useFloating({
45
+ open,
46
+ onOpenChange: (next) => {
47
+ if (!isControlled) setUncontrolledOpen(next);
48
+ onOpenChange?.(next);
49
+ },
50
+ placement: safePlacement,
51
+ whileElementsMounted: autoUpdate,
52
+ middleware: [
53
+ offset(ARROW_HEIGHT + GAP),
54
+ flip({ fallbackAxisSideDirection: "start", padding: 8 }),
55
+ shift({ padding: 8 }),
56
+ // eslint-disable-next-line react-hooks/refs -- floating-ui's documented arrow API takes the ref object itself, it is not read during render
57
+ showArrow ? arrow({ element: arrowRef, padding: 6 }) : null
58
+ ].filter(Boolean)
59
+ });
60
+ const hadVirtualReference = useRef(false);
61
+ useIsomorphicLayoutEffect(() => {
62
+ if (reference) {
63
+ hadVirtualReference.current = true;
64
+ refs.setPositionReference(reference);
65
+ return;
66
+ }
67
+ if (hadVirtualReference.current) {
68
+ hadVirtualReference.current = false;
69
+ refs.setPositionReference(null);
70
+ refs.setReference(refs.domReference.current);
71
+ }
72
+ }, [reference, refs]);
73
+ const interactive_ = !inert && !isControlled;
74
+ const { getReferenceProps, getFloatingProps } = useInteractions([
75
+ useHover(context, {
76
+ enabled: interactive_,
77
+ delay,
78
+ mouseOnly: true,
79
+ move: false,
80
+ handleClose: interactive ? safePolygon({ blockPointerEvents: false }) : null
81
+ }),
82
+ useFocus(context, { enabled: interactive_, visibleOnly: true }),
83
+ // Touch has no hover: tap toggles. `ignoreMouse` avoids double-firing with hover.
84
+ // `keyboardHandlers: false` — Enter/Space would otherwise toggle the tooltip shut
85
+ // when a keyboard user activates the trigger (focus already governs visibility).
86
+ useClick(context, { enabled: interactive_, ignoreMouse: true, keyboardHandlers: false }),
87
+ // `ancestorScroll: false` — autoUpdate already keeps the bubble anchored while
88
+ // scrolling, and dismissing on scroll leaves a stationary pointer unable to reopen.
89
+ useDismiss(context, { enabled: !inert && !isControlled, ancestorScroll: false }),
90
+ useRole(context, { role: "tooltip" })
91
+ ]);
92
+ const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {
93
+ duration: 200,
94
+ initial: { opacity: 0 }
95
+ });
96
+ const candidate = isValidElement(children) ? children : null;
97
+ const childRef = (candidate?.props?.ref ?? candidate?.ref) || null;
98
+ const mergedRef = useMergeRefs([refs.setReference, childRef]);
99
+ const childProps = candidate?.props;
100
+ const childIsDisabled = !!childProps?.disabled || childProps?.["aria-disabled"] === true;
101
+ const childTakesRef = !!candidate && acceptsDomRef(candidate.type);
102
+ const child = candidate && childTakesRef && !childIsDisabled ? candidate : null;
103
+ if (inert) return /* @__PURE__ */ jsx(Fragment, { children });
104
+ let trigger = null;
105
+ if (child) {
106
+ trigger = cloneElement(child, {
107
+ ...getReferenceProps({ ...child.props, ref: mergedRef })
108
+ });
109
+ } else if (children != null) {
110
+ trigger = /* @__PURE__ */ jsx(TriggerWrapper, { ref: refs.setReference, ...getReferenceProps(), children });
111
+ }
112
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
113
+ trigger,
114
+ isMounted && /* @__PURE__ */ jsx(FloatingPortal, { children: /* @__PURE__ */ jsxs(
115
+ Bubble,
116
+ {
117
+ ref: refs.setFloating,
118
+ className,
119
+ $maxWidth: maxWidth,
120
+ $interactive: interactive,
121
+ style: { ...style, ...floatingStyles, ...transitionStyles, zIndex },
122
+ ...getFloatingProps(),
123
+ children: [
124
+ content,
125
+ showArrow && /* @__PURE__ */ jsx(
126
+ FloatingArrow,
127
+ {
128
+ ref: arrowRef,
129
+ context,
130
+ width: ARROW_WIDTH,
131
+ height: ARROW_HEIGHT,
132
+ tipRadius: 1,
133
+ fill: arrowColor || theme.cPrimary
134
+ }
135
+ )
136
+ ]
137
+ }
138
+ ) })
139
+ ] });
140
+ };
141
+ export {
142
+ Tooltip
143
+ };