@telefonica/mistica 17.5.0 → 17.7.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.
- package/css/mistica.css +1 -1
- package/dist/accordion.css-mistica.js +6 -6
- package/dist/align.css-mistica.js +1 -1
- package/dist/autocomplete.css-mistica.js +1 -1
- package/dist/avatar.css-mistica.js +1 -1
- package/dist/badge.css-mistica.js +1 -1
- package/dist/box.css-mistica.js +13 -13
- package/dist/boxed.css-mistica.js +24 -24
- package/dist/button-group.css-mistica.js +1 -1
- package/dist/button-layout.css-mistica.js +14 -14
- package/dist/button.css-mistica.js +34 -34
- package/dist/callout.css-mistica.js +11 -11
- package/dist/card-cover.d.ts +2 -2
- package/dist/card-data.d.ts +2 -2
- package/dist/card-data.js +6 -8
- package/dist/card-internal.css-mistica.js +47 -29
- package/dist/card-internal.css.d.ts +4 -0
- package/dist/card-internal.d.ts +38 -3
- package/dist/card-internal.js +394 -301
- package/dist/card-media.d.ts +2 -2
- package/dist/card-media.js +7 -9
- package/dist/card-naked.d.ts +2 -2
- package/dist/card-naked.js +9 -11
- package/dist/carousel.css-mistica.js +8 -8
- package/dist/checkbox.css-mistica.js +11 -11
- package/dist/checkbox.d.ts +2 -0
- package/dist/checkbox.js +10 -10
- package/dist/chip.css-mistica.js +15 -15
- package/dist/circle.css-mistica.js +1 -1
- package/dist/community/advanced-data-card.css-mistica.js +20 -11
- package/dist/community/advanced-data-card.css.d.ts +2 -0
- package/dist/community/advanced-data-card.d.ts +7 -3
- package/dist/community/advanced-data-card.js +164 -142
- package/dist/community/ai-card.css-mistica.js +13 -13
- package/dist/community/ai-card.js +1 -1
- package/dist/community/blocks.css-mistica.js +1 -1
- package/dist/community/cyber/example-component.css-mistica.js +1 -1
- package/dist/community/example-component.css-mistica.js +2 -2
- package/dist/counter.css-mistica.js +1 -1
- package/dist/cover-hero.css-mistica.js +2 -2
- package/dist/credit-card-number-field.css-mistica.js +3 -3
- package/dist/date-field.css-mistica.js +1 -1
- package/dist/date-time-picker.css-mistica.js +1 -1
- package/dist/dialog.css-mistica.js +4 -4
- package/dist/divider.css-mistica.js +5 -5
- package/dist/double-field.css-mistica.js +2 -2
- package/dist/drawer.css-mistica.js +1 -1
- package/dist/empty-state-card.css-mistica.js +1 -1
- package/dist/empty-state.css-mistica.js +5 -5
- package/dist/fade-in.css-mistica.js +1 -1
- package/dist/fade-out.css-mistica.js +1 -1
- package/dist/feedback.css-mistica.js +1 -1
- package/dist/file-upload.css-mistica.js +7 -7
- package/dist/fixed-footer-layout.css-mistica.js +2 -2
- package/dist/form.css-mistica.js +1 -1
- package/dist/generated/mistica-icons/icon-document-information-filled.js +165 -0
- package/dist/generated/mistica-icons/icon-document-information-light.js +165 -0
- package/dist/generated/mistica-icons/icon-document-information-regular.js +165 -0
- package/dist/generated/mistica-icons/icon-internet-roaming-filled.js +159 -0
- package/dist/generated/mistica-icons/icon-internet-roaming-light.js +159 -0
- package/dist/generated/mistica-icons/icon-internet-roaming-regular.js +159 -0
- package/dist/generated/mistica-icons/icon-mobile-information-filled.js +165 -0
- package/dist/generated/mistica-icons/icon-mobile-information-light.js +173 -0
- package/dist/generated/mistica-icons/icon-mobile-information-regular.js +165 -0
- package/dist/generated/mistica-icons/icon-search-ai-filled.js +165 -0
- package/dist/generated/mistica-icons/icon-search-ai-light.js +165 -0
- package/dist/generated/mistica-icons/icon-search-ai-regular.js +165 -0
- package/dist/grid-layout.css-mistica.js +3 -3
- package/dist/grid.css-mistica.js +120 -120
- package/dist/header.css-mistica.js +1 -1
- package/dist/hero.css-mistica.js +2 -2
- package/dist/horizontal-scroll.css-mistica.js +1 -1
- package/dist/icon-button.css-mistica.js +53 -53
- package/dist/icons/icon-chevron.css-mistica.js +2 -2
- package/dist/icons/icon-error.css-mistica.js +1 -1
- package/dist/image.css-mistica.js +10 -10
- package/dist/index.d.ts +12 -0
- package/dist/index.js +48 -0
- package/dist/inline.css-mistica.js +11 -11
- package/dist/list.css-mistica.js +7 -7
- package/dist/loading-bar.css-mistica.js +1 -1
- package/dist/loading-screen.css-mistica.js +4 -4
- package/dist/logo.css-mistica.js +5 -5
- package/dist/menu.css-mistica.js +26 -24
- package/dist/menu.css.d.ts +2 -2
- package/dist/menu.d.ts +15 -3
- package/dist/menu.js +184 -162
- package/dist/mosaic.css-mistica.js +1 -1
- package/dist/navigation-bar.css-mistica.js +9 -9
- package/dist/navigation-breadcrumbs.css-mistica.js +1 -1
- package/dist/navigation-shared.css-mistica.js +9 -9
- package/dist/package-version.js +1 -1
- package/dist/pagination.css-mistica.js +18 -18
- package/dist/pin-field.css-mistica.js +1 -1
- package/dist/popover.css-mistica.js +1 -1
- package/dist/popover.d.ts +1 -0
- package/dist/progress-bar.css-mistica.js +6 -6
- package/dist/radio-button.css-mistica.js +19 -19
- package/dist/radio-button.d.ts +3 -1
- package/dist/radio-button.js +73 -72
- package/dist/rating.css-mistica.js +2 -2
- package/dist/responsive-layout.css-mistica.js +6 -6
- package/dist/screen-reader-only.css-mistica.js +1 -1
- package/dist/select.css-mistica.js +15 -15
- package/dist/sheet-action-row.css-mistica.js +1 -1
- package/dist/sheet-common.css-mistica.js +1 -1
- package/dist/sheet-info.css-mistica.js +1 -1
- package/dist/sidenav-bar-layout.css-mistica.js +1 -1
- package/dist/sidenav-bar.css-mistica.js +71 -71
- package/dist/sidenav-bar.js +55 -50
- package/dist/skeletons.css-mistica.js +6 -6
- package/dist/skins/skin-contract.css-mistica.js +738 -738
- package/dist/skip-link.css-mistica.js +1 -1
- package/dist/slider.css-mistica.js +18 -18
- package/dist/snackbar.css-mistica.js +4 -4
- package/dist/spinner.css-mistica.js +1 -1
- package/dist/square.css-mistica.js +1 -1
- package/dist/stack.css-mistica.js +5 -5
- package/dist/stacking-group.css-mistica.js +1 -1
- package/dist/stepper.css-mistica.js +2 -2
- package/dist/switch-component.css-mistica.js +35 -35
- package/dist/switch-component.d.ts +2 -0
- package/dist/switch-component.js +19 -18
- package/dist/table.css-mistica.js +9 -9
- package/dist/tabs.css-mistica.js +17 -17
- package/dist/tag.css-mistica.js +1 -1
- package/dist/text-field-base.css-mistica.js +16 -16
- package/dist/text-field-components.css-mistica.js +3 -3
- package/dist/text-link.css-mistica.js +6 -6
- package/dist/text.css-mistica.js +6 -6
- package/dist/timeline.css-mistica.js +9 -9
- package/dist/timer.css-mistica.js +6 -6
- package/dist/tooltip.css-mistica.js +1 -1
- package/dist/tooltip.d.ts +3 -1
- package/dist/tooltip.js +158 -147
- package/dist/touchable.css-mistica.js +1 -1
- package/dist/utils/aspect-ratio-support.css-mistica.js +2 -2
- package/dist/video.css-mistica.js +1 -1
- package/dist/vivinho-loading-animation/vivinho-loading-animation.css-mistica.js +1 -1
- package/dist-es/accordion.css-mistica.js +6 -6
- package/dist-es/align.css-mistica.js +1 -1
- package/dist-es/autocomplete.css-mistica.js +1 -1
- package/dist-es/avatar.css-mistica.js +1 -1
- package/dist-es/badge.css-mistica.js +1 -1
- package/dist-es/box.css-mistica.js +13 -13
- package/dist-es/boxed.css-mistica.js +23 -23
- package/dist-es/button-group.css-mistica.js +1 -1
- package/dist-es/button-layout.css-mistica.js +14 -14
- package/dist-es/button.css-mistica.js +34 -34
- package/dist-es/callout.css-mistica.js +11 -11
- package/dist-es/card-data.js +10 -12
- package/dist-es/card-internal.css-mistica.js +25 -19
- package/dist-es/card-internal.js +482 -395
- package/dist-es/card-media.js +11 -13
- package/dist-es/card-naked.js +14 -16
- package/dist-es/carousel.css-mistica.js +8 -8
- package/dist-es/checkbox.css-mistica.js +11 -11
- package/dist-es/checkbox.js +19 -19
- package/dist-es/chip.css-mistica.js +15 -15
- package/dist-es/circle.css-mistica.js +1 -1
- package/dist-es/community/advanced-data-card.css-mistica.js +10 -7
- package/dist-es/community/advanced-data-card.js +214 -192
- package/dist-es/community/ai-card.css-mistica.js +4 -4
- package/dist-es/community/ai-card.js +1 -1
- package/dist-es/community/blocks.css-mistica.js +1 -1
- package/dist-es/community/cyber/example-component.css-mistica.js +1 -1
- package/dist-es/community/example-component.css-mistica.js +2 -2
- package/dist-es/counter.css-mistica.js +1 -1
- package/dist-es/cover-hero.css-mistica.js +2 -2
- package/dist-es/credit-card-number-field.css-mistica.js +3 -3
- package/dist-es/date-field.css-mistica.js +1 -1
- package/dist-es/date-time-picker.css-mistica.js +1 -1
- package/dist-es/dialog.css-mistica.js +4 -4
- package/dist-es/divider.css-mistica.js +5 -5
- package/dist-es/double-field.css-mistica.js +2 -2
- package/dist-es/drawer.css-mistica.js +1 -1
- package/dist-es/empty-state-card.css-mistica.js +1 -1
- package/dist-es/empty-state.css-mistica.js +5 -5
- package/dist-es/fade-in.css-mistica.js +1 -1
- package/dist-es/fade-out.css-mistica.js +1 -1
- package/dist-es/feedback.css-mistica.js +1 -1
- package/dist-es/file-upload.css-mistica.js +7 -7
- package/dist-es/fixed-footer-layout.css-mistica.js +2 -2
- package/dist-es/form.css-mistica.js +1 -1
- package/dist-es/generated/mistica-icons/icon-document-information-filled.js +115 -0
- package/dist-es/generated/mistica-icons/icon-document-information-light.js +115 -0
- package/dist-es/generated/mistica-icons/icon-document-information-regular.js +115 -0
- package/dist-es/generated/mistica-icons/icon-internet-roaming-filled.js +109 -0
- package/dist-es/generated/mistica-icons/icon-internet-roaming-light.js +109 -0
- package/dist-es/generated/mistica-icons/icon-internet-roaming-regular.js +109 -0
- package/dist-es/generated/mistica-icons/icon-mobile-information-filled.js +115 -0
- package/dist-es/generated/mistica-icons/icon-mobile-information-light.js +123 -0
- package/dist-es/generated/mistica-icons/icon-mobile-information-regular.js +115 -0
- package/dist-es/generated/mistica-icons/icon-search-ai-filled.js +115 -0
- package/dist-es/generated/mistica-icons/icon-search-ai-light.js +115 -0
- package/dist-es/generated/mistica-icons/icon-search-ai-regular.js +115 -0
- package/dist-es/grid-layout.css-mistica.js +3 -3
- package/dist-es/grid.css-mistica.js +120 -120
- package/dist-es/header.css-mistica.js +1 -1
- package/dist-es/hero.css-mistica.js +2 -2
- package/dist-es/horizontal-scroll.css-mistica.js +1 -1
- package/dist-es/icon-button.css-mistica.js +53 -53
- package/dist-es/icons/icon-chevron.css-mistica.js +2 -2
- package/dist-es/icons/icon-error.css-mistica.js +1 -1
- package/dist-es/image.css-mistica.js +4 -4
- package/dist-es/index.js +1501 -1489
- package/dist-es/inline.css-mistica.js +11 -11
- package/dist-es/list.css-mistica.js +7 -7
- package/dist-es/loading-bar.css-mistica.js +1 -1
- package/dist-es/loading-screen.css-mistica.js +4 -4
- package/dist-es/logo.css-mistica.js +5 -5
- package/dist-es/menu.css-mistica.js +14 -15
- package/dist-es/menu.js +238 -216
- package/dist-es/mosaic.css-mistica.js +1 -1
- package/dist-es/navigation-bar.css-mistica.js +9 -9
- package/dist-es/navigation-breadcrumbs.css-mistica.js +1 -1
- package/dist-es/navigation-shared.css-mistica.js +9 -9
- package/dist-es/package-version.js +1 -1
- package/dist-es/pagination.css-mistica.js +18 -18
- package/dist-es/pin-field.css-mistica.js +1 -1
- package/dist-es/popover.css-mistica.js +1 -1
- package/dist-es/progress-bar.css-mistica.js +6 -6
- package/dist-es/radio-button.css-mistica.js +19 -19
- package/dist-es/radio-button.js +91 -90
- package/dist-es/rating.css-mistica.js +2 -2
- package/dist-es/responsive-layout.css-mistica.js +6 -6
- package/dist-es/screen-reader-only.css-mistica.js +1 -1
- package/dist-es/select.css-mistica.js +15 -15
- package/dist-es/sheet-action-row.css-mistica.js +1 -1
- package/dist-es/sheet-common.css-mistica.js +1 -1
- package/dist-es/sheet-info.css-mistica.js +1 -1
- package/dist-es/sidenav-bar-layout.css-mistica.js +1 -1
- package/dist-es/sidenav-bar.css-mistica.js +71 -71
- package/dist-es/sidenav-bar.js +70 -65
- package/dist-es/skeletons.css-mistica.js +6 -6
- package/dist-es/skins/skin-contract.css-mistica.js +738 -738
- package/dist-es/skip-link.css-mistica.js +1 -1
- package/dist-es/slider.css-mistica.js +18 -18
- package/dist-es/snackbar.css-mistica.js +4 -4
- package/dist-es/spinner.css-mistica.js +1 -1
- package/dist-es/square.css-mistica.js +1 -1
- package/dist-es/stack.css-mistica.js +5 -5
- package/dist-es/stacking-group.css-mistica.js +1 -1
- package/dist-es/stepper.css-mistica.js +2 -2
- package/dist-es/style.css +1 -1
- package/dist-es/switch-component.css-mistica.js +35 -35
- package/dist-es/switch-component.js +34 -33
- package/dist-es/table.css-mistica.js +9 -9
- package/dist-es/tabs.css-mistica.js +17 -17
- package/dist-es/tag.css-mistica.js +1 -1
- package/dist-es/text-field-base.css-mistica.js +16 -16
- package/dist-es/text-field-components.css-mistica.js +3 -3
- package/dist-es/text-link.css-mistica.js +6 -6
- package/dist-es/text.css-mistica.js +6 -6
- package/dist-es/timeline.css-mistica.js +9 -9
- package/dist-es/timer.css-mistica.js +6 -6
- package/dist-es/tooltip.css-mistica.js +1 -1
- package/dist-es/tooltip.js +198 -187
- package/dist-es/touchable.css-mistica.js +1 -1
- package/dist-es/utils/aspect-ratio-support.css-mistica.js +2 -2
- package/dist-es/video.css-mistica.js +1 -1
- package/dist-es/vivinho-loading-animation/vivinho-loading-animation.css-mistica.js +1 -1
- package/doc/components.md +35 -0
- package/package.json +4 -3
- package/src/card-cover.tsx +2 -2
- package/src/card-data.tsx +3 -4
- package/src/card-internal.css.ts +36 -0
- package/src/card-internal.tsx +162 -9
- package/src/card-media.tsx +3 -4
- package/src/card-naked.tsx +3 -4
- package/src/checkbox.tsx +6 -1
- package/src/community/__screenshot_tests__/__image_snapshots__/ai-card-screenshot-test-tsx-ai-card-line-break-at-chars-1-snap.png +0 -0
- package/src/community/__screenshot_tests__/__image_snapshots__/ai-card-screenshot-test-tsx-ai-card-static-text-1-snap.png +0 -0
- package/src/community/__screenshot_tests__/ai-card-screenshot-test.tsx +28 -0
- package/src/community/__stories__/advanced-data-card-story.tsx +5 -0
- package/src/community/__type_tests__/advanced-data-card-type-test.tsx +3 -0
- package/src/community/advanced-data-card.css.ts +26 -1
- package/src/community/advanced-data-card.tsx +123 -73
- package/src/community/ai-card.tsx +3 -3
- package/src/index.tsx +12 -0
- package/src/menu.css.ts +5 -9
- package/src/menu.tsx +82 -64
- package/src/package-version.tsx +1 -1
- package/src/popover.tsx +1 -0
- package/src/radio-button.tsx +7 -1
- package/src/sidenav-bar.tsx +9 -2
- package/src/switch-component.tsx +7 -3
- package/src/tooltip.css.ts +1 -0
- package/src/tooltip.tsx +94 -90
package/src/switch-component.tsx
CHANGED
|
@@ -6,6 +6,7 @@ https://github.com/storybookjs/storybook/issues/11980
|
|
|
6
6
|
|
|
7
7
|
'use client';
|
|
8
8
|
import * as React from 'react';
|
|
9
|
+
import classnames from 'classnames';
|
|
9
10
|
import {debounce} from './utils/helpers';
|
|
10
11
|
import {SPACE} from './utils/keys';
|
|
11
12
|
import {useControlProps} from './form-context';
|
|
@@ -36,6 +37,7 @@ type PropsRender = {
|
|
|
36
37
|
'aria-labelledby'?: string;
|
|
37
38
|
'aria-label'?: string;
|
|
38
39
|
dataAttributes?: DataAttributes;
|
|
40
|
+
className?: string;
|
|
39
41
|
};
|
|
40
42
|
|
|
41
43
|
type PropsChildren = {
|
|
@@ -49,6 +51,7 @@ type PropsChildren = {
|
|
|
49
51
|
'aria-labelledby'?: string;
|
|
50
52
|
'aria-label'?: string;
|
|
51
53
|
dataAttributes?: DataAttributes;
|
|
54
|
+
className?: string;
|
|
52
55
|
};
|
|
53
56
|
|
|
54
57
|
const Switch = (props: PropsRender | PropsChildren): JSX.Element => {
|
|
@@ -155,15 +158,16 @@ const Switch = (props: PropsRender | PropsChildren): JSX.Element => {
|
|
|
155
158
|
onKeyDown={disabled ? undefined : handleKeyDown}
|
|
156
159
|
tabIndex={disabled ? undefined : 0}
|
|
157
160
|
ref={focusableRef}
|
|
158
|
-
className={
|
|
161
|
+
className={classnames(
|
|
159
162
|
props.render
|
|
160
163
|
? disabled
|
|
161
164
|
? styles.containerDisabledFullWidth
|
|
162
165
|
: styles.containerFullWidth
|
|
163
166
|
: disabled
|
|
164
167
|
? styles.containerDisabled
|
|
165
|
-
: styles.container
|
|
166
|
-
|
|
168
|
+
: styles.container,
|
|
169
|
+
props.className
|
|
170
|
+
)}
|
|
167
171
|
aria-disabled={disabled}
|
|
168
172
|
aria-label={props['aria-label']}
|
|
169
173
|
aria-labelledby={props['aria-label'] ? undefined : labelId}
|
package/src/tooltip.css.ts
CHANGED
package/src/tooltip.tsx
CHANGED
|
@@ -6,7 +6,6 @@ import {Transition} from 'react-transition-group';
|
|
|
6
6
|
import * as styles from './tooltip.css';
|
|
7
7
|
import Stack from './stack';
|
|
8
8
|
import {Text2} from './text';
|
|
9
|
-
import {getCssVarValue} from './utils/dom';
|
|
10
9
|
import {ESC, TAB} from './utils/keys';
|
|
11
10
|
import {isTouchableDevice} from './utils/environment';
|
|
12
11
|
import {isEqual} from './utils/helpers';
|
|
@@ -41,7 +40,9 @@ const TOOLTIP_ENTER_TRANSITION_DELAY_IN_MS = 500;
|
|
|
41
40
|
const TOOLTIP_EXIT_TRANSITION_DURATION_IN_MS = 100;
|
|
42
41
|
const ARROW_SIZE = 20;
|
|
43
42
|
const TOOLTIP_OFFSET_FROM_TARGET = 6;
|
|
44
|
-
const
|
|
43
|
+
const TOOLTIP_BORDER_SIZE = 1;
|
|
44
|
+
const TOOLTIP_PADDING_FROM_TARGET = TOOLTIP_OFFSET_FROM_TARGET + ARROW_SIZE / 2 + TOOLTIP_BORDER_SIZE;
|
|
45
|
+
const REFLECTED_POSITION = {top: 'bottom', bottom: 'top', left: 'right', right: 'left'} as const;
|
|
45
46
|
|
|
46
47
|
type Position = 'top' | 'bottom' | 'left' | 'right';
|
|
47
48
|
|
|
@@ -79,62 +80,36 @@ const getFinalPosition = (
|
|
|
79
80
|
tooltip: HTMLElement | undefined | null,
|
|
80
81
|
position: Position,
|
|
81
82
|
windowHeight: number,
|
|
82
|
-
windowWidth: number
|
|
83
|
+
windowWidth: number,
|
|
84
|
+
contentHeight?: number
|
|
83
85
|
): Position | undefined => {
|
|
84
86
|
if (!targetRect || !tooltip) {
|
|
85
87
|
return undefined;
|
|
86
88
|
}
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
89
|
+
const availableSpace = {
|
|
90
|
+
top: targetRect.top,
|
|
91
|
+
bottom: windowHeight - targetRect.bottom,
|
|
92
|
+
left: targetRect.left,
|
|
93
|
+
right: windowWidth - targetRect.right,
|
|
94
|
+
};
|
|
95
|
+
const dimensions = getElementDimensionsWithoutPadding(tooltip);
|
|
96
|
+
const width = dimensions.width;
|
|
97
|
+
const height = contentHeight === undefined ? dimensions.height : contentHeight + 2 * TOOLTIP_BORDER_SIZE;
|
|
98
|
+
const size = (position === 'top' || position === 'bottom' ? height : width) + TOOLTIP_PADDING_FROM_TARGET;
|
|
99
|
+
const reflected = REFLECTED_POSITION[position];
|
|
100
|
+
const candidateFinalPosition =
|
|
101
|
+
availableSpace[position] < size && availableSpace[reflected] > availableSpace[position]
|
|
102
|
+
? reflected
|
|
103
|
+
: position;
|
|
104
|
+
|
|
105
|
+
if (
|
|
106
|
+
(candidateFinalPosition === 'left' || candidateFinalPosition === 'right') &&
|
|
107
|
+
availableSpace[candidateFinalPosition] < size
|
|
108
|
+
) {
|
|
109
|
+
return availableSpace.bottom > availableSpace.top ? 'bottom' : 'top';
|
|
104
110
|
}
|
|
105
111
|
|
|
106
|
-
|
|
107
|
-
case 'left':
|
|
108
|
-
if (fitsHorizontal) {
|
|
109
|
-
return tooltipWidth <= availableSpaceOnLeft ? 'left' : 'right';
|
|
110
|
-
} else {
|
|
111
|
-
return availableSpaceOnBottom > availableSpaceOnTop ? 'bottom' : 'top';
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
case 'right':
|
|
115
|
-
if (fitsHorizontal) {
|
|
116
|
-
return tooltipWidth <= availableSpaceOnRight ? 'right' : 'left';
|
|
117
|
-
} else {
|
|
118
|
-
return availableSpaceOnBottom > availableSpaceOnTop ? 'bottom' : 'top';
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
case 'top':
|
|
122
|
-
if (fitsVertical) {
|
|
123
|
-
return tooltipHeight <= availableSpaceOnTop ? 'top' : 'bottom';
|
|
124
|
-
} else {
|
|
125
|
-
return availableSpaceOnLeft > availableSpaceOnRight ? 'left' : 'right';
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
case 'bottom':
|
|
129
|
-
if (fitsVertical) {
|
|
130
|
-
return tooltipHeight <= availableSpaceOnBottom ? 'bottom' : 'top';
|
|
131
|
-
} else {
|
|
132
|
-
return availableSpaceOnLeft > availableSpaceOnRight ? 'left' : 'right';
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
default:
|
|
136
|
-
return undefined;
|
|
137
|
-
}
|
|
112
|
+
return candidateFinalPosition;
|
|
138
113
|
};
|
|
139
114
|
|
|
140
115
|
type Props = {
|
|
@@ -145,6 +120,7 @@ type Props = {
|
|
|
145
120
|
targetStyle?: React.CSSProperties;
|
|
146
121
|
title?: string;
|
|
147
122
|
position?: Position;
|
|
123
|
+
alignment?: 'start' | 'middle' | 'end';
|
|
148
124
|
width?: number;
|
|
149
125
|
delay?: boolean;
|
|
150
126
|
dataAttributes?: DataAttributes;
|
|
@@ -157,6 +133,7 @@ type BaseTooltipProps = {
|
|
|
157
133
|
target: React.ReactNode;
|
|
158
134
|
targetStyle?: React.CSSProperties;
|
|
159
135
|
position?: Position;
|
|
136
|
+
alignment?: 'start' | 'middle' | 'end';
|
|
160
137
|
width?: number;
|
|
161
138
|
delay?: boolean;
|
|
162
139
|
dataAttributes?: DataAttributes;
|
|
@@ -174,6 +151,7 @@ export const BaseTooltip = ({
|
|
|
174
151
|
targetStyle,
|
|
175
152
|
width,
|
|
176
153
|
position = 'top',
|
|
154
|
+
alignment = 'middle',
|
|
177
155
|
dataAttributes,
|
|
178
156
|
delay = true,
|
|
179
157
|
centerContent,
|
|
@@ -183,7 +161,12 @@ export const BaseTooltip = ({
|
|
|
183
161
|
hasPointerInteractionOnly = false,
|
|
184
162
|
trackingEvent,
|
|
185
163
|
}: BaseTooltipProps): JSX.Element => {
|
|
186
|
-
const {texts, t} = useTheme();
|
|
164
|
+
const {texts, t, borderRadii} = useTheme();
|
|
165
|
+
const arrowOffsetFromBorder = parseFloat(borderRadii.popup);
|
|
166
|
+
const minSize = Math.max(
|
|
167
|
+
styles.CONTENT_MIN_WIDTH,
|
|
168
|
+
2 * (arrowOffsetFromBorder + TOOLTIP_BORDER_SIZE) + ARROW_SIZE
|
|
169
|
+
);
|
|
187
170
|
const tooltipId = React.useId();
|
|
188
171
|
const {openTooltipId} = useTooltipState();
|
|
189
172
|
const {openTooltip, closeTooltip} = useSetTooltipState();
|
|
@@ -194,6 +177,7 @@ export const BaseTooltip = ({
|
|
|
194
177
|
|
|
195
178
|
const targetRef = React.useRef<Element | null>(null);
|
|
196
179
|
const tooltipRef = React.useRef<HTMLDivElement | null>(null);
|
|
180
|
+
const contentRef = React.useRef<HTMLDivElement | null>(null);
|
|
197
181
|
const [tooltip, setTooltip] = React.useState<HTMLElement | null>(null);
|
|
198
182
|
const isTouchable = isTouchableDevice();
|
|
199
183
|
const tooltipEnterDelay = delay ? TOOLTIP_ENTER_TRANSITION_DELAY_IN_MS : 0;
|
|
@@ -208,7 +192,26 @@ export const BaseTooltip = ({
|
|
|
208
192
|
|
|
209
193
|
const targetRect = useBoundingRect(targetRef, isTooltipOpen);
|
|
210
194
|
const tooltipRect = useBoundingRect(tooltipRef, isTooltipOpen, true);
|
|
195
|
+
const contentRect = useBoundingRect(contentRef, isTooltipOpen, true);
|
|
211
196
|
const windowSize = useWindowSize();
|
|
197
|
+
const currentPosition = getFinalPosition(
|
|
198
|
+
targetRect,
|
|
199
|
+
tooltip,
|
|
200
|
+
position,
|
|
201
|
+
windowSize.height,
|
|
202
|
+
windowSize.width,
|
|
203
|
+
contentRect?.height
|
|
204
|
+
);
|
|
205
|
+
const maxHeight = Math.max(
|
|
206
|
+
0,
|
|
207
|
+
(currentPosition === 'top'
|
|
208
|
+
? targetRect?.top ?? windowSize.height
|
|
209
|
+
: currentPosition === 'bottom'
|
|
210
|
+
? windowSize.height - (targetRect?.bottom ?? 0)
|
|
211
|
+
: windowSize.height) -
|
|
212
|
+
(currentPosition === 'top' || currentPosition === 'bottom' ? TOOLTIP_PADDING_FROM_TARGET : 0) -
|
|
213
|
+
2 * TOOLTIP_BORDER_SIZE
|
|
214
|
+
);
|
|
212
215
|
|
|
213
216
|
const resetTooltipInteractions = React.useCallback(() => {
|
|
214
217
|
setIsFocused(false);
|
|
@@ -227,15 +230,7 @@ export const BaseTooltip = ({
|
|
|
227
230
|
return;
|
|
228
231
|
}
|
|
229
232
|
|
|
230
|
-
|
|
231
|
-
targetRect,
|
|
232
|
-
tooltip,
|
|
233
|
-
position,
|
|
234
|
-
windowSize.height,
|
|
235
|
-
windowSize.width
|
|
236
|
-
);
|
|
237
|
-
|
|
238
|
-
if (!finalPosition || !targetRect) {
|
|
233
|
+
if (!currentPosition || !targetRect) {
|
|
239
234
|
setTooltipComputedStyles(undefined);
|
|
240
235
|
setArrowComputedStyles(undefined);
|
|
241
236
|
resetTooltipInteractions();
|
|
@@ -250,22 +245,29 @@ export const BaseTooltip = ({
|
|
|
250
245
|
|
|
251
246
|
const maxLeftOffset = windowSize.width - tooltipWidth;
|
|
252
247
|
const maxTopOffset = windowSize.height - tooltipHeight;
|
|
248
|
+
const alignmentRatio = alignment === 'start' ? 0 : alignment === 'end' ? 1 : 0.5;
|
|
249
|
+
const leftPropInPx = Math.max(
|
|
250
|
+
0,
|
|
251
|
+
Math.min(maxLeftOffset, left + (right - left - tooltipWidth) * alignmentRatio)
|
|
252
|
+
);
|
|
253
|
+
const topPropInPx = Math.max(
|
|
254
|
+
0,
|
|
255
|
+
Math.min(maxTopOffset, top + (bottom - top - tooltipHeight) * alignmentRatio)
|
|
256
|
+
);
|
|
253
257
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
switch (finalPosition) {
|
|
258
|
+
switch (currentPosition) {
|
|
257
259
|
case 'top':
|
|
258
260
|
tooltipStyles = {
|
|
259
|
-
left:
|
|
261
|
+
left: leftPropInPx,
|
|
260
262
|
top: top - tooltipHeight - ARROW_SIZE / 2,
|
|
261
263
|
padding: `0px 0px ${TOOLTIP_PADDING_FROM_TARGET}px 0px`,
|
|
262
264
|
};
|
|
263
265
|
|
|
264
266
|
arrowStyles = {
|
|
265
267
|
left: Math.max(
|
|
266
|
-
|
|
268
|
+
leftPropInPx + arrowOffsetFromBorder,
|
|
267
269
|
Math.min(
|
|
268
|
-
|
|
270
|
+
leftPropInPx + tooltipWidth - arrowOffsetFromBorder - ARROW_SIZE,
|
|
269
271
|
(left + right - ARROW_SIZE) / 2
|
|
270
272
|
)
|
|
271
273
|
),
|
|
@@ -276,16 +278,16 @@ export const BaseTooltip = ({
|
|
|
276
278
|
|
|
277
279
|
case 'bottom':
|
|
278
280
|
tooltipStyles = {
|
|
279
|
-
left:
|
|
281
|
+
left: leftPropInPx,
|
|
280
282
|
top: bottom - TOOLTIP_OFFSET_FROM_TARGET,
|
|
281
283
|
padding: `${TOOLTIP_PADDING_FROM_TARGET}px 0px 0px 0px`,
|
|
282
284
|
};
|
|
283
285
|
|
|
284
286
|
arrowStyles = {
|
|
285
287
|
left: Math.max(
|
|
286
|
-
|
|
288
|
+
leftPropInPx + arrowOffsetFromBorder,
|
|
287
289
|
Math.min(
|
|
288
|
-
|
|
290
|
+
leftPropInPx + tooltipWidth - arrowOffsetFromBorder - ARROW_SIZE,
|
|
289
291
|
(left + right - ARROW_SIZE) / 2
|
|
290
292
|
)
|
|
291
293
|
),
|
|
@@ -298,15 +300,15 @@ export const BaseTooltip = ({
|
|
|
298
300
|
case 'left':
|
|
299
301
|
tooltipStyles = {
|
|
300
302
|
left: left - tooltipWidth - ARROW_SIZE / 2,
|
|
301
|
-
top:
|
|
303
|
+
top: topPropInPx,
|
|
302
304
|
padding: `0px ${TOOLTIP_PADDING_FROM_TARGET}px 0px 0px`,
|
|
303
305
|
};
|
|
304
306
|
|
|
305
307
|
arrowStyles = {
|
|
306
308
|
top: Math.max(
|
|
307
|
-
|
|
309
|
+
topPropInPx + arrowOffsetFromBorder,
|
|
308
310
|
Math.min(
|
|
309
|
-
|
|
311
|
+
topPropInPx + tooltipHeight - arrowOffsetFromBorder - ARROW_SIZE,
|
|
310
312
|
(top + bottom - ARROW_SIZE) / 2
|
|
311
313
|
)
|
|
312
314
|
),
|
|
@@ -318,18 +320,17 @@ export const BaseTooltip = ({
|
|
|
318
320
|
break;
|
|
319
321
|
|
|
320
322
|
case 'right':
|
|
321
|
-
default:
|
|
322
323
|
tooltipStyles = {
|
|
323
324
|
left: right - TOOLTIP_OFFSET_FROM_TARGET,
|
|
324
|
-
top:
|
|
325
|
+
top: topPropInPx,
|
|
325
326
|
padding: `0px 0px 0px ${TOOLTIP_PADDING_FROM_TARGET}px`,
|
|
326
327
|
};
|
|
327
328
|
|
|
328
329
|
arrowStyles = {
|
|
329
330
|
top: Math.max(
|
|
330
|
-
|
|
331
|
+
topPropInPx + arrowOffsetFromBorder,
|
|
331
332
|
Math.min(
|
|
332
|
-
|
|
333
|
+
topPropInPx + tooltipHeight - arrowOffsetFromBorder - ARROW_SIZE,
|
|
333
334
|
(top + bottom - ARROW_SIZE) / 2
|
|
334
335
|
)
|
|
335
336
|
),
|
|
@@ -339,6 +340,10 @@ export const BaseTooltip = ({
|
|
|
339
340
|
};
|
|
340
341
|
|
|
341
342
|
break;
|
|
343
|
+
default: {
|
|
344
|
+
const exhaustiveCheck: never = currentPosition;
|
|
345
|
+
throw new Error(`Invalid tooltip position: ${exhaustiveCheck}`);
|
|
346
|
+
}
|
|
342
347
|
}
|
|
343
348
|
|
|
344
349
|
/**
|
|
@@ -366,10 +371,12 @@ export const BaseTooltip = ({
|
|
|
366
371
|
targetRect,
|
|
367
372
|
tooltipRect,
|
|
368
373
|
isTooltipOpen,
|
|
369
|
-
|
|
374
|
+
currentPosition,
|
|
375
|
+
alignment,
|
|
370
376
|
windowSize,
|
|
371
377
|
tooltipComputedStyles,
|
|
372
378
|
arrowComputedStyles,
|
|
379
|
+
arrowOffsetFromBorder,
|
|
373
380
|
isTouchable,
|
|
374
381
|
tooltipId,
|
|
375
382
|
resetTooltipInteractions,
|
|
@@ -438,17 +445,8 @@ export const BaseTooltip = ({
|
|
|
438
445
|
hasControlledValue,
|
|
439
446
|
]);
|
|
440
447
|
|
|
441
|
-
const currentPosition = getFinalPosition(
|
|
442
|
-
targetRect,
|
|
443
|
-
tooltip,
|
|
444
|
-
position,
|
|
445
|
-
windowSize.height,
|
|
446
|
-
windowSize.width
|
|
447
|
-
);
|
|
448
|
-
|
|
449
448
|
// by default, center content only if tooltip has minimum possible width
|
|
450
|
-
const hasCenteredContent =
|
|
451
|
-
centerContent !== undefined ? centerContent : tooltipRect?.width === styles.CONTENT_MIN_WIDTH;
|
|
449
|
+
const hasCenteredContent = centerContent !== undefined ? centerContent : tooltipRect?.width === minSize;
|
|
452
450
|
|
|
453
451
|
return (
|
|
454
452
|
<>
|
|
@@ -568,17 +566,23 @@ export const BaseTooltip = ({
|
|
|
568
566
|
className={styles.tooltip}
|
|
569
567
|
style={{
|
|
570
568
|
width,
|
|
569
|
+
minWidth: minSize,
|
|
570
|
+
minHeight:
|
|
571
|
+
currentPosition === 'left' || currentPosition === 'right'
|
|
572
|
+
? minSize
|
|
573
|
+
: undefined,
|
|
571
574
|
...getBorderStyle(themeVariant),
|
|
572
575
|
maxWidth: Math.min(TOOLTIP_MAX_WIDTH, windowSize.width),
|
|
573
576
|
}}
|
|
574
577
|
>
|
|
575
578
|
<div
|
|
579
|
+
style={{maxHeight}}
|
|
576
580
|
className={classNames(styles.contentContainer, {
|
|
577
581
|
[styles.tooltipCenter]: hasCenteredContent,
|
|
578
582
|
})}
|
|
579
583
|
>
|
|
580
584
|
<ThemeVariant variant="default">
|
|
581
|
-
{content}
|
|
585
|
+
<div ref={contentRef}>{content}</div>
|
|
582
586
|
|
|
583
587
|
{onClose && (
|
|
584
588
|
<div className={styles.closeButtonIcon}>
|