@ilo-org/react 0.9.1 → 0.10.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 (81) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/lib/cjs/components/Checkbox/Checkbox.js +1 -1
  3. package/lib/cjs/components/Checkbox/index.js +1 -1
  4. package/lib/cjs/components/DatePicker/DatePicker.js +1 -1
  5. package/lib/cjs/components/DatePicker/index.js +1 -1
  6. package/lib/cjs/components/Dropdown/Dropdown.js +1 -1
  7. package/lib/cjs/components/Dropdown/index.js +1 -1
  8. package/lib/cjs/components/Fieldset/Fieldset.js +1 -1
  9. package/lib/cjs/components/Fieldset/index.js +1 -1
  10. package/lib/cjs/components/FileUpload/FileUpload.js +1 -1
  11. package/lib/cjs/components/FileUpload/index.js +1 -1
  12. package/lib/cjs/components/FormControl/FormControl.js +1 -1
  13. package/lib/cjs/components/FormControl/index.js +1 -1
  14. package/lib/cjs/components/Hero/Hero.js +1 -1
  15. package/lib/cjs/components/Hero/index.js +1 -1
  16. package/lib/cjs/components/Input/Input.js +1 -1
  17. package/lib/cjs/components/Input/index.js +1 -1
  18. package/lib/cjs/components/Navigation/Navigation.js +1 -1
  19. package/lib/cjs/components/Navigation/index.js +1 -1
  20. package/lib/cjs/components/NumberPicker/NumberPicker.js +1 -1
  21. package/lib/cjs/components/NumberPicker/index.js +1 -1
  22. package/lib/cjs/components/Profile/Profile.js +4 -2
  23. package/lib/cjs/components/Radio/Radio.js +1 -1
  24. package/lib/cjs/components/Radio/index.js +1 -1
  25. package/lib/cjs/components/SearchField/SearchField.js +1 -1
  26. package/lib/cjs/components/SearchField/index.js +1 -1
  27. package/lib/cjs/components/TextInput/TextInput.js +1 -1
  28. package/lib/cjs/components/TextInput/index.js +1 -1
  29. package/lib/cjs/components/Textarea/Textarea.js +1 -1
  30. package/lib/cjs/components/Textarea/index.js +1 -1
  31. package/lib/cjs/components/Toggle/Toggle.js +1 -1
  32. package/lib/cjs/components/Toggle/index.js +1 -1
  33. package/lib/cjs/components/Tooltip/Tooltip.js +42 -72
  34. package/lib/cjs/components/Tooltip/index.js +1 -1
  35. package/lib/cjs/components/index.js +1 -0
  36. package/lib/cjs/index.js +1 -0
  37. package/lib/esm/components/Checkbox/Checkbox.js +1 -1
  38. package/lib/esm/components/Checkbox/index.js +1 -1
  39. package/lib/esm/components/DatePicker/DatePicker.js +1 -1
  40. package/lib/esm/components/DatePicker/index.js +1 -1
  41. package/lib/esm/components/Dropdown/Dropdown.js +1 -1
  42. package/lib/esm/components/Dropdown/index.js +1 -1
  43. package/lib/esm/components/Fieldset/Fieldset.js +1 -1
  44. package/lib/esm/components/Fieldset/index.js +1 -1
  45. package/lib/esm/components/FileUpload/FileUpload.js +1 -1
  46. package/lib/esm/components/FileUpload/index.js +1 -1
  47. package/lib/esm/components/FormControl/FormControl.js +1 -1
  48. package/lib/esm/components/FormControl/index.js +1 -1
  49. package/lib/esm/components/Hero/Hero.js +1 -1
  50. package/lib/esm/components/Hero/index.js +1 -1
  51. package/lib/esm/components/Input/Input.js +1 -1
  52. package/lib/esm/components/Input/index.js +1 -1
  53. package/lib/esm/components/Navigation/Navigation.js +1 -1
  54. package/lib/esm/components/Navigation/index.js +1 -1
  55. package/lib/esm/components/NumberPicker/NumberPicker.js +1 -1
  56. package/lib/esm/components/NumberPicker/index.js +1 -1
  57. package/lib/esm/components/Profile/Profile.js +4 -2
  58. package/lib/esm/components/Radio/Radio.js +1 -1
  59. package/lib/esm/components/Radio/index.js +1 -1
  60. package/lib/esm/components/SearchField/SearchField.js +1 -1
  61. package/lib/esm/components/SearchField/index.js +1 -1
  62. package/lib/esm/components/TextInput/TextInput.js +1 -1
  63. package/lib/esm/components/TextInput/index.js +1 -1
  64. package/lib/esm/components/Textarea/Textarea.js +1 -1
  65. package/lib/esm/components/Textarea/index.js +1 -1
  66. package/lib/esm/components/Toggle/Toggle.js +1 -1
  67. package/lib/esm/components/Toggle/index.js +1 -1
  68. package/lib/esm/components/Tooltip/Tooltip.js +42 -72
  69. package/lib/esm/components/Tooltip/index.js +1 -1
  70. package/lib/esm/components/index.js +1 -0
  71. package/lib/esm/index.js +1 -0
  72. package/lib/types/react/src/components/Profile/Profile.props.d.ts +9 -0
  73. package/lib/types/react/src/components/Tooltip/Tooltip.props.d.ts +3 -11
  74. package/lib/types/react/src/types/index.d.ts +1 -0
  75. package/package.json +16 -16
  76. package/src/components/Profile/Profile.props.ts +12 -0
  77. package/src/components/Profile/Profile.tsx +19 -11
  78. package/src/components/Tooltip/Tooltip.args.ts +1 -1
  79. package/src/components/Tooltip/Tooltip.props.ts +3 -13
  80. package/src/components/Tooltip/Tooltip.tsx +68 -91
  81. package/src/types/index.ts +1 -0
@@ -1,138 +1,115 @@
1
- import { FC, useState, useRef } from "react";
1
+ import React, { FC, useState, useRef } from "react";
2
2
  import classNames from "classnames";
3
3
  import useGlobalSettings from "../../hooks/useGlobalSettings";
4
4
  import { TooltipProps } from "./Tooltip.props";
5
- import ReactDOM from "react-dom";
5
+ import { createPopper, Instance as PopperInstance } from "@popperjs/core";
6
6
 
7
7
  const Tooltip: FC<TooltipProps> = ({
8
8
  className,
9
9
  children,
10
10
  icon,
11
11
  label,
12
+ iconTheme,
12
13
  theme,
13
14
  id,
14
15
  }) => {
15
16
  const { prefix } = useGlobalSettings();
16
17
  const baseClass = `${prefix}--tooltip`;
17
18
  const [isVisible, setIsVisible] = useState<boolean>(false);
18
- const [position, setPosition] = useState<{ x: number; y: number }>({
19
- x: 0,
20
- y: 0,
21
- });
22
- const [arrowPlacement, setArrowPlacement] = useState<string>("center");
23
- const [arrowAlignment, setArrowAlignment] = useState<string>("left");
24
-
25
- const tooltipRef = useRef(null);
19
+ const tooltipRef = useRef<HTMLDivElement>(null);
20
+ const popperInstanceRef = useRef<PopperInstance | null>(null);
21
+
22
+ const isLongTooltip = () => {
23
+ const tooltipText = (
24
+ tooltipRef.current?.textContent ||
25
+ tooltipRef.current?.innerText ||
26
+ ""
27
+ ).trim();
28
+ return tooltipText.length > 50;
29
+ };
26
30
 
27
31
  const tooltipClasses = classNames(className, {
28
32
  [baseClass]: true,
29
33
  [`${baseClass}--${theme}`]: theme,
30
- [`${baseClass}--alignment-${arrowAlignment}`]: arrowAlignment,
31
34
  [`${baseClass}--visible`]: isVisible,
35
+ [`${baseClass}--long`]: isLongTooltip(),
32
36
  });
33
37
 
34
- const tooltipArrowClasses = classNames(className, {
35
- [`${baseClass}--arrow`]: true,
36
- [`${baseClass}--arrow--placement-${arrowPlacement}`]: arrowPlacement,
38
+ const tooltipArrowClasses = classNames(
39
+ `${baseClass}--arrow`,
40
+ `${baseClass}--arrow--placement-negative`
41
+ );
42
+
43
+ const iconClasses = classNames(className, `${baseClass}--wrapper`, {
44
+ [`${baseClass}--wrapper__icon ${baseClass}--wrapper__icon__theme__${theme}`]:
45
+ icon,
46
+ [`${baseClass}--wrapper__icon__theme__${theme}`]: iconTheme,
37
47
  });
38
48
 
39
- const handleOnMouseOver: React.MouseEventHandler<HTMLDivElement> &
40
- React.FocusEventHandler<HTMLDivElement> = (e) => {
41
- // get hovered element reference
49
+ const handleOnMouseOver: React.MouseEventHandler<HTMLDivElement> = (e) => {
42
50
  const target = e.currentTarget;
51
+ if (target && tooltipRef.current) {
52
+ const popperInstance = createPopper(target, tooltipRef.current, {
53
+ placement: "top",
54
+ modifiers: [
55
+ {
56
+ name: "offset",
57
+ options: {
58
+ offset: [0, 12], // Adjust offset as needed
59
+ },
60
+ },
61
+ {
62
+ name: "flip",
63
+ enabled: true,
64
+ },
65
+ {
66
+ name: "preventOverflow",
67
+ enabled: true,
68
+ },
69
+ ],
70
+ });
71
+
72
+ popperInstanceRef.current = popperInstance;
43
73
 
44
- if (target) {
45
- const rect = target.getBoundingClientRect();
46
74
  setIsVisible(true);
47
- postMouseOver(rect);
48
- }
49
- };
50
-
51
- const postMouseOver = (hoverRect: any) => {
52
- // position the tooltip after showing it
53
- let placement = "center";
54
- let alignment = "left";
55
-
56
- const ttNode = ReactDOM.findDOMNode(tooltipRef.current) as Element;
57
- if (ttNode != null) {
58
- let x = 0,
59
- y = 0;
60
-
61
- const docWidth = document.documentElement.clientWidth,
62
- docHeight = document.documentElement.clientHeight;
63
-
64
- const rx = hoverRect.x + hoverRect.width, // most right x
65
- lx = hoverRect.x, // most left x
66
- ty = hoverRect.y, // most top y
67
- by = hoverRect.y + hoverRect.height; // most bottom y
68
-
69
- // tool tip rectange
70
- const ttRect = ttNode.getBoundingClientRect();
71
-
72
- const bRight =
73
- rx + ttRect.width <= window.scrollX + docWidth &&
74
- ty + ttRect.height <= window.scrollY + docHeight;
75
- const bLeft =
76
- lx - ttRect.width >= 0 &&
77
- ty + ttRect.height <= window.scrollY + docHeight;
78
- const bAbove = ty - ttRect.height >= 0;
79
- const bBellow = by + ttRect.height <= window.scrollY + docHeight;
80
-
81
- // the tooltip doesn't fit to the left
82
- if (bRight) {
83
- x = hoverRect.width + 16;
84
- y = icon ? -8 : 0;
85
- placement = "negative";
86
- alignment = "right";
87
- } else if (bBellow) {
88
- x = icon ? -8 : 0;
89
- y = hoverRect.height + 16;
90
-
91
- placement = "center";
92
- alignment = "bottom";
93
- } else if (bLeft) {
94
- x = -ttRect.width - 16;
95
- y = icon ? -8 : 0;
96
-
97
- placement = "negative";
98
- alignment = "left";
99
- } else if (bAbove) {
100
- x = icon ? -8 : 0;
101
- y = -ttRect.height - 16;
102
-
103
- placement = "center";
104
- alignment = "top";
105
- }
106
-
107
- setPosition({ x: x, y: y });
108
- setArrowPlacement(placement);
109
- setArrowAlignment(alignment);
110
75
  }
111
76
  };
112
77
 
113
78
  const handleOnMouseOut = () => {
79
+ if (popperInstanceRef.current) {
80
+ popperInstanceRef.current.destroy();
81
+ }
114
82
  setIsVisible(false);
115
83
  };
116
84
 
117
- const style = {
118
- // left: ((position.x + window.scrollX) + 'px'),
119
- // top: ((position.y + window.scrollY) + 'px')
120
- left: position.x + "px",
121
- top: position.y + "px",
85
+ const handleOnFocus: React.FocusEventHandler<HTMLDivElement> = (e) => {
86
+ handleOnMouseOver(e as unknown as React.MouseEvent<HTMLDivElement>);
122
87
  };
123
88
 
124
89
  return (
125
90
  <div
126
- className={`${baseClass}--wrapper ${icon && "has-icon"}`}
91
+ className={iconClasses}
127
92
  onMouseOver={handleOnMouseOver}
128
- onFocus={handleOnMouseOver}
93
+ onFocus={handleOnFocus}
129
94
  onMouseOut={handleOnMouseOut}
130
95
  onBlur={handleOnMouseOut}
131
96
  id={id}
132
97
  >
133
98
  {!icon && <>{children}</>}
134
- <span className={tooltipClasses} style={style} ref={tooltipRef}>
135
- <span className={tooltipArrowClasses} role="presentation"></span>
99
+ <span
100
+ className={tooltipClasses}
101
+ ref={tooltipRef}
102
+ data-id={id}
103
+ id="tooltip"
104
+ role="tooltip"
105
+ aria-hidden={!isVisible}
106
+ >
107
+ <span
108
+ data-popper-arrow
109
+ className={tooltipArrowClasses}
110
+ data-placement="negative"
111
+ role="presentation"
112
+ />
136
113
  {label}
137
114
  </span>
138
115
  </div>
@@ -32,6 +32,7 @@ export type LabelTypes = "default" | "actionable" | "light";
32
32
  export type LinkTypes = "light" | "dark" | "footer" | "button";
33
33
  export type LinkListThemes = "light" | "dark";
34
34
  export type TooltipThemes = "light" | "dark";
35
+ export type TooltipIconThemes = "light" | "dark";
35
36
  export type TooltipAlignment = "top" | "right" | "bottom" | "left";
36
37
  export type TooltipPlacement = "negative" | "center" | "positive";
37
38
  export type ListAlignment = "default" | "horizontal";