@ultraviolet/ui 1.0.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.
Files changed (115) hide show
  1. package/LICENSE +189 -0
  2. package/README.md +64 -0
  3. package/dist/index.d.ts +2427 -0
  4. package/dist/react-datepicker/dist/react-datepicker.min.css.js +3 -0
  5. package/dist/react-toastify/dist/ReactToastify.min.css.js +3 -0
  6. package/dist/src/components/ActionBar/index.js +55 -0
  7. package/dist/src/components/Alert/index.js +144 -0
  8. package/dist/src/components/Avatar/index.js +90 -0
  9. package/dist/src/components/Badge/index.js +143 -0
  10. package/dist/src/components/Banner/index.js +117 -0
  11. package/dist/src/components/BarChart/Tooltip.js +63 -0
  12. package/dist/src/components/BarChart/index.js +94 -0
  13. package/dist/src/components/BarStack/index.js +223 -0
  14. package/dist/src/components/Breadcrumbs/index.js +89 -0
  15. package/dist/src/components/Bullet/index.js +137 -0
  16. package/dist/src/components/Button/index.js +303 -0
  17. package/dist/src/components/Card/index.js +81 -0
  18. package/dist/src/components/Carousel/index.js +162 -0
  19. package/dist/src/components/Checkbox/index.js +338 -0
  20. package/dist/src/components/CopyButton/index.js +92 -0
  21. package/dist/src/components/DateInput/index.js +250 -0
  22. package/dist/src/components/EmptyState/index.js +124 -0
  23. package/dist/src/components/Expandable/index.js +84 -0
  24. package/dist/src/components/Icon/index.js +350 -0
  25. package/dist/src/components/LineChart/CustomLegend.js +147 -0
  26. package/dist/src/components/LineChart/Tooltip.js +58 -0
  27. package/dist/src/components/LineChart/helpers.js +75 -0
  28. package/dist/src/components/LineChart/index.js +139 -0
  29. package/dist/src/components/Link/index.js +159 -0
  30. package/dist/src/components/List/Body.js +22 -0
  31. package/dist/src/components/List/Cell.js +38 -0
  32. package/dist/src/components/List/HeaderCell.js +118 -0
  33. package/dist/src/components/List/HeaderRow.js +47 -0
  34. package/dist/src/components/List/ListContext.js +120 -0
  35. package/dist/src/components/List/Row.js +211 -0
  36. package/dist/src/components/List/SelectBar.js +52 -0
  37. package/dist/src/components/List/SkeletonRows.js +54 -0
  38. package/dist/src/components/List/constants.js +3 -0
  39. package/dist/src/components/List/index.js +77 -0
  40. package/dist/src/components/Loader/index.js +87 -0
  41. package/dist/src/components/Menu/Item.js +122 -0
  42. package/dist/src/components/Menu/index.js +143 -0
  43. package/dist/src/components/Modal/index.js +279 -0
  44. package/dist/src/components/Notice/index.js +33 -0
  45. package/dist/src/components/NumberInput/helpers.js +6 -0
  46. package/dist/src/components/NumberInput/index.js +366 -0
  47. package/dist/src/components/Pagination/getPageNumbers.js +32 -0
  48. package/dist/src/components/Pagination/index.js +118 -0
  49. package/dist/src/components/PasswordCheck/index.js +42 -0
  50. package/dist/src/components/PasswordStrengthMeter/index.js +116 -0
  51. package/dist/src/components/PieChart/Legends.js +183 -0
  52. package/dist/src/components/PieChart/Tooltip.js +64 -0
  53. package/dist/src/components/PieChart/index.js +133 -0
  54. package/dist/src/components/PieChart/patterns.js +9 -0
  55. package/dist/src/components/Popover/index.js +131 -0
  56. package/dist/src/components/ProgressBar/index.js +72 -0
  57. package/dist/src/components/Radio/index.js +231 -0
  58. package/dist/src/components/Row/index.js +43 -0
  59. package/dist/src/components/SelectInput/index.js +662 -0
  60. package/dist/src/components/SelectableCard/index.js +154 -0
  61. package/dist/src/components/Separator/index.js +91 -0
  62. package/dist/src/components/Skeleton/Block.js +53 -0
  63. package/dist/src/components/Skeleton/Blocks.js +52 -0
  64. package/dist/src/components/Skeleton/BoxWithIcon.js +47 -0
  65. package/dist/src/components/Skeleton/Donut.js +58 -0
  66. package/dist/src/components/Skeleton/IconSkeleton.js +37 -0
  67. package/dist/src/components/Skeleton/Line.js +19 -0
  68. package/dist/src/components/Skeleton/List.js +60 -0
  69. package/dist/src/components/Skeleton/Slider.js +57 -0
  70. package/dist/src/components/Skeleton/index.js +85 -0
  71. package/dist/src/components/Snippet/index.js +250 -0
  72. package/dist/src/components/Stack/index.js +24 -0
  73. package/dist/src/components/Status/index.js +101 -0
  74. package/dist/src/components/StepList/index.js +81 -0
  75. package/dist/src/components/Stepper/index.js +217 -0
  76. package/dist/src/components/SwitchButton/FocusOverlay.js +47 -0
  77. package/dist/src/components/SwitchButton/index.js +131 -0
  78. package/dist/src/components/Table/Body.js +12 -0
  79. package/dist/src/components/Table/Cell.js +27 -0
  80. package/dist/src/components/Table/Header.js +21 -0
  81. package/dist/src/components/Table/HeaderCell.js +119 -0
  82. package/dist/src/components/Table/HeaderRow.js +35 -0
  83. package/dist/src/components/Table/Row.js +70 -0
  84. package/dist/src/components/Table/SelectBar.js +52 -0
  85. package/dist/src/components/Table/SkeletonRows.js +52 -0
  86. package/dist/src/components/Table/TableContext.js +91 -0
  87. package/dist/src/components/Table/index.js +84 -0
  88. package/dist/src/components/Tabs/Tab.js +165 -0
  89. package/dist/src/components/Tabs/TabMenu.js +46 -0
  90. package/dist/src/components/Tabs/TabMenuItem.js +40 -0
  91. package/dist/src/components/Tabs/TabsContext.js +6 -0
  92. package/dist/src/components/Tabs/index.js +117 -0
  93. package/dist/src/components/Tag/index.js +177 -0
  94. package/dist/src/components/TagInput/index.js +277 -0
  95. package/dist/src/components/TagList/index.js +110 -0
  96. package/dist/src/components/Text/index.js +106 -0
  97. package/dist/src/components/TextInput/index.js +529 -0
  98. package/dist/src/components/TimeInput/index.js +38 -0
  99. package/dist/src/components/Toaster/index.js +116 -0
  100. package/dist/src/components/Toggle/index.js +192 -0
  101. package/dist/src/components/Tooltip/helpers.js +131 -0
  102. package/dist/src/components/Tooltip/index.js +275 -0
  103. package/dist/src/components/VerificationCode/index.js +203 -0
  104. package/dist/src/helpers/isJSON.js +11 -0
  105. package/dist/src/helpers/legend.js +13 -0
  106. package/dist/src/helpers/recursivelyGetChildrenString.js +12 -0
  107. package/dist/src/index.js +63 -0
  108. package/dist/src/theme/index.js +25 -0
  109. package/dist/src/utils/animations.js +250 -0
  110. package/dist/src/utils/capitalize.js +4 -0
  111. package/dist/src/utils/ids.js +12 -0
  112. package/dist/src/utils/normalize.js +36 -0
  113. package/dist/src/utils/responsive/Breakpoint.js +12 -0
  114. package/dist/src/utils/responsive/utilities.js +12 -0
  115. package/package.json +70 -0
@@ -0,0 +1,192 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { forwardRef, useState, useId, useCallback, useEffect } from 'react';
3
+ import { Icon } from '../Icon/index.js';
4
+ import { Tooltip } from '../Tooltip/index.js';
5
+ import { jsx, jsxs, Fragment } from '@emotion/react/jsx-runtime';
6
+
7
+ function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
8
+ const SIZES = {
9
+ large: {
10
+ ball: 16,
11
+ height: 24,
12
+ width: 48
13
+ },
14
+ small: {
15
+ ball: 12,
16
+ height: 20,
17
+ width: 40
18
+ }
19
+ };
20
+ const StyledToggle = /*#__PURE__*/_styled("div", {
21
+ target: "e1wstm612"
22
+ })("box-sizing:content-box;outline:none;overflow:hidden;display:flex;align-items:center;border:none;border-radius:", _ref => {
23
+ let {
24
+ theme
25
+ } = _ref;
26
+ return theme.radii.xlarge;
27
+ }, ";position:relative;transition:all 300ms;background-color:", _ref2 => {
28
+ let {
29
+ theme
30
+ } = _ref2;
31
+ return theme.colors.neutral.textWeak;
32
+ }, ";width:", _ref3 => {
33
+ let {
34
+ size
35
+ } = _ref3;
36
+ return SIZES[size].width;
37
+ }, "px;height:", _ref4 => {
38
+ let {
39
+ size
40
+ } = _ref4;
41
+ return SIZES[size].height;
42
+ }, "px;&:after{content:'';position:absolute;top:", _ref5 => {
43
+ let {
44
+ size
45
+ } = _ref5;
46
+ return SIZES[size].height / 2 - SIZES[size].ball / 2;
47
+ }, "px;left:5px;width:", _ref6 => {
48
+ let {
49
+ size
50
+ } = _ref6;
51
+ return SIZES[size].ball;
52
+ }, "px;height:", _ref7 => {
53
+ let {
54
+ size
55
+ } = _ref7;
56
+ return SIZES[size].ball;
57
+ }, "px;border-radius:", _ref8 => {
58
+ let {
59
+ theme
60
+ } = _ref8;
61
+ return theme.radii.circle;
62
+ }, ";background-color:", _ref9 => {
63
+ let {
64
+ theme
65
+ } = _ref9;
66
+ return theme.colors.neutral.backgroundWeak;
67
+ }, ";transition:all 300ms;}&:focus-within,&:focus{box-shadow:", _ref10 => {
68
+ let {
69
+ theme
70
+ } = _ref10;
71
+ return theme.shadows.focusPrimary;
72
+ }, ";}&[data-disabled='false']:active:after{width:", _ref11 => {
73
+ let {
74
+ size
75
+ } = _ref11;
76
+ return SIZES[size].ball * 1.3775;
77
+ }, "px;}&[data-checked='true']{color:", _ref12 => {
78
+ let {
79
+ theme
80
+ } = _ref12;
81
+ return theme.colors.neutral.textStrong;
82
+ }, ";background-color:", _ref13 => {
83
+ let {
84
+ theme
85
+ } = _ref13;
86
+ return theme.colors.primary.backgroundStrong;
87
+ }, ";&:after{left:calc(100% - 5px);transform:translateX(-100%);}&:focus-within,&:focus{box-shadow:", _ref14 => {
88
+ let {
89
+ theme
90
+ } = _ref14;
91
+ return theme.shadows.focusPrimary;
92
+ }, ";}}&[data-disabled='true']{background:", _ref15 => {
93
+ let {
94
+ theme
95
+ } = _ref15;
96
+ return theme.colors.neutral.borderWeakDisabled;
97
+ }, ";&[data-checked='true']{background:", _ref16 => {
98
+ let {
99
+ theme
100
+ } = _ref16;
101
+ return theme.colors.primary.backgroundStrongDisabled;
102
+ }, ";}}");
103
+ const StyledCheckbox = /*#__PURE__*/_styled("input", {
104
+ target: "e1wstm611"
105
+ })(process.env.NODE_ENV === "production" ? {
106
+ name: "p9zju0",
107
+ styles: "position:absolute;opacity:0;top:0;left:0;width:100%;height:100%;cursor:pointer;&[disabled]{cursor:not-allowed;}"
108
+ } : {
109
+ name: "p9zju0",
110
+ styles: "position:absolute;opacity:0;top:0;left:0;width:100%;height:100%;cursor:pointer;&[disabled]{cursor:not-allowed;}",
111
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__
112
+ });
113
+ const StyledLabel = /*#__PURE__*/_styled("label", {
114
+ target: "e1wstm610"
115
+ })("display:flex;gap:", _ref17 => {
116
+ let {
117
+ theme
118
+ } = _ref17;
119
+ return theme.space['1'];
120
+ }, ";align-items:center;width:fit-content;cursor:pointer;&:active ", StyledToggle, "[data-disabled='false']:after{width:", _ref18 => {
121
+ let {
122
+ size
123
+ } = _ref18;
124
+ return SIZES[size].ball * 1.3775;
125
+ }, "px;}&[aria-disabled='true']{cursor:not-allowed;color:", _ref19 => {
126
+ let {
127
+ theme
128
+ } = _ref19;
129
+ return theme.colors.neutral.textDisabled;
130
+ }, ";}");
131
+ const RequiredIcon = () => jsx("sup", {
132
+ children: jsx(Icon, {
133
+ name: "asterisk",
134
+ size: 10,
135
+ color: "danger"
136
+ })
137
+ });
138
+ const Toggle = /*#__PURE__*/forwardRef((_ref20, ref) => {
139
+ let {
140
+ checked = false,
141
+ disabled = false,
142
+ id,
143
+ name,
144
+ onChange,
145
+ size = 'large',
146
+ tooltip,
147
+ labelPosition = 'right',
148
+ label,
149
+ required,
150
+ className,
151
+ 'data-testid': dataTestId
152
+ } = _ref20;
153
+ const [state, setState] = useState(checked);
154
+ const uniqueId = useId();
155
+ const onLocalChange = useCallback(event => {
156
+ if (onChange) onChange?.(event);else setState(event.target.checked);
157
+ }, [onChange, setState]);
158
+ useEffect(() => {
159
+ setState(checked);
160
+ }, [checked, setState]);
161
+ return jsx(Tooltip, {
162
+ text: tooltip,
163
+ children: jsxs(StyledLabel, {
164
+ "aria-disabled": disabled,
165
+ size: size,
166
+ onClick: evt => evt.stopPropagation(),
167
+ className: className,
168
+ "data-testid": dataTestId,
169
+ children: [label && labelPosition === 'left' ? jsxs(Fragment, {
170
+ children: [label, required ? jsx(RequiredIcon, {}) : null]
171
+ }) : null, jsx(StyledToggle, {
172
+ size: size,
173
+ "data-checked": state,
174
+ "data-disabled": disabled,
175
+ children: jsx(StyledCheckbox, {
176
+ id: id || uniqueId,
177
+ checked: state,
178
+ "aria-checked": state,
179
+ disabled: disabled,
180
+ name: name,
181
+ onChange: onLocalChange,
182
+ type: "checkbox",
183
+ ref: ref
184
+ })
185
+ }), label && labelPosition === 'right' ? jsxs(Fragment, {
186
+ children: [label, required ? jsx(RequiredIcon, {}) : null]
187
+ }) : null]
188
+ })
189
+ });
190
+ });
191
+
192
+ export { SIZES, Toggle };
@@ -0,0 +1,131 @@
1
+ const ARROW_WIDTH = 8; // in px
2
+ const SPACE = 4; // in px
3
+ const TOTAL_USED_SPACE = ARROW_WIDTH + SPACE; // in px
4
+ const DEFAULT_POSITIONS = {
5
+ arrowLeft: -999,
6
+ arrowTop: -999,
7
+ arrowTransform: 'translate(-50%, -50)',
8
+ placement: 'top',
9
+ rotate: 135,
10
+ tooltipInitialPosition: 'translate3d(-999px, -999px, 0)',
11
+ tooltipPosition: 'translate3d(-999px, -999px, 0)'
12
+ };
13
+ /**
14
+ * This function will find the best placement in a window for tooltip based on children position and tooltip size
15
+ */
16
+ const computePlacement = _ref => {
17
+ let {
18
+ childrenStructuredRef,
19
+ tooltipStructuredRef
20
+ } = _ref;
21
+ const {
22
+ top: childrenX,
23
+ left: childrenY,
24
+ right: childrenRight
25
+ } = childrenStructuredRef;
26
+ const {
27
+ width: tooltipWidth,
28
+ height: tooltipHeight
29
+ } = tooltipStructuredRef;
30
+ if (childrenX - tooltipHeight - TOTAL_USED_SPACE < 0) {
31
+ return 'bottom';
32
+ }
33
+ if (childrenY - tooltipWidth - TOTAL_USED_SPACE < 0) {
34
+ return 'right';
35
+ }
36
+ if (childrenRight + tooltipWidth + TOTAL_USED_SPACE > window.innerWidth) {
37
+ return 'left';
38
+ }
39
+ return 'top';
40
+ };
41
+ /**
42
+ * This function will compute the positions of tooltip and arrow based on children position and tooltip size
43
+ */
44
+ const computePositions = _ref2 => {
45
+ let {
46
+ placement,
47
+ childrenRef,
48
+ tooltipRef
49
+ } = _ref2;
50
+ const childrenStructuredRef = childrenRef.current.getBoundingClientRect();
51
+ const tooltipStructuredRef = tooltipRef.current.getBoundingClientRect();
52
+ const placementBasedOnWindowSize = placement === 'auto' ? computePlacement({
53
+ childrenStructuredRef,
54
+ tooltipStructuredRef
55
+ }) : placement;
56
+ const {
57
+ top: childrenTop,
58
+ left: childrenLeft,
59
+ right: childrenRight,
60
+ width: childrenWidth,
61
+ height: childrenHeight
62
+ } = childrenStructuredRef;
63
+ const {
64
+ width: tooltipWidth,
65
+ height: tooltipHeight
66
+ } = tooltipStructuredRef;
67
+
68
+ // It will get how much scroll is done on the page to compute the position of the tooltip
69
+ const scrollTopValue = document.documentElement.scrollTop;
70
+ switch (placementBasedOnWindowSize) {
71
+ case 'bottom':
72
+ {
73
+ const positionX = childrenLeft + childrenWidth / 2 - tooltipWidth / 2;
74
+ const positionY = childrenTop + scrollTopValue + childrenHeight + ARROW_WIDTH + SPACE;
75
+ return {
76
+ arrowLeft: tooltipWidth / 2,
77
+ arrowTop: -ARROW_WIDTH - 5,
78
+ arrowTransform: '',
79
+ placement: 'bottom',
80
+ rotate: 180,
81
+ tooltipInitialPosition: `translate3d(${positionX}px, ${positionY - TOTAL_USED_SPACE}px, 0)`,
82
+ tooltipPosition: `translate3d(${positionX}px, ${positionY}px, 0)`
83
+ };
84
+ }
85
+ case 'left':
86
+ {
87
+ const positionX = childrenLeft - tooltipWidth - ARROW_WIDTH - SPACE * 2;
88
+ const positionY = childrenTop + scrollTopValue - tooltipHeight / 2 + childrenHeight / 2;
89
+ return {
90
+ arrowLeft: tooltipWidth + ARROW_WIDTH + 5,
91
+ arrowTop: tooltipHeight / 2,
92
+ arrowTransform: 'translate(-50%, -50%)',
93
+ placement: 'left',
94
+ rotate: -90,
95
+ tooltipInitialPosition: `translate3d(${positionX + TOTAL_USED_SPACE}px, ${positionY}px, 0)`,
96
+ tooltipPosition: `translate3d(${positionX}px, ${positionY}px, 0)`
97
+ };
98
+ }
99
+ case 'right':
100
+ {
101
+ const positionX = childrenRight + ARROW_WIDTH + SPACE * 2;
102
+ const positionY = childrenTop + scrollTopValue - tooltipHeight / 2 + childrenHeight / 2;
103
+ return {
104
+ arrowLeft: -ARROW_WIDTH - 5,
105
+ arrowTop: tooltipHeight / 2,
106
+ arrowTransform: 'translate(50%, -50%)',
107
+ placement: 'right',
108
+ rotate: 90,
109
+ tooltipInitialPosition: `translate3d(${positionX - TOTAL_USED_SPACE}px, ${positionY}px, 0)`,
110
+ tooltipPosition: `translate3d(${positionX}px, ${positionY}px, 0)`
111
+ };
112
+ }
113
+ default:
114
+ {
115
+ // top placement is default value
116
+ const positionX = childrenLeft + childrenWidth / 2 - tooltipWidth / 2;
117
+ const positionY = childrenTop + scrollTopValue - tooltipHeight - ARROW_WIDTH - SPACE;
118
+ return {
119
+ arrowLeft: tooltipWidth / 2,
120
+ arrowTop: tooltipHeight - 1,
121
+ arrowTransform: '',
122
+ placement: 'top',
123
+ rotate: 0,
124
+ tooltipInitialPosition: `translate3d(${positionX}px, ${positionY + TOTAL_USED_SPACE}px, 0)`,
125
+ tooltipPosition: `translate3d(${positionX}px, ${positionY}px, 0)`
126
+ };
127
+ }
128
+ }
129
+ };
130
+
131
+ export { ARROW_WIDTH, DEFAULT_POSITIONS, computePositions };
@@ -0,0 +1,275 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { css, keyframes } from '@emotion/react';
3
+ import { forwardRef, useRef, useImperativeHandle, useState, useId, useCallback, useEffect } from 'react';
4
+ import { createPortal } from 'react-dom';
5
+ import { DEFAULT_POSITIONS, computePositions, ARROW_WIDTH } from './helpers.js';
6
+ import { jsx, Fragment, jsxs } from '@emotion/react/jsx-runtime';
7
+
8
+ function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
9
+ const ANIMATION_DURATION = 230; // in ms
10
+
11
+ function noop() {}
12
+ const animation = positions => keyframes`
13
+ 0% {
14
+ opacity: 0;
15
+ transform: ${positions.tooltipInitialPosition};
16
+ }
17
+ 100% {
18
+ opacity: 1;
19
+ transform: ${positions.tooltipPosition};
20
+ }
21
+ `;
22
+ const exitAnimation = positions => keyframes`
23
+ 0% {
24
+ opacity: 1;
25
+ transform: ${positions.tooltipPosition};
26
+ }
27
+ 100% {
28
+ opacity: 0;
29
+ transform: ${positions.tooltipInitialPosition};
30
+ }
31
+ `;
32
+ const StyledTooltip = /*#__PURE__*/_styled("div", {
33
+ target: "e1h4zly11"
34
+ })("background:", _ref => {
35
+ let {
36
+ theme
37
+ } = _ref;
38
+ return theme.colors.neutral.backgroundStronger;
39
+ }, ";color:", _ref2 => {
40
+ let {
41
+ theme
42
+ } = _ref2;
43
+ return theme.colors.neutral.textStronger;
44
+ }, ";border-radius:", _ref3 => {
45
+ let {
46
+ theme
47
+ } = _ref3;
48
+ return theme.radii.default;
49
+ }, ";padding:", _ref4 => {
50
+ let {
51
+ theme
52
+ } = _ref4;
53
+ return `${theme.space['0.5']} ${theme.space['1']}`;
54
+ }, ";text-align:center;position:absolute;max-width:", _ref5 => {
55
+ let {
56
+ maxWidth
57
+ } = _ref5;
58
+ return maxWidth;
59
+ }, "px;font-size:0.8rem;inset:0 auto auto 0;top:0;left:0;transform:", _ref6 => {
60
+ let {
61
+ positions
62
+ } = _ref6;
63
+ return positions.tooltipPosition;
64
+ }, ";animation:", _ref7 => {
65
+ let {
66
+ positions,
67
+ reverseAnimation
68
+ } = _ref7;
69
+ return /*#__PURE__*/css(ANIMATION_DURATION, "ms ", !reverseAnimation ? animation(positions) : exitAnimation(positions), " forwards;");
70
+ }, ";&::after{content:' ';position:absolute;top:", _ref8 => {
71
+ let {
72
+ positions
73
+ } = _ref8;
74
+ return positions.arrowTop;
75
+ }, "px;left:", _ref9 => {
76
+ let {
77
+ positions
78
+ } = _ref9;
79
+ return positions.arrowLeft;
80
+ }, "px;transform:", _ref10 => {
81
+ let {
82
+ positions
83
+ } = _ref10;
84
+ return positions.arrowTransform;
85
+ }, " rotate(", _ref11 => {
86
+ let {
87
+ positions
88
+ } = _ref11;
89
+ return positions.rotate;
90
+ }, "deg);margin-left:-", ARROW_WIDTH, "px;border-width:", ARROW_WIDTH, "px;border-style:solid;border-color:", _ref12 => {
91
+ let {
92
+ theme
93
+ } = _ref12;
94
+ return theme.colors.neutral.backgroundStronger;
95
+ }, " transparent transparent transparent;pointer-events:none;}");
96
+ const StyledChildrenContainer = /*#__PURE__*/_styled("div", {
97
+ target: "e1h4zly10"
98
+ })(process.env.NODE_ENV === "production" ? {
99
+ name: "ck88l6",
100
+ styles: "display:inherit"
101
+ } : {
102
+ name: "ck88l6",
103
+ styles: "display:inherit",
104
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__
105
+ });
106
+ const Tooltip = /*#__PURE__*/forwardRef((_ref13, tooltipRef) => {
107
+ let {
108
+ children,
109
+ text = '',
110
+ placement = 'auto',
111
+ id,
112
+ className,
113
+ maxWidth = 232,
114
+ visible,
115
+ innerRef,
116
+ role = 'tooltip',
117
+ 'data-testid': dataTestId
118
+ } = _ref13;
119
+ const childrenRef = useRef(null);
120
+ useImperativeHandle(innerRef, () => childrenRef.current);
121
+ const tempTooltipRef = useRef(null);
122
+ const innerTooltipRef = tooltipRef || tempTooltipRef;
123
+ const timer = useRef();
124
+
125
+ // Debounce timer will be used to prevent the tooltip from flickering when the user moves the mouse out and in the children element.
126
+ const debounceTimer = useRef();
127
+ const [visibleInDom, setVisibleInDom] = useState(false);
128
+ const [reverseAnimation, setReverseAnimation] = useState(false);
129
+ const [positions, setPositions] = useState({
130
+ ...DEFAULT_POSITIONS
131
+ });
132
+ const uniqueId = useId();
133
+ const generatedId = id ?? uniqueId;
134
+ const isControlled = visible !== undefined;
135
+ const generatePositions = useCallback(() => {
136
+ if (childrenRef.current && innerTooltipRef.current) {
137
+ setPositions(computePositions({
138
+ childrenRef,
139
+ placement,
140
+ tooltipRef: innerTooltipRef
141
+ }));
142
+ }
143
+ }, [innerTooltipRef, placement]);
144
+ const onScrollDetected = useCallback(() => {
145
+ // We remove animation on scroll or the animation will restart on every scroll
146
+ if (innerTooltipRef.current) {
147
+ innerTooltipRef.current.style.animation = 'none';
148
+ }
149
+ generatePositions();
150
+ }, [generatePositions, innerTooltipRef]);
151
+
152
+ /**
153
+ * This function is called when we need to remove tooltip portal from DOM and remove event listener to it.
154
+ */
155
+ const unmountTooltip = useCallback(() => {
156
+ setVisibleInDom(false);
157
+ setReverseAnimation(false);
158
+ window.removeEventListener('scroll', onScrollDetected, true);
159
+ }, [onScrollDetected]);
160
+
161
+ /**
162
+ * When mouse hover or stop hovering children this function display or hide tooltip. A timeout is set to allow animation
163
+ * end, then remove tooltip from dom.
164
+ */
165
+ const onPointerEvent = useCallback(isVisible => () => {
166
+ // This condition is for when we want to unmount the tooltip
167
+ // There is debounce in order to avoid tooltip to flicker when we move the mouse from children to tooltip
168
+ // Timer is used to follow the animation duration
169
+ if (!isVisible && innerTooltipRef.current && !debounceTimer.current) {
170
+ debounceTimer.current = setTimeout(() => {
171
+ setReverseAnimation(true);
172
+ timer.current = setTimeout(() => unmountTooltip(), ANIMATION_DURATION);
173
+ }, 200);
174
+ } else if (isVisible) {
175
+ // This condition is for when we want to mount the tooltip
176
+ // If the timer exists it means the tooltip was about to umount, but we hovered the children again,
177
+ // so we clear the timer and the tooltip will not be unmounted
178
+ if (timer.current) {
179
+ setReverseAnimation(false);
180
+ clearTimeout(timer.current);
181
+ timer.current = undefined;
182
+ }
183
+ // And here is when we currently are in a debounce timer, it means tooltip was hovered during
184
+ // that period, and so we can clear debounce timer
185
+ if (debounceTimer.current) {
186
+ clearTimeout(debounceTimer.current);
187
+ debounceTimer.current = undefined;
188
+ }
189
+ setVisibleInDom(true);
190
+ }
191
+ }, [innerTooltipRef, unmountTooltip]);
192
+
193
+ /**
194
+ * Once tooltip is visible in the dom we can compute positions, then set it visible on screen and add event to
195
+ * recompute positions on scroll or screen resize.
196
+ */
197
+ useEffect(() => {
198
+ if (visibleInDom) {
199
+ generatePositions();
200
+
201
+ // We want to detect scroll in order to recompute positions of tooltip
202
+ // Adding true as third parameter to event listener will detect nested scrolls.
203
+ window.addEventListener('scroll', onScrollDetected, true);
204
+ }
205
+ return () => {
206
+ window.removeEventListener('scroll', onScrollDetected, true);
207
+ if (timer.current) {
208
+ clearTimeout(timer.current);
209
+ timer.current = undefined;
210
+ }
211
+ };
212
+ }, [generatePositions, onScrollDetected, visibleInDom]);
213
+
214
+ /**
215
+ * If tooltip has `visible` prop it means the tooltip is manually controlled through this prop.
216
+ * In this cas we don't want to display tooltip on hover, but only when `visible` is true.
217
+ */
218
+ useEffect(() => {
219
+ if (isControlled) {
220
+ onPointerEvent(visible)();
221
+ }
222
+ }, [isControlled, onPointerEvent, visible]);
223
+ const onKeyDown = useCallback(event => {
224
+ if (event.code === 'Escape') {
225
+ unmountTooltip();
226
+ }
227
+ }, [unmountTooltip]);
228
+
229
+ /**
230
+ * Will render children conditionally if children is a function or not.
231
+ */
232
+ const renderChildren = useCallback(() => {
233
+ if (typeof children === 'function') {
234
+ return children({
235
+ onBlur: !isControlled ? onPointerEvent(false) : noop,
236
+ onFocus: !isControlled ? onPointerEvent(true) : noop,
237
+ onPointerEnter: !isControlled ? onPointerEvent(true) : noop,
238
+ onPointerLeave: !isControlled ? onPointerEvent(false) : noop,
239
+ ref: childrenRef
240
+ });
241
+ }
242
+ return jsx(StyledChildrenContainer, {
243
+ "aria-describedby": generatedId,
244
+ onBlur: !isControlled ? onPointerEvent(false) : noop,
245
+ onFocus: !isControlled ? onPointerEvent(true) : noop,
246
+ onPointerEnter: !isControlled ? onPointerEvent(true) : noop,
247
+ onPointerLeave: !isControlled ? onPointerEvent(false) : noop,
248
+ ref: childrenRef,
249
+ tabIndex: 0,
250
+ onKeyDown: onKeyDown,
251
+ children: children
252
+ });
253
+ }, [children, generatedId, isControlled, onKeyDown, onPointerEvent]);
254
+ if (!text) {
255
+ if (typeof children === 'function') return null;
256
+ return jsx(Fragment, {
257
+ children: children
258
+ });
259
+ }
260
+ return jsxs(Fragment, {
261
+ children: [renderChildren(), visibleInDom ? /*#__PURE__*/createPortal(jsx(StyledTooltip, {
262
+ ref: innerTooltipRef,
263
+ positions: positions,
264
+ maxWidth: maxWidth,
265
+ role: role,
266
+ id: generatedId,
267
+ className: className,
268
+ reverseAnimation: reverseAnimation,
269
+ "data-testid": dataTestId,
270
+ children: text
271
+ }), document.body) : null]
272
+ });
273
+ });
274
+
275
+ export { Tooltip };