@udixio/ui-react 2.9.7 → 2.9.9

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 (38) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/index.cjs +3 -3
  3. package/dist/index.js +2158 -2042
  4. package/dist/lib/components/Tooltip.d.ts +9 -0
  5. package/dist/lib/components/Tooltip.d.ts.map +1 -0
  6. package/dist/lib/components/index.d.ts +1 -1
  7. package/dist/lib/effects/State.d.ts.map +1 -1
  8. package/dist/lib/hooks/index.d.ts +5 -0
  9. package/dist/lib/hooks/index.d.ts.map +1 -0
  10. package/dist/lib/hooks/useTooltipPosition.d.ts +22 -0
  11. package/dist/lib/hooks/useTooltipPosition.d.ts.map +1 -0
  12. package/dist/lib/hooks/useTooltipTrigger.d.ts +44 -0
  13. package/dist/lib/hooks/useTooltipTrigger.d.ts.map +1 -0
  14. package/dist/lib/index.d.ts +1 -0
  15. package/dist/lib/index.d.ts.map +1 -1
  16. package/dist/lib/interfaces/tooltip.interface.d.ts +24 -2
  17. package/dist/lib/interfaces/tooltip.interface.d.ts.map +1 -1
  18. package/dist/lib/styles/card.style.d.ts.map +1 -1
  19. package/dist/lib/styles/tooltip.style.d.ts +32 -4
  20. package/dist/lib/styles/tooltip.style.d.ts.map +1 -1
  21. package/package.json +3 -3
  22. package/src/lib/components/Fab.tsx +2 -2
  23. package/src/lib/components/IconButton.tsx +3 -3
  24. package/src/lib/components/Tooltip.tsx +172 -0
  25. package/src/lib/components/index.ts +1 -1
  26. package/src/lib/effects/State.tsx +6 -2
  27. package/src/lib/hooks/index.ts +11 -0
  28. package/src/lib/hooks/useTooltipPosition.ts +95 -0
  29. package/src/lib/hooks/useTooltipTrigger.ts +270 -0
  30. package/src/lib/index.ts +1 -0
  31. package/src/lib/interfaces/tooltip.interface.ts +24 -2
  32. package/src/lib/styles/card.style.ts +4 -1
  33. package/src/lib/styles/tooltip.style.ts +1 -0
  34. package/src/stories/communication/tool-tip.stories.tsx +19 -19
  35. package/tsconfig.json +0 -6
  36. package/dist/lib/components/ToolTip.d.ts +0 -9
  37. package/dist/lib/components/ToolTip.d.ts.map +0 -1
  38. package/src/lib/components/ToolTip.tsx +0 -256
@@ -1,256 +0,0 @@
1
- import {
2
- cloneElement,
3
- isValidElement,
4
- useEffect,
5
- useRef,
6
- useState,
7
- } from 'react';
8
- import { MotionProps } from '../utils';
9
- import { Button } from './Button';
10
- import { ToolTipInterface } from '../interfaces';
11
- import { useToolTipStyle } from '../styles';
12
- import { v4 } from 'uuid';
13
- import { AnimatePresence, motion } from 'motion/react';
14
- import { SyncedFixedWrapper } from '../effects';
15
-
16
- /**
17
- * Tooltips display brief labels or messages
18
- * @status beta
19
- * @category Communication
20
- */
21
- export const ToolTip = ({
22
- variant = 'plain',
23
- buttons,
24
- className,
25
- children,
26
- title,
27
- text,
28
- position,
29
- targetRef,
30
- ref,
31
- trigger = ['hover', 'focus'],
32
- transition,
33
- ...props
34
- }: MotionProps<ToolTipInterface>) => {
35
- transition = { duration: 0.3, delay: 0.4, ...transition };
36
-
37
- if (!children && !targetRef) {
38
- throw new Error('ToolTip must have a child or a targetRef');
39
- }
40
- if (!Array.isArray(trigger)) {
41
- trigger = [trigger];
42
- }
43
-
44
- if (buttons && !Array.isArray(buttons)) {
45
- buttons = [buttons];
46
- }
47
-
48
- const internalRef = useRef<HTMLElement | null>(null); // Ref interne au cas où targetRef est undefined
49
- const resolvedRef = targetRef || internalRef; // Utilise targetRef si défini, sinon internalRef
50
-
51
- const [currentToolTipId, setCurrentToolTipId] = useState<string | null>(null);
52
- const [id] = useState(v4());
53
- const [isVisible, setIsVisible] = useState(false);
54
-
55
- const timeout = useRef<ReturnType<typeof setTimeout> | null>(null);
56
- const showTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);
57
-
58
- useEffect(() => {
59
- const handleUpdate = (event: CustomEvent) => {
60
- setCurrentToolTipId(event.detail);
61
- };
62
-
63
- document.addEventListener('tooltip-update', handleUpdate as EventListener);
64
- return () => {
65
- document.removeEventListener(
66
- 'tooltip-update',
67
- handleUpdate as EventListener,
68
- );
69
- };
70
- }, []);
71
-
72
- useEffect(() => {
73
- if (timeout.current) clearTimeout(timeout.current);
74
- if (showTimeout.current) clearTimeout(showTimeout.current);
75
-
76
- if (currentToolTipId) {
77
- if (currentToolTipId === id) {
78
- showTimeout.current = setTimeout(
79
- () => {
80
- setIsVisible(true);
81
- },
82
- (transition?.delay ?? 0) * 1000,
83
- );
84
- } else {
85
- setIsVisible(false);
86
- }
87
- } else {
88
- timeout.current = setTimeout(() => {
89
- setIsVisible(false);
90
- }, 1200);
91
- }
92
- }, [currentToolTipId, id]);
93
-
94
- // Ajouter des gestionnaires sur l'élément cible (targetRef ou internalRef)
95
-
96
- const handleMouseEnter = () => {
97
- if (trigger.includes('hover')) {
98
- const event = new CustomEvent('tooltip-update', { detail: id });
99
- document.dispatchEvent(event);
100
- }
101
- };
102
-
103
- const handleMouseLeave = () => {
104
- if (trigger.includes('hover')) {
105
- const event = new CustomEvent('tooltip-update', { detail: null });
106
- document.dispatchEvent(event);
107
- }
108
- };
109
-
110
- const handleClick = () => {
111
- if (trigger.includes('click')) {
112
- const event = new CustomEvent('tooltip-update', {
113
- detail: isVisible ? null : id,
114
- });
115
- document.dispatchEvent(event);
116
- }
117
- };
118
-
119
- const handleFocus = () => {
120
- if (trigger.includes('focus')) {
121
- const event = new CustomEvent('tooltip-update', { detail: id });
122
- document.dispatchEvent(event);
123
- }
124
- };
125
-
126
- const handleBlur = () => {
127
- if (trigger.includes('focus')) {
128
- const event = new CustomEvent('tooltip-update', { detail: null });
129
- document.dispatchEvent(event);
130
- }
131
- };
132
-
133
- useEffect(() => {
134
- if (resolvedRef?.current) {
135
- const targetElement = resolvedRef.current;
136
-
137
- targetElement.addEventListener('mouseenter', handleMouseEnter);
138
- targetElement.addEventListener('mouseleave', handleMouseLeave);
139
- targetElement.addEventListener('click', handleClick);
140
- targetElement.addEventListener('focus', handleFocus);
141
- targetElement.addEventListener('blur', handleBlur);
142
-
143
- // Nettoyage au démontage
144
- return () => {
145
- targetElement.removeEventListener('mouseenter', handleMouseEnter);
146
- targetElement.removeEventListener('mouseleave', handleMouseLeave);
147
- targetElement.removeEventListener('click', handleClick);
148
- targetElement.removeEventListener('focus', handleFocus);
149
- targetElement.removeEventListener('blur', handleBlur);
150
- };
151
- }
152
- return;
153
- }, [resolvedRef, trigger, id, isVisible]);
154
-
155
- // Si targetRef est undefined, on applique la réf au premier enfant
156
- const enhancedChildren =
157
- !targetRef && isValidElement(children)
158
- ? cloneElement(children, { ref: internalRef } as any)
159
- : children;
160
-
161
- if (!position && typeof window !== 'undefined') {
162
- if (resolvedRef?.current && !position) {
163
- const rect = resolvedRef.current.getBoundingClientRect();
164
-
165
- const viewportWidth = window.innerWidth;
166
- const viewportHeight = window.innerHeight;
167
-
168
- const x = rect.left / viewportWidth; // X entre 0 et 1
169
- const y = rect.top / viewportHeight; // Y entre 0 et 1
170
-
171
- if (variant === 'plain') {
172
- if (x < 1 / 3) {
173
- position = 'right';
174
- } else if (x > 2 / 3) {
175
- position = 'left';
176
- } else {
177
- position = y > 0.5 ? 'top' : 'bottom';
178
- }
179
- } else {
180
- if (x < 1 / 2 && y < 1 / 2) {
181
- position = 'bottom-right';
182
- } else if (x > 1 / 2 && y < 1 / 2) {
183
- position = 'bottom-left';
184
- } else if (x > 1 / 2 && y > 1 / 2) {
185
- position = 'top-left';
186
- } else if (x < 1 / 2 && y > 1 / 2) {
187
- position = 'top-right';
188
- }
189
- }
190
- }
191
- }
192
-
193
- const styles = useToolTipStyle({
194
- variant,
195
- buttons,
196
- className,
197
- title,
198
- text,
199
- position,
200
- trigger,
201
- targetRef: targetRef as any,
202
- children: children as any,
203
- });
204
-
205
- const variants = {
206
- open: {
207
- opacity: 1,
208
- height: 'auto',
209
- },
210
- close: {
211
- opacity: 0,
212
- height: 16,
213
- },
214
- };
215
-
216
- return (
217
- <>
218
- {enhancedChildren}
219
- <AnimatePresence>
220
- {isVisible && (
221
- <SyncedFixedWrapper targetRef={resolvedRef}>
222
- <motion.div
223
- initial={'close'}
224
- variants={variants}
225
- animate={'open'}
226
- transition={{ duration: transition.duration }}
227
- exit={'close'}
228
- className={styles.toolTip}
229
- {...props}
230
- onMouseEnter={handleMouseEnter}
231
- onMouseLeave={handleMouseLeave}
232
- >
233
- <div className={styles.container}>
234
- {title && <div className={styles.subHead}>{title}</div>}
235
- <div className={styles.supportingText}>{text}</div>
236
- {buttons && (
237
- <div className={styles.actions}>
238
- {Array.isArray(buttons) &&
239
- buttons.map((buttonArgs, index) => (
240
- <Button
241
- key={index}
242
- size={'small'}
243
- variant={'text'}
244
- {...buttonArgs}
245
- />
246
- ))}
247
- </div>
248
- )}
249
- </div>
250
- </motion.div>
251
- </SyncedFixedWrapper>
252
- )}
253
- </AnimatePresence>
254
- </>
255
- );
256
- };