@nascentdigital/funnel-ui 4.5.1 → 4.5.3

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 (67) hide show
  1. package/dist/client/hooks/breakpoint/BreakpointContainer.d.ts +1 -1
  2. package/dist/client/hooks/breakpoint/BreakpointContainer.js +3 -1
  3. package/dist/client/interaction/index.d.ts +0 -6
  4. package/dist/client/interaction/index.js +0 -6
  5. package/dist/server/blocks/Block.js +2 -2
  6. package/dist/server/blocks/Message.js +2 -1
  7. package/dist/server/blocks/Testimonial.js +13 -10
  8. package/dist/server/blocks/Testimonials.d.ts +35 -35
  9. package/dist/server/blocks/Testimonials.js +21 -66
  10. package/dist/server/blocks/index.d.ts +1 -0
  11. package/dist/server/blocks/index.js +1 -0
  12. package/dist/server/fields/CallToActions.d.ts +12 -0
  13. package/dist/server/fields/CallToActions.js +27 -0
  14. package/dist/server/fields/index.d.ts +1 -0
  15. package/dist/server/fields/index.js +1 -0
  16. package/dist/server/panels/BlockPanel.js +1 -2
  17. package/dist/server/panels/MessagePanel.d.ts +2 -6
  18. package/dist/server/panels/MessagePanel.js +2 -9
  19. package/dist/server/panels/TestimonialPanel.d.ts +44 -18
  20. package/dist/server/panels/TestimonialPanel.js +44 -19
  21. package/dist/server/panels/VisualPanel.d.ts +1 -1
  22. package/dist/styles/blocks/MediaLayout.css +23 -183
  23. package/package.json +2 -2
  24. package/dist/client/interaction/Popup.d.ts +0 -36
  25. package/dist/client/interaction/Popup.js +0 -244
  26. package/dist/client/interaction/Tooltip.d.ts +0 -16
  27. package/dist/client/interaction/Tooltip.js +0 -122
  28. package/dist/client/interaction/UILevel.d.ts +0 -1
  29. package/dist/client/interaction/UILevel.js +0 -2
  30. package/dist/client/interaction/backdrop/BackdropContainer.d.ts +0 -5
  31. package/dist/client/interaction/backdrop/BackdropContainer.js +0 -114
  32. package/dist/client/interaction/backdrop/BackdropContext.d.ts +0 -8
  33. package/dist/client/interaction/backdrop/BackdropContext.js +0 -6
  34. package/dist/client/interaction/backdrop/BackdropEvent.d.ts +0 -64
  35. package/dist/client/interaction/backdrop/BackdropEvent.js +0 -92
  36. package/dist/client/interaction/backdrop/index.d.ts +0 -4
  37. package/dist/client/interaction/backdrop/index.js +0 -20
  38. package/dist/client/interaction/backdrop/useBackdrop.d.ts +0 -13
  39. package/dist/client/interaction/backdrop/useBackdrop.js +0 -58
  40. package/dist/client/interaction/backdrop/useBackdropClick.d.ts +0 -2
  41. package/dist/client/interaction/backdrop/useBackdropClick.js +0 -21
  42. package/dist/client/interaction/backdrop/useBackdropVisible.d.ts +0 -1
  43. package/dist/client/interaction/backdrop/useBackdropVisible.js +0 -30
  44. package/dist/client/interaction/focus/FocusArea.d.ts +0 -10
  45. package/dist/client/interaction/focus/FocusArea.js +0 -38
  46. package/dist/client/interaction/focus/FocusContext.d.ts +0 -7
  47. package/dist/client/interaction/focus/FocusContext.js +0 -7
  48. package/dist/client/interaction/focus/FocusController.d.ts +0 -9
  49. package/dist/client/interaction/focus/FocusController.js +0 -40
  50. package/dist/client/interaction/focus/FocusService.d.ts +0 -20
  51. package/dist/client/interaction/focus/FocusService.js +0 -204
  52. package/dist/client/interaction/focus/LinkedList.d.ts +0 -18
  53. package/dist/client/interaction/focus/LinkedList.js +0 -122
  54. package/dist/client/interaction/focus/index.d.ts +0 -2
  55. package/dist/client/interaction/focus/index.js +0 -18
  56. package/dist/client/interaction/focus/useFocusService.d.ts +0 -2
  57. package/dist/client/interaction/focus/useFocusService.js +0 -14
  58. package/dist/client/interaction/modal/Modal.d.ts +0 -29
  59. package/dist/client/interaction/modal/Modal.js +0 -136
  60. package/dist/client/interaction/modal/ModalContainer.d.ts +0 -5
  61. package/dist/client/interaction/modal/ModalContainer.js +0 -104
  62. package/dist/client/interaction/modal/ModalContext.d.ts +0 -8
  63. package/dist/client/interaction/modal/ModalContext.js +0 -6
  64. package/dist/client/interaction/modal/ModalEvent.d.ts +0 -39
  65. package/dist/client/interaction/modal/ModalEvent.js +0 -53
  66. package/dist/client/interaction/modal/index.d.ts +0 -2
  67. package/dist/client/interaction/modal/index.js +0 -18
@@ -8,7 +8,7 @@ export declare namespace VisualPanel {
8
8
  type Props = BlockPanel.Props & {
9
9
  className?: string;
10
10
  panel: BlockLayout.Visual;
11
- visual: Visual.Model;
11
+ visual?: Visual.Model;
12
12
  visualDecorator?: ReactNode;
13
13
  visualLoading?: Visual.Loading;
14
14
  aspect?: AspectRatio;
@@ -1,214 +1,54 @@
1
1
  @layer components {
2
2
 
3
3
  :root {
4
- --nd-medialayout-gap: theme('spacing.l8');
5
- --nd-medialayout-poster-gap: unset;
6
- --nd-medialayout-1col-gap: var(--nd-medialayout-gap);
7
- --nd-medialayout-2col-gap: var(--nd-medialayout-gap);
8
- --nd-medialayout-brick-gap: var(--nd-medialayout-gap);
9
- @media screen(md) {
10
- --nd-medialayout-gap: theme('spacing.l9');
11
- }
12
- @media screen(lg) {
13
- --nd-medialayout-gap: theme('spacing.l10');
14
- }
15
4
  }
16
5
 
17
6
  /* base */
18
7
  .nd-MediaLayout {
19
8
  }
20
9
 
10
+ /* visual aspect ratios */
11
+ .nd-MediaLayout .nd-ListPanel {
21
12
 
22
- /* poster */
23
- .nd-MediaLayout-layout-poster {
24
-
25
- .nd-MediaLayout-content {
26
- @apply flex flex-col gap-[var(--nd-medialayout-poster-gap)];
27
- }
28
- .nd-MediaLayout-itemWrap {
29
- @apply w-full aspect-cinema lg:aspect-cinemascope;
30
- }
31
- .nd-MediaLayout-item {
32
- @apply w-full object-cover;
33
- }
34
- }
35
-
36
- /* 1col */
37
- .nd-MediaLayout-layout-1col {
38
-
39
- .nd-MediaLayout-content {
40
- @apply container-wide-p flex flex-col gap-[var(--nd-medialayout-1col-gap)];
41
- }
42
- .nd-MediaLayout-itemWrap {
43
- @apply w-full;
44
- }
45
- .nd-MediaLayout-item {
46
- @apply w-full object-cover;
47
- }
48
- }
49
-
50
- /* 2col */
51
- ._nd-MediaLayout-layout-2col-mobile {
52
- .nd-MediaLayout-content {
53
- @apply container-wide-p grid grid-flow-row grid-cols-1 gap-[var(--nd-medialayout-2col-gap)];
54
- }
13
+ /* general styling across layouts */
55
14
  .nd-MediaLayout-itemWrap {
56
- @apply block max-w-full aspect-tv overflow-hidden;
15
+ @apply block w-full overflow-hidden;
57
16
  }
58
17
  .nd-MediaLayout-item {
59
- @apply w-full h-full object-cover object-center;
18
+ @apply size-full object-cover object-center;
60
19
  }
61
- }
62
- ._nd-MediaLayout-layout-2col-desktop {
63
- .nd-MediaLayout-content {
64
- @apply container-wide-p grid grid-cols-2 grid-flow-row gap-[var(--nd-medialayout-2col-gap)];
65
- }
66
- .nd-MediaLayout-itemWrap {
67
- @apply w-full col-span-1 aspect-tv overflow-hidden;
68
-
69
- /* make full width if a solo last child */
70
- &:nth-child(odd):last-child {
71
- @apply col-span-full aspect-cinema;
72
- }
73
- }
74
- .nd-MediaLayout-item {
75
- @apply w-full h-full object-cover object-center;
76
- }
77
- }
78
- .nd-MediaLayout-layout-2col {
79
- @apply max-md:_nd-MediaLayout-layout-2col-mobile md:_nd-MediaLayout-layout-2col-desktop;
80
- }
81
20
 
82
- /* brick */
83
- ._nd-MediaLayout-layout-brick-mobile {
84
-
85
- .nd-MediaLayout-content {
86
- @apply container-wide-p grid grid-flow-row grid-cols-1 gap-[var(--nd-medialayout-brick-gap)];
87
- }
88
- .nd-MediaLayout-itemWrap {
89
- @apply block max-w-full aspect-widescreen overflow-hidden;
90
- }
91
- .nd-MediaLayout-item {
92
- @apply w-full h-full object-cover object-center;
93
- }
94
- }
95
- ._nd-MediaLayout-layout-brick-desktop {
96
-
97
- /* base */
98
- .nd-MediaLayout-content {
99
- @apply container-wide-p grid grid-cols-2 gap-[var(--nd-medialayout-brick-gap)];
100
- }
101
- .nd-MediaLayout-itemWrap {
102
- @apply block max-w-full col-span-1 aspect-tv overflow-hidden;
103
-
104
- /* every 1, 4, 7, 10, 13 and so on images will be full width */
105
- &:nth-child(3n + 1) {
106
- @apply col-span-full aspect-cinema;
107
- }
108
- }
109
- .nd-MediaLayout-item {
110
- @apply w-full h-full object-cover object-center;
111
- }
112
-
113
- /* if the total number of images are 2, 5, 8, 11, 14 and so on, then make last 2 single */
114
- .nd-MediaLayout-content:has(.nd-MediaLayout-itemWrap:nth-child(3n+2):last-child) {
21
+ /* brick */
22
+ .nd-BrickLayout {
115
23
 
24
+ /* default aspect ratio */
116
25
  .nd-MediaLayout-itemWrap {
117
- &:nth-last-child(1), &:nth-last-child(2) {
118
- @apply col-span-1 aspect-tv;
119
- }
26
+ @apply aspect-widescreen @panel-md:aspect-tv;
120
27
  }
121
- }
122
- }
123
- .nd-MediaLayout-layout-brick {
124
- @apply max-md:_nd-MediaLayout-layout-brick-mobile md:_nd-MediaLayout-layout-brick-desktop;
125
- }
126
-
127
-
128
- /* brick */
129
- ._nd-MediaLayout-layout-brickAlt-desktop {
130
28
 
131
- /* base */
132
- .nd-MediaLayout-content {
133
- @apply container-wide-p grid grid-cols-2 gap-[var(--nd-medialayout-brick-gap)];
134
- }
135
- .nd-MediaLayout-itemWrap {
136
- @apply block max-w-full col-span-1 aspect-tv overflow-hidden;
29
+ /* brick (not flipped) */
30
+ &:not(.nd-BrickLayout-flipped) {
137
31
 
138
- /* every 3, 6, 9, 12, 15 and so on images will be full width */
139
- &:nth-child(3n) {
140
- @apply col-span-full aspect-cinema;
32
+ /* every 1, 4, 7, 10, 13 and so on images will be full width */
33
+ .nd-MediaLayout-itemWrap:nth-child(3n + 1) {
34
+ @apply @panel-md:aspect-cinema;
35
+ }
141
36
  }
142
- }
143
- .nd-MediaLayout-item {
144
- @apply w-full h-full object-cover object-center;
145
- }
146
37
 
147
- /* if the total number of images are 1, 4, 7, 10, 13, 16 and so on, then make last 2 single */
148
- .nd-MediaLayout-content:has(.nd-MediaLayout-itemWrap:nth-child(3n+2):last-child) {
38
+ /* brick (flipped) */
39
+ &.nd-BrickLayout-flipped {
149
40
 
150
- .nd-MediaLayout-itemWrap {
151
- &:nth-last-child(1), &:nth-last-child(2) {
152
- @apply col-span-1 aspect-tv;
41
+ /* every 3, 6, 9, 12, 15 and so on images will be full width */
42
+ .nd-MediaLayout-itemWrap:nth-child(3n) {
43
+ @apply @panel-md:aspect-cinema;
153
44
  }
154
45
  }
155
46
  }
156
47
 
157
- /* single image would be full width */
158
- .nd-MediaLayout-content:has(.nd-MediaLayout-itemWrap:first-child:last-child) {
159
-
160
- /* make it full width */
48
+ /* vertical stack */
49
+ .nd-StackLayout.nd-StackLayout-direction-vertical {
161
50
  .nd-MediaLayout-itemWrap {
162
- @apply col-span-full aspect-cinema;
163
- }
164
- }
165
- }
166
- .nd-MediaLayout-layout-brickAlt {
167
- @apply max-md:_nd-MediaLayout-layout-brick-mobile md:_nd-MediaLayout-layout-brickAlt-desktop;
168
- }
169
- }
170
-
171
-
172
- @layer components {
173
-
174
- /* desktop overrides */
175
- @media screen(md) {
176
- .nd-MediaGrid-root {
177
-
178
- /* brick layout flipped */
179
- &.nd-MediaGrid-brickFlipped {
180
- .nd-MediaGrid-content {
181
- @apply grid-cols-2;
182
-
183
- .nd-MediaGrid-visual {
184
- @apply col-span-1;
185
-
186
- /* every 3, 6, 9, 12, 15 and so on images will be full width */
187
- &:nth-child(3n) {
188
- @apply col-span-full aspect-widescreen;
189
- }
190
- }
191
-
192
- /* if the total number of images are 1, 4, 7, 10, 13, 16 and so on */
193
- &:has(.nd-MediaGrid-visual:nth-child(3n+1):last-child) {
194
-
195
- /* make the last two images take 50-50 of the screen width */
196
- .nd-MediaGrid-visual {
197
- &:nth-last-child(2) {
198
- @apply col-span-1 aspect-tv;
199
- }
200
- }
201
- }
202
-
203
- /* if there is only one image */
204
- &:has(.nd-MediaGrid-visual:first-child:last-child) {
205
-
206
- /* make it full width */
207
- .nd-MediaGrid-visual {
208
- @apply col-span-full aspect-widescreen;
209
- }
210
- }
211
- }
51
+ @apply aspect-cinema @panel-lg:aspect-cinemascope;
212
52
  }
213
53
  }
214
54
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nascentdigital/funnel-ui",
3
3
  "description": "UI components for funnel",
4
- "version": "4.5.1",
4
+ "version": "4.5.3",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/",
7
7
  "access": "restricted"
@@ -70,5 +70,5 @@
70
70
  "react-dom": "^19",
71
71
  "ts-jest": "^29.3.2"
72
72
  },
73
- "gitHead": "3348c90ff56f3dd931ab564f8a6ad13d454a4ca1"
73
+ "gitHead": "ef42bb5440cc23187aeefc29319875ed5402676f"
74
74
  }
@@ -1,36 +0,0 @@
1
- import { Callback, Frame, Rect } from '@nascentdigital/funnel-core';
2
- import { Variants } from 'framer-motion';
3
- import { HTMLAttributes } from 'react';
4
- import { ClickObserver } from './ClickObserver';
5
- import { UILevel } from './UILevel';
6
- export declare function Popup({ className, style, anchor, level, placement, anchorOffset, viewportPadding, animation, dismissTrigger, disableBackground, disabled, bubbleCloseEvent, open, onOpened: onOpenedRaw, onClose, onClosed: onClosedRaw, children, ...props }: Popup.Props): import("react/jsx-runtime").JSX.Element | null;
7
- export declare namespace Popup {
8
- type Props = HTMLAttributes<HTMLDivElement> & {
9
- anchor?: Rect | Element | string | null | undefined;
10
- level?: UILevel;
11
- placement?: Placement;
12
- anchorOffset?: number;
13
- viewportPadding?: number;
14
- animation?: Animation;
15
- dismissTrigger?: ClickObserver.Trigger | 'none';
16
- disableBackground?: boolean;
17
- disabled?: boolean;
18
- bubbleCloseEvent?: boolean;
19
- open?: boolean;
20
- onOpened?: Callback.Void;
21
- onClose?: Callback.Void;
22
- onClosed?: Callback.Void;
23
- };
24
- type Placement = 'top-start' | 'top' | 'top-end' | 'top-match' | 'bottom-start' | 'bottom' | 'bottom-end' | 'bottom-match' | 'left-start' | 'left' | 'left-end' | 'right-start' | 'right' | 'right-end';
25
- type Animation = 'in' | 'out' | 'in-out';
26
- type GetFrameArgs = {
27
- anchorRect: Rect;
28
- contentElement: HTMLDivElement;
29
- placement: Popup.Placement;
30
- anchorOffset: number;
31
- viewportPadding: number;
32
- };
33
- function getFrame({ anchorRect, contentElement, placement, anchorOffset, viewportPadding }: GetFrameArgs): Partial<Frame>;
34
- }
35
- export declare const animations: Variants;
36
- export declare function getAnchorRect(anchor: Rect | Element | string | null | undefined): Rect | null;
@@ -1,244 +0,0 @@
1
- "use strict";
2
- var __rest = (this && this.__rest) || function (s, e) {
3
- var t = {};
4
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
- t[p] = s[p];
6
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
- t[p[i]] = s[p[i]];
10
- }
11
- return t;
12
- };
13
- var __importDefault = (this && this.__importDefault) || function (mod) {
14
- return (mod && mod.__esModule) ? mod : { "default": mod };
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.animations = void 0;
18
- exports.Popup = Popup;
19
- exports.getAnchorRect = getAnchorRect;
20
- const jsx_runtime_1 = require("react/jsx-runtime");
21
- const funnel_core_1 = require("@nascentdigital/funnel-core");
22
- const classnames_1 = __importDefault(require("classnames"));
23
- const framer_motion_1 = require("framer-motion");
24
- const react_1 = require("react");
25
- const react_dom_1 = require("react-dom");
26
- const react_hotkeys_hook_1 = require("react-hotkeys-hook");
27
- const hooks_1 = require("../hooks");
28
- const ClickObserver_1 = require("./ClickObserver");
29
- // component
30
- function Popup(_a) {
31
- var { className, style = {}, anchor, level = 'l1', placement = 'bottom', anchorOffset = 0, viewportPadding = 0, animation = 'in-out', dismissTrigger, disableBackground = false, disabled = false, bubbleCloseEvent = false, open = false, onOpened: onOpenedRaw = funnel_core_1.Fn.NoOp, onClose = funnel_core_1.Fn.NoOp, onClosed: onClosedRaw = funnel_core_1.Fn.NoOp, children } = _a, props = __rest(_a, ["className", "style", "anchor", "level", "placement", "anchorOffset", "viewportPadding", "animation", "dismissTrigger", "disableBackground", "disabled", "bubbleCloseEvent", "open", "onOpened", "onClose", "onClosed", "children"]);
32
- // bind context
33
- const [active, setActive] = (0, react_1.useState)(false);
34
- const openedRef = (0, react_1.useRef)(false);
35
- const contentRef = (0, react_1.useRef)(null);
36
- const id = (0, react_1.useId)();
37
- const anchorRect = getAnchorRect(anchor);
38
- const onOpenedRef = (0, react_1.useRef)(onOpenedRaw);
39
- onOpenedRef.current = onOpenedRaw;
40
- const onClosedRef = (0, react_1.useRef)(onClosedRaw);
41
- onClosedRef.current = onClosedRaw;
42
- const closeCallback = (0, react_1.useCallback)(() => {
43
- if (openedRef.current) {
44
- onClose();
45
- }
46
- }, [onClose]);
47
- // re-render on window size change
48
- (0, hooks_1.useViewportSize)();
49
- // close on escape
50
- (0, react_hotkeys_hook_1.useHotkeys)('esc', closeCallback);
51
- // show/hide based on open change
52
- (0, react_1.useEffect)(() => {
53
- // raise event on open/close
54
- let unlock = undefined;
55
- if (open) {
56
- // update ref
57
- openedRef.current = true;
58
- // activate
59
- setActive(true);
60
- // lock keyboard
61
- unlock = funnel_core_1.Browser.lockFocus(`#${CSS.escape(id)}`);
62
- }
63
- // raise event on close (if it was actually opened)
64
- else if (openedRef.current) {
65
- // deactivate
66
- setActive(false);
67
- // update ref
68
- openedRef.current = false;
69
- }
70
- // on unmount
71
- return () => {
72
- // unlock (if locked)
73
- if (unlock) {
74
- unlock();
75
- }
76
- };
77
- }, [open, id]);
78
- // skip for SSR
79
- if (!funnel_core_1.Browser.available) {
80
- return null;
81
- }
82
- // compute popup rect (if visible + ready)
83
- const contentElement = contentRef.current;
84
- const popupFrame = active && !!anchorRect && !!contentElement
85
- ? Popup.getFrame({
86
- anchorRect,
87
- contentElement,
88
- placement,
89
- anchorOffset,
90
- viewportPadding
91
- })
92
- : {};
93
- // helpers
94
- const onClickOutside = (e) => {
95
- // consume click
96
- if (!bubbleCloseEvent) {
97
- e.preventDefault();
98
- e.stopPropagation();
99
- }
100
- // close
101
- onClose();
102
- };
103
- const onAnimationComplete = (definition) => {
104
- if (definition === 'visible') {
105
- onOpenedRef.current();
106
- }
107
- else if (definition === 'exit') {
108
- onClosedRef.current();
109
- }
110
- };
111
- // render
112
- return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { children: open && !!anchorRect &&
113
- (0, jsx_runtime_1.jsx)(framer_motion_1.motion.div, { id: id, className: (0, classnames_1.default)('Popup-wrap', {
114
- 'Popup-disableBg': disableBackground,
115
- 'Popup-disabled': disabled,
116
- 'Popup-l1': level === 'l1',
117
- 'Popup-l2': level === 'l2',
118
- 'Popup-l3': level === 'l3'
119
- }), variants: exports.animations, initial: animation !== 'out' ? 'hidden' : 'visible', animate: "visible", exit: animation !== 'in' ? 'exit' : 'visible', onAnimationComplete: definition => onAnimationComplete(definition), children: (0, jsx_runtime_1.jsx)(ClickObserver_1.ClickObserver, { trigger: dismissTrigger === 'none' ? 'click' : dismissTrigger, disabled: !open || dismissTrigger === 'none', onClickOutside: onClickOutside, children: (0, jsx_runtime_1.jsx)("div", Object.assign({}, props, { ref: contentRef, style: Object.assign(Object.assign({}, style), popupFrame), className: (0, classnames_1.default)(className, 'Popup-root'), children: children })) }) }, id) }), document.body) }));
120
- }
121
- // extension
122
- (function (Popup) {
123
- // helpers
124
- function getFrame({ anchorRect, contentElement, placement, anchorOffset, viewportPadding }) {
125
- // get geometries
126
- const viewportRect = new funnel_core_1.Rect(viewportPadding, viewportPadding, window.innerWidth - viewportPadding * 2, window.innerHeight - viewportPadding * 2);
127
- const contentWidth = contentElement.offsetWidth;
128
- const contentHeight = contentElement.offsetHeight;
129
- // horizontal layout if left/right
130
- const popupFrame = {};
131
- const [primary, secondary] = placement.split('-');
132
- if (primary === 'left' || primary === 'right') {
133
- // determine space to left/right
134
- const spaceLeft = Math.max(0, anchorRect.left - viewportRect.left - anchorOffset);
135
- const spaceRight = Math.max(0, viewportRect.right - anchorRect.right - anchorOffset);
136
- // place left if it fits or it fits better than on the right
137
- if ((primary === 'left' && (spaceLeft >= contentWidth || spaceLeft > spaceRight))
138
- || (primary === 'right' && spaceRight < contentWidth && spaceRight < spaceLeft)) {
139
- popupFrame.right = viewportRect.right - anchorRect.left + anchorOffset;
140
- }
141
- // or place right
142
- else {
143
- popupFrame.left = anchorRect.right + anchorOffset;
144
- }
145
- // top-align on start
146
- if (secondary === 'start') {
147
- popupFrame.top = anchorRect.top;
148
- }
149
- // bottom-align on end
150
- else if (secondary === 'end') {
151
- popupFrame.bottom = viewportRect.bottom - anchorRect.bottom;
152
- }
153
- // or center against anchor
154
- else {
155
- // set top bounds so it's centered
156
- popupFrame.top = Math.max(anchorRect.top + (anchorRect.height - contentHeight) / 2, viewportRect.top);
157
- // offset if the bottom is bleeding over
158
- if (popupFrame.top + contentHeight > viewportRect.bottom) {
159
- popupFrame.top -= popupFrame.top + contentHeight - viewportRect.bottom;
160
- }
161
- }
162
- }
163
- // or standard vertical layout
164
- else {
165
- // determine space to top/bottom
166
- const spaceTop = Math.max(0, anchorRect.top - viewportRect.top - anchorOffset);
167
- const spaceBottom = Math.max(0, viewportRect.bottom - anchorRect.bottom - anchorOffset);
168
- // place above if it fits or it fits better than on the right
169
- if ((primary === 'top' && (spaceTop >= contentHeight || spaceBottom < spaceTop))
170
- || (primary === 'bottom' && spaceBottom < contentHeight && spaceBottom < spaceTop)) {
171
- popupFrame.bottom = viewportRect.bottom - anchorRect.top + anchorOffset;
172
- }
173
- // or place below
174
- else {
175
- popupFrame.top = anchorRect.bottom + anchorOffset;
176
- }
177
- // left-align on start
178
- if (secondary === 'start') {
179
- popupFrame.left = anchorRect.left;
180
- }
181
- // right-align on end
182
- else if (secondary === 'end') {
183
- popupFrame.right = viewportRect.right - anchorRect.right;
184
- }
185
- // match width
186
- else if (secondary === 'match') {
187
- popupFrame.left = anchorRect.left;
188
- popupFrame.width = anchorRect.width;
189
- }
190
- // or center against anchor
191
- else {
192
- // set left bounds so it's centered
193
- popupFrame.left = Math.max(anchorRect.left + (anchorRect.width - contentWidth) / 2, viewportRect.left);
194
- // offset if the right is bleeding over
195
- if (popupFrame.left + contentWidth > viewportRect.right) {
196
- popupFrame.left -= popupFrame.left + contentWidth - viewportRect.right;
197
- }
198
- }
199
- }
200
- // return position insets
201
- return popupFrame;
202
- }
203
- Popup.getFrame = getFrame;
204
- })(Popup || (exports.Popup = Popup = {}));
205
- // helpers
206
- exports.animations = {
207
- hidden: {
208
- opacity: 0
209
- },
210
- visible: {
211
- opacity: 1,
212
- transition: {
213
- ease: 'easeOut',
214
- duration: 0.5,
215
- when: 'beforeChildren'
216
- }
217
- },
218
- exit: {
219
- opacity: 0,
220
- transition: {
221
- ease: 'easeIn',
222
- duration: 0.15,
223
- bounce: 0,
224
- when: 'afterChildren'
225
- }
226
- }
227
- };
228
- function getAnchorRect(anchor) {
229
- // skip if there's no anchor or if we're SSR
230
- if (!anchor || !funnel_core_1.Browser.available) {
231
- return null;
232
- }
233
- // or skip if we already have a rect
234
- else if (anchor instanceof funnel_core_1.Rect) {
235
- return anchor;
236
- }
237
- // try to coerce anchor into an element (or fail)
238
- const anchorElement = typeof anchor === 'string'
239
- ? document.querySelector(anchor)
240
- : anchor;
241
- return anchorElement
242
- ? funnel_core_1.Rect.fromInsets(anchorElement.getBoundingClientRect())
243
- : null;
244
- }
@@ -1,16 +0,0 @@
1
- import { ReactNode, RefObject } from 'react';
2
- import { Popup } from './Popup';
3
- export declare function Tooltip({ delay, scroller, content, children, anchorClassName, popupClassName, onClose, placement, anchorOffset, viewportPadding, disabled }: DelayedPopup.Props): import("react/jsx-runtime").JSX.Element;
4
- export declare namespace DelayedPopup {
5
- type Props = Pick<Popup.Props, 'anchorOffset' | 'viewportPadding' | 'placement' | 'onClose'> & {
6
- delay?: number;
7
- scroller?: string | RefObject<HTMLElement | null>;
8
- content: ReactNode;
9
- children: ReactNode;
10
- anchorClassName?: string;
11
- popupClassName?: string;
12
- disabled?: boolean;
13
- };
14
- type HoverState = 'inactive' | 'waiting' | 'active';
15
- type TapState = 'inactive' | 'active';
16
- }