@indico-data/design-system 3.8.0 → 3.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.
- package/lib/components/floatUI/FloatUI.d.ts +1 -1
- package/lib/components/floatUI/FloatUI.stories.d.ts +1 -0
- package/lib/components/floatUI/types.d.ts +2 -0
- package/lib/components/icons/Icon.d.ts +1 -1
- package/lib/components/icons/types.d.ts +5 -1
- package/lib/index.d.ts +9 -3
- package/lib/index.esm.js +329 -10
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +329 -10
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/floatUI/FloatUI.mdx +8 -1
- package/src/components/floatUI/FloatUI.stories.tsx +44 -0
- package/src/components/floatUI/FloatUI.tsx +6 -2
- package/src/components/floatUI/__tests__/FloatUI.test.tsx +32 -0
- package/src/components/floatUI/types.ts +2 -0
- package/src/components/icons/Icon.stories.tsx +7 -0
- package/src/components/icons/Icon.tsx +9 -2
- package/src/components/icons/types.ts +5 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { FloatUIProps } from './types';
|
|
2
|
-
export declare function FloatUI({ children, ariaLabel, isOpen: controlledIsOpen, setIsOpen: controlledSetIsOpen, isPortal, portalOptions, floatingOptions, className, }: FloatUIProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function FloatUI({ children, ariaLabel, isOpen: controlledIsOpen, setIsOpen: controlledSetIsOpen, isPortal, portalOptions, floatingOptions, className, hover, }: FloatUIProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -18,4 +18,6 @@ export type FloatUIProps = {
|
|
|
18
18
|
};
|
|
19
19
|
/** Function to toggle the visibility of the FloatUI (for controlled mode). */
|
|
20
20
|
setIsOpen?: React.Dispatch<React.SetStateAction<boolean>>;
|
|
21
|
+
/** If true, opens on hover instead of click. Defaults to false. */
|
|
22
|
+
hover?: boolean;
|
|
21
23
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { IconProps } from './types';
|
|
2
|
-
export declare const Icon: ({ name, size, className, ariaLabel, ...props }: IconProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
2
|
+
export declare const Icon: ({ name, size, className, ariaLabel, faPrefix, ...props }: IconProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MouseEventHandler, CSSProperties } from 'react';
|
|
2
2
|
import { PermafrostComponent } from '../../types';
|
|
3
|
-
import { IconName as FAIconName } from '@fortawesome/fontawesome-svg-core';
|
|
3
|
+
import { IconName as FAIconName, IconPrefix } from '@fortawesome/fontawesome-svg-core';
|
|
4
4
|
import { indicons } from './indicons';
|
|
5
5
|
export type IconSizes = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl';
|
|
6
6
|
export type IndiconName = keyof typeof indicons;
|
|
@@ -16,4 +16,8 @@ export type IconProps = PermafrostComponent & {
|
|
|
16
16
|
style?: CSSProperties;
|
|
17
17
|
/** Click event handler */
|
|
18
18
|
onClick?: MouseEventHandler<SVGElement>;
|
|
19
|
+
/** The Font Awesome prefix of the icon (defaults to 'fas', the solid icon prefix)
|
|
20
|
+
* Only used for Font Awesome icons, not for Indicons.
|
|
21
|
+
*/
|
|
22
|
+
faPrefix?: IconPrefix;
|
|
19
23
|
};
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IconDefinition, IconName as IconName$1 } from '@fortawesome/fontawesome-svg-core';
|
|
1
|
+
import { IconDefinition, IconPrefix, IconName as IconName$1 } from '@fortawesome/fontawesome-svg-core';
|
|
2
2
|
import { UseFloatingOptions } from '@floating-ui/react-dom';
|
|
3
3
|
export * from '@floating-ui/react-dom';
|
|
4
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
@@ -191,6 +191,10 @@ type IconProps = PermafrostComponent & {
|
|
|
191
191
|
style?: CSSProperties;
|
|
192
192
|
/** Click event handler */
|
|
193
193
|
onClick?: MouseEventHandler<SVGElement>;
|
|
194
|
+
/** The Font Awesome prefix of the icon (defaults to 'fas', the solid icon prefix)
|
|
195
|
+
* Only used for Font Awesome icons, not for Indicons.
|
|
196
|
+
*/
|
|
197
|
+
faPrefix?: IconPrefix;
|
|
194
198
|
};
|
|
195
199
|
|
|
196
200
|
type SelectOption = {
|
|
@@ -327,7 +331,7 @@ interface ButtonProps {
|
|
|
327
331
|
|
|
328
332
|
declare const Button: React$1.ForwardRefExoticComponent<ButtonProps & React$1.RefAttributes<HTMLButtonElement>>;
|
|
329
333
|
|
|
330
|
-
declare const Icon: ({ name, size, className, ariaLabel, ...props }: IconProps) => react_jsx_runtime.JSX.Element | null;
|
|
334
|
+
declare const Icon: ({ name, size, className, ariaLabel, faPrefix, ...props }: IconProps) => react_jsx_runtime.JSX.Element | null;
|
|
331
335
|
|
|
332
336
|
declare const Table: <T>(props: TableProps<T>) => react_jsx_runtime.JSX.Element;
|
|
333
337
|
|
|
@@ -772,9 +776,11 @@ type FloatUIProps = {
|
|
|
772
776
|
};
|
|
773
777
|
/** Function to toggle the visibility of the FloatUI (for controlled mode). */
|
|
774
778
|
setIsOpen?: React.Dispatch<React.SetStateAction<boolean>>;
|
|
779
|
+
/** If true, opens on hover instead of click. Defaults to false. */
|
|
780
|
+
hover?: boolean;
|
|
775
781
|
};
|
|
776
782
|
|
|
777
|
-
declare function FloatUI({ children, ariaLabel, isOpen: controlledIsOpen, setIsOpen: controlledSetIsOpen, isPortal, portalOptions, floatingOptions, className, }: FloatUIProps): react_jsx_runtime.JSX.Element;
|
|
783
|
+
declare function FloatUI({ children, ariaLabel, isOpen: controlledIsOpen, setIsOpen: controlledSetIsOpen, isPortal, portalOptions, floatingOptions, className, hover, }: FloatUIProps): react_jsx_runtime.JSX.Element;
|
|
778
784
|
|
|
779
785
|
type MenuProps = {
|
|
780
786
|
children: React$1.ReactNode;
|
package/lib/index.esm.js
CHANGED
|
@@ -2283,7 +2283,7 @@ function roundByDPR(element, value) {
|
|
|
2283
2283
|
return Math.round(value * dpr) / dpr;
|
|
2284
2284
|
}
|
|
2285
2285
|
|
|
2286
|
-
function useLatestRef(value) {
|
|
2286
|
+
function useLatestRef$1(value) {
|
|
2287
2287
|
const ref = React.useRef(value);
|
|
2288
2288
|
index$1(() => {
|
|
2289
2289
|
ref.current = value;
|
|
@@ -2344,8 +2344,8 @@ function useFloating$1(options) {
|
|
|
2344
2344
|
const floatingRef = React.useRef(null);
|
|
2345
2345
|
const dataRef = React.useRef(data);
|
|
2346
2346
|
const hasWhileElementsMounted = whileElementsMounted != null;
|
|
2347
|
-
const whileElementsMountedRef = useLatestRef(whileElementsMounted);
|
|
2348
|
-
const platformRef = useLatestRef(platform);
|
|
2347
|
+
const whileElementsMountedRef = useLatestRef$1(whileElementsMounted);
|
|
2348
|
+
const platformRef = useLatestRef$1(platform);
|
|
2349
2349
|
const update = React.useCallback(() => {
|
|
2350
2350
|
if (!referenceRef.current || !floatingRef.current) {
|
|
2351
2351
|
return;
|
|
@@ -5016,7 +5016,7 @@ var classnamesExports = classnames.exports;
|
|
|
5016
5016
|
var classNames = /*@__PURE__*/getDefaultExportFromCjs(classnamesExports);
|
|
5017
5017
|
|
|
5018
5018
|
const Icon = (_a) => {
|
|
5019
|
-
var { name, size = 'md', className, ariaLabel } = _a, props = __rest(_a, ["name", "size", "className", "ariaLabel"]);
|
|
5019
|
+
var { name, size = 'md', className, ariaLabel, faPrefix = 'fas' } = _a, props = __rest(_a, ["name", "size", "className", "ariaLabel", "faPrefix"]);
|
|
5020
5020
|
const label = ariaLabel || `${name} Icon`;
|
|
5021
5021
|
const iconClasses = classNames('icon', {
|
|
5022
5022
|
[`icon--${size}`]: size,
|
|
@@ -5026,7 +5026,7 @@ const Icon = (_a) => {
|
|
|
5026
5026
|
// Otherwise, search for an indicon (registered under Font Awesome with a prefix of 'fak')
|
|
5027
5027
|
const icon = faIconName
|
|
5028
5028
|
? findIconDefinition({
|
|
5029
|
-
prefix:
|
|
5029
|
+
prefix: faPrefix,
|
|
5030
5030
|
iconName: faIconName,
|
|
5031
5031
|
})
|
|
5032
5032
|
: findIconDefinition({
|
|
@@ -11933,6 +11933,9 @@ function isMouseLikePointerType(pointerType, strict) {
|
|
|
11933
11933
|
// On some Linux machines with Chromium, mouse inputs return a `pointerType`
|
|
11934
11934
|
// of "pen": https://github.com/floating-ui/floating-ui/issues/2015
|
|
11935
11935
|
const values = ['mouse', 'pen'];
|
|
11936
|
+
if (!strict) {
|
|
11937
|
+
values.push('', undefined);
|
|
11938
|
+
}
|
|
11936
11939
|
return values.includes(pointerType);
|
|
11937
11940
|
}
|
|
11938
11941
|
function isReactEvent(event) {
|
|
@@ -12628,6 +12631,320 @@ function createAttribute(name) {
|
|
|
12628
12631
|
return "data-floating-ui-" + name;
|
|
12629
12632
|
}
|
|
12630
12633
|
|
|
12634
|
+
function useLatestRef(value) {
|
|
12635
|
+
const ref = useRef(value);
|
|
12636
|
+
index(() => {
|
|
12637
|
+
ref.current = value;
|
|
12638
|
+
});
|
|
12639
|
+
return ref;
|
|
12640
|
+
}
|
|
12641
|
+
|
|
12642
|
+
const safePolygonIdentifier = /*#__PURE__*/createAttribute('safe-polygon');
|
|
12643
|
+
function getDelay(value, prop, pointerType) {
|
|
12644
|
+
if (pointerType && !isMouseLikePointerType(pointerType)) {
|
|
12645
|
+
return 0;
|
|
12646
|
+
}
|
|
12647
|
+
if (typeof value === 'number') {
|
|
12648
|
+
return value;
|
|
12649
|
+
}
|
|
12650
|
+
return value == null ? void 0 : value[prop];
|
|
12651
|
+
}
|
|
12652
|
+
/**
|
|
12653
|
+
* Opens the floating element while hovering over the reference element, like
|
|
12654
|
+
* CSS `:hover`.
|
|
12655
|
+
* @see https://floating-ui.com/docs/useHover
|
|
12656
|
+
*/
|
|
12657
|
+
function useHover(context, props) {
|
|
12658
|
+
if (props === void 0) {
|
|
12659
|
+
props = {};
|
|
12660
|
+
}
|
|
12661
|
+
const {
|
|
12662
|
+
open,
|
|
12663
|
+
onOpenChange,
|
|
12664
|
+
dataRef,
|
|
12665
|
+
events,
|
|
12666
|
+
elements
|
|
12667
|
+
} = context;
|
|
12668
|
+
const {
|
|
12669
|
+
enabled = true,
|
|
12670
|
+
delay = 0,
|
|
12671
|
+
handleClose = null,
|
|
12672
|
+
mouseOnly = false,
|
|
12673
|
+
restMs = 0,
|
|
12674
|
+
move = true
|
|
12675
|
+
} = props;
|
|
12676
|
+
const tree = useFloatingTree();
|
|
12677
|
+
const parentId = useFloatingParentNodeId();
|
|
12678
|
+
const handleCloseRef = useLatestRef(handleClose);
|
|
12679
|
+
const delayRef = useLatestRef(delay);
|
|
12680
|
+
const openRef = useLatestRef(open);
|
|
12681
|
+
const pointerTypeRef = React.useRef();
|
|
12682
|
+
const timeoutRef = React.useRef(-1);
|
|
12683
|
+
const handlerRef = React.useRef();
|
|
12684
|
+
const restTimeoutRef = React.useRef(-1);
|
|
12685
|
+
const blockMouseMoveRef = React.useRef(true);
|
|
12686
|
+
const performedPointerEventsMutationRef = React.useRef(false);
|
|
12687
|
+
const unbindMouseMoveRef = React.useRef(() => {});
|
|
12688
|
+
const isHoverOpen = React.useCallback(() => {
|
|
12689
|
+
var _dataRef$current$open;
|
|
12690
|
+
const type = (_dataRef$current$open = dataRef.current.openEvent) == null ? void 0 : _dataRef$current$open.type;
|
|
12691
|
+
return (type == null ? void 0 : type.includes('mouse')) && type !== 'mousedown';
|
|
12692
|
+
}, [dataRef]);
|
|
12693
|
+
|
|
12694
|
+
// When closing before opening, clear the delay timeouts to cancel it
|
|
12695
|
+
// from showing.
|
|
12696
|
+
React.useEffect(() => {
|
|
12697
|
+
if (!enabled) return;
|
|
12698
|
+
function onOpenChange(_ref) {
|
|
12699
|
+
let {
|
|
12700
|
+
open
|
|
12701
|
+
} = _ref;
|
|
12702
|
+
if (!open) {
|
|
12703
|
+
clearTimeout(timeoutRef.current);
|
|
12704
|
+
clearTimeout(restTimeoutRef.current);
|
|
12705
|
+
blockMouseMoveRef.current = true;
|
|
12706
|
+
}
|
|
12707
|
+
}
|
|
12708
|
+
events.on('openchange', onOpenChange);
|
|
12709
|
+
return () => {
|
|
12710
|
+
events.off('openchange', onOpenChange);
|
|
12711
|
+
};
|
|
12712
|
+
}, [enabled, events]);
|
|
12713
|
+
React.useEffect(() => {
|
|
12714
|
+
if (!enabled) return;
|
|
12715
|
+
if (!handleCloseRef.current) return;
|
|
12716
|
+
if (!open) return;
|
|
12717
|
+
function onLeave(event) {
|
|
12718
|
+
if (isHoverOpen()) {
|
|
12719
|
+
onOpenChange(false, event, 'hover');
|
|
12720
|
+
}
|
|
12721
|
+
}
|
|
12722
|
+
const html = getDocument(elements.floating).documentElement;
|
|
12723
|
+
html.addEventListener('mouseleave', onLeave);
|
|
12724
|
+
return () => {
|
|
12725
|
+
html.removeEventListener('mouseleave', onLeave);
|
|
12726
|
+
};
|
|
12727
|
+
}, [elements.floating, open, onOpenChange, enabled, handleCloseRef, isHoverOpen]);
|
|
12728
|
+
const closeWithDelay = React.useCallback(function (event, runElseBranch, reason) {
|
|
12729
|
+
if (runElseBranch === void 0) {
|
|
12730
|
+
runElseBranch = true;
|
|
12731
|
+
}
|
|
12732
|
+
if (reason === void 0) {
|
|
12733
|
+
reason = 'hover';
|
|
12734
|
+
}
|
|
12735
|
+
const closeDelay = getDelay(delayRef.current, 'close', pointerTypeRef.current);
|
|
12736
|
+
if (closeDelay && !handlerRef.current) {
|
|
12737
|
+
clearTimeout(timeoutRef.current);
|
|
12738
|
+
timeoutRef.current = window.setTimeout(() => onOpenChange(false, event, reason), closeDelay);
|
|
12739
|
+
} else if (runElseBranch) {
|
|
12740
|
+
clearTimeout(timeoutRef.current);
|
|
12741
|
+
onOpenChange(false, event, reason);
|
|
12742
|
+
}
|
|
12743
|
+
}, [delayRef, onOpenChange]);
|
|
12744
|
+
const cleanupMouseMoveHandler = useEffectEvent(() => {
|
|
12745
|
+
unbindMouseMoveRef.current();
|
|
12746
|
+
handlerRef.current = undefined;
|
|
12747
|
+
});
|
|
12748
|
+
const clearPointerEvents = useEffectEvent(() => {
|
|
12749
|
+
if (performedPointerEventsMutationRef.current) {
|
|
12750
|
+
const body = getDocument(elements.floating).body;
|
|
12751
|
+
body.style.pointerEvents = '';
|
|
12752
|
+
body.removeAttribute(safePolygonIdentifier);
|
|
12753
|
+
performedPointerEventsMutationRef.current = false;
|
|
12754
|
+
}
|
|
12755
|
+
});
|
|
12756
|
+
|
|
12757
|
+
// Registering the mouse events on the reference directly to bypass React's
|
|
12758
|
+
// delegation system. If the cursor was on a disabled element and then entered
|
|
12759
|
+
// the reference (no gap), `mouseenter` doesn't fire in the delegation system.
|
|
12760
|
+
React.useEffect(() => {
|
|
12761
|
+
if (!enabled) return;
|
|
12762
|
+
function isClickLikeOpenEvent() {
|
|
12763
|
+
return dataRef.current.openEvent ? ['click', 'mousedown'].includes(dataRef.current.openEvent.type) : false;
|
|
12764
|
+
}
|
|
12765
|
+
function onMouseEnter(event) {
|
|
12766
|
+
clearTimeout(timeoutRef.current);
|
|
12767
|
+
blockMouseMoveRef.current = false;
|
|
12768
|
+
if (mouseOnly && !isMouseLikePointerType(pointerTypeRef.current) || restMs > 0 && !getDelay(delayRef.current, 'open')) {
|
|
12769
|
+
return;
|
|
12770
|
+
}
|
|
12771
|
+
const openDelay = getDelay(delayRef.current, 'open', pointerTypeRef.current);
|
|
12772
|
+
if (openDelay) {
|
|
12773
|
+
timeoutRef.current = window.setTimeout(() => {
|
|
12774
|
+
if (!openRef.current) {
|
|
12775
|
+
onOpenChange(true, event, 'hover');
|
|
12776
|
+
}
|
|
12777
|
+
}, openDelay);
|
|
12778
|
+
} else {
|
|
12779
|
+
onOpenChange(true, event, 'hover');
|
|
12780
|
+
}
|
|
12781
|
+
}
|
|
12782
|
+
function onMouseLeave(event) {
|
|
12783
|
+
if (isClickLikeOpenEvent()) return;
|
|
12784
|
+
unbindMouseMoveRef.current();
|
|
12785
|
+
const doc = getDocument(elements.floating);
|
|
12786
|
+
clearTimeout(restTimeoutRef.current);
|
|
12787
|
+
if (handleCloseRef.current && dataRef.current.floatingContext) {
|
|
12788
|
+
// Prevent clearing `onScrollMouseLeave` timeout.
|
|
12789
|
+
if (!open) {
|
|
12790
|
+
clearTimeout(timeoutRef.current);
|
|
12791
|
+
}
|
|
12792
|
+
handlerRef.current = handleCloseRef.current({
|
|
12793
|
+
...dataRef.current.floatingContext,
|
|
12794
|
+
tree,
|
|
12795
|
+
x: event.clientX,
|
|
12796
|
+
y: event.clientY,
|
|
12797
|
+
onClose() {
|
|
12798
|
+
clearPointerEvents();
|
|
12799
|
+
cleanupMouseMoveHandler();
|
|
12800
|
+
closeWithDelay(event, true, 'safe-polygon');
|
|
12801
|
+
}
|
|
12802
|
+
});
|
|
12803
|
+
const handler = handlerRef.current;
|
|
12804
|
+
doc.addEventListener('mousemove', handler);
|
|
12805
|
+
unbindMouseMoveRef.current = () => {
|
|
12806
|
+
doc.removeEventListener('mousemove', handler);
|
|
12807
|
+
};
|
|
12808
|
+
return;
|
|
12809
|
+
}
|
|
12810
|
+
|
|
12811
|
+
// Allow interactivity without `safePolygon` on touch devices. With a
|
|
12812
|
+
// pointer, a short close delay is an alternative, so it should work
|
|
12813
|
+
// consistently.
|
|
12814
|
+
const shouldClose = pointerTypeRef.current === 'touch' ? !contains(elements.floating, event.relatedTarget) : true;
|
|
12815
|
+
if (shouldClose) {
|
|
12816
|
+
closeWithDelay(event);
|
|
12817
|
+
}
|
|
12818
|
+
}
|
|
12819
|
+
|
|
12820
|
+
// Ensure the floating element closes after scrolling even if the pointer
|
|
12821
|
+
// did not move.
|
|
12822
|
+
// https://github.com/floating-ui/floating-ui/discussions/1692
|
|
12823
|
+
function onScrollMouseLeave(event) {
|
|
12824
|
+
if (isClickLikeOpenEvent()) return;
|
|
12825
|
+
if (!dataRef.current.floatingContext) return;
|
|
12826
|
+
handleCloseRef.current == null || handleCloseRef.current({
|
|
12827
|
+
...dataRef.current.floatingContext,
|
|
12828
|
+
tree,
|
|
12829
|
+
x: event.clientX,
|
|
12830
|
+
y: event.clientY,
|
|
12831
|
+
onClose() {
|
|
12832
|
+
clearPointerEvents();
|
|
12833
|
+
cleanupMouseMoveHandler();
|
|
12834
|
+
closeWithDelay(event);
|
|
12835
|
+
}
|
|
12836
|
+
})(event);
|
|
12837
|
+
}
|
|
12838
|
+
if (isElement$1(elements.domReference)) {
|
|
12839
|
+
var _elements$floating;
|
|
12840
|
+
const ref = elements.domReference;
|
|
12841
|
+
open && ref.addEventListener('mouseleave', onScrollMouseLeave);
|
|
12842
|
+
(_elements$floating = elements.floating) == null || _elements$floating.addEventListener('mouseleave', onScrollMouseLeave);
|
|
12843
|
+
move && ref.addEventListener('mousemove', onMouseEnter, {
|
|
12844
|
+
once: true
|
|
12845
|
+
});
|
|
12846
|
+
ref.addEventListener('mouseenter', onMouseEnter);
|
|
12847
|
+
ref.addEventListener('mouseleave', onMouseLeave);
|
|
12848
|
+
return () => {
|
|
12849
|
+
var _elements$floating2;
|
|
12850
|
+
open && ref.removeEventListener('mouseleave', onScrollMouseLeave);
|
|
12851
|
+
(_elements$floating2 = elements.floating) == null || _elements$floating2.removeEventListener('mouseleave', onScrollMouseLeave);
|
|
12852
|
+
move && ref.removeEventListener('mousemove', onMouseEnter);
|
|
12853
|
+
ref.removeEventListener('mouseenter', onMouseEnter);
|
|
12854
|
+
ref.removeEventListener('mouseleave', onMouseLeave);
|
|
12855
|
+
};
|
|
12856
|
+
}
|
|
12857
|
+
}, [elements, enabled, context, mouseOnly, restMs, move, closeWithDelay, cleanupMouseMoveHandler, clearPointerEvents, onOpenChange, open, openRef, tree, delayRef, handleCloseRef, dataRef]);
|
|
12858
|
+
|
|
12859
|
+
// Block pointer-events of every element other than the reference and floating
|
|
12860
|
+
// while the floating element is open and has a `handleClose` handler. Also
|
|
12861
|
+
// handles nested floating elements.
|
|
12862
|
+
// https://github.com/floating-ui/floating-ui/issues/1722
|
|
12863
|
+
index(() => {
|
|
12864
|
+
var _handleCloseRef$curre;
|
|
12865
|
+
if (!enabled) return;
|
|
12866
|
+
if (open && (_handleCloseRef$curre = handleCloseRef.current) != null && _handleCloseRef$curre.__options.blockPointerEvents && isHoverOpen()) {
|
|
12867
|
+
const body = getDocument(elements.floating).body;
|
|
12868
|
+
body.setAttribute(safePolygonIdentifier, '');
|
|
12869
|
+
body.style.pointerEvents = 'none';
|
|
12870
|
+
performedPointerEventsMutationRef.current = true;
|
|
12871
|
+
const floatingEl = elements.floating;
|
|
12872
|
+
if (isElement$1(elements.domReference) && floatingEl) {
|
|
12873
|
+
var _tree$nodesRef$curren;
|
|
12874
|
+
const ref = elements.domReference;
|
|
12875
|
+
const parentFloating = tree == null || (_tree$nodesRef$curren = tree.nodesRef.current.find(node => node.id === parentId)) == null || (_tree$nodesRef$curren = _tree$nodesRef$curren.context) == null ? void 0 : _tree$nodesRef$curren.elements.floating;
|
|
12876
|
+
if (parentFloating) {
|
|
12877
|
+
parentFloating.style.pointerEvents = '';
|
|
12878
|
+
}
|
|
12879
|
+
ref.style.pointerEvents = 'auto';
|
|
12880
|
+
floatingEl.style.pointerEvents = 'auto';
|
|
12881
|
+
return () => {
|
|
12882
|
+
ref.style.pointerEvents = '';
|
|
12883
|
+
floatingEl.style.pointerEvents = '';
|
|
12884
|
+
};
|
|
12885
|
+
}
|
|
12886
|
+
}
|
|
12887
|
+
}, [enabled, open, parentId, elements, tree, handleCloseRef, isHoverOpen]);
|
|
12888
|
+
index(() => {
|
|
12889
|
+
if (!open) {
|
|
12890
|
+
pointerTypeRef.current = undefined;
|
|
12891
|
+
cleanupMouseMoveHandler();
|
|
12892
|
+
clearPointerEvents();
|
|
12893
|
+
}
|
|
12894
|
+
}, [open, cleanupMouseMoveHandler, clearPointerEvents]);
|
|
12895
|
+
React.useEffect(() => {
|
|
12896
|
+
return () => {
|
|
12897
|
+
cleanupMouseMoveHandler();
|
|
12898
|
+
clearTimeout(timeoutRef.current);
|
|
12899
|
+
clearTimeout(restTimeoutRef.current);
|
|
12900
|
+
clearPointerEvents();
|
|
12901
|
+
};
|
|
12902
|
+
}, [enabled, elements.domReference, cleanupMouseMoveHandler, clearPointerEvents]);
|
|
12903
|
+
const reference = React.useMemo(() => {
|
|
12904
|
+
function setPointerRef(event) {
|
|
12905
|
+
pointerTypeRef.current = event.pointerType;
|
|
12906
|
+
}
|
|
12907
|
+
return {
|
|
12908
|
+
onPointerDown: setPointerRef,
|
|
12909
|
+
onPointerEnter: setPointerRef,
|
|
12910
|
+
onMouseMove(event) {
|
|
12911
|
+
const {
|
|
12912
|
+
nativeEvent
|
|
12913
|
+
} = event;
|
|
12914
|
+
function handleMouseMove() {
|
|
12915
|
+
if (!blockMouseMoveRef.current && !openRef.current) {
|
|
12916
|
+
onOpenChange(true, nativeEvent, 'hover');
|
|
12917
|
+
}
|
|
12918
|
+
}
|
|
12919
|
+
if (mouseOnly && !isMouseLikePointerType(pointerTypeRef.current)) {
|
|
12920
|
+
return;
|
|
12921
|
+
}
|
|
12922
|
+
if (open || restMs === 0) {
|
|
12923
|
+
return;
|
|
12924
|
+
}
|
|
12925
|
+
clearTimeout(restTimeoutRef.current);
|
|
12926
|
+
if (pointerTypeRef.current === 'touch') {
|
|
12927
|
+
handleMouseMove();
|
|
12928
|
+
} else {
|
|
12929
|
+
restTimeoutRef.current = window.setTimeout(handleMouseMove, restMs);
|
|
12930
|
+
}
|
|
12931
|
+
}
|
|
12932
|
+
};
|
|
12933
|
+
}, [mouseOnly, onOpenChange, open, openRef, restMs]);
|
|
12934
|
+
const floating = React.useMemo(() => ({
|
|
12935
|
+
onMouseEnter() {
|
|
12936
|
+
clearTimeout(timeoutRef.current);
|
|
12937
|
+
},
|
|
12938
|
+
onMouseLeave(event) {
|
|
12939
|
+
closeWithDelay(event.nativeEvent, false);
|
|
12940
|
+
}
|
|
12941
|
+
}), [closeWithDelay]);
|
|
12942
|
+
return React.useMemo(() => enabled ? {
|
|
12943
|
+
reference,
|
|
12944
|
+
floating
|
|
12945
|
+
} : {}, [enabled, reference, floating]);
|
|
12946
|
+
}
|
|
12947
|
+
|
|
12631
12948
|
function getChildren(nodes, id) {
|
|
12632
12949
|
let allChildren = nodes.filter(node => {
|
|
12633
12950
|
var _node$context;
|
|
@@ -12953,7 +13270,7 @@ function useClick(context, props) {
|
|
|
12953
13270
|
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
|
|
12954
13271
|
if (event.button !== 0) return;
|
|
12955
13272
|
if (eventOption === 'click') return;
|
|
12956
|
-
if (isMouseLikePointerType(pointerType) && ignoreMouse) return;
|
|
13273
|
+
if (isMouseLikePointerType(pointerType, true) && ignoreMouse) return;
|
|
12957
13274
|
if (open && toggle && (dataRef.current.openEvent ? dataRef.current.openEvent.type === 'mousedown' : true)) {
|
|
12958
13275
|
onOpenChange(false, event.nativeEvent, 'click');
|
|
12959
13276
|
} else {
|
|
@@ -12968,7 +13285,7 @@ function useClick(context, props) {
|
|
|
12968
13285
|
pointerTypeRef.current = undefined;
|
|
12969
13286
|
return;
|
|
12970
13287
|
}
|
|
12971
|
-
if (isMouseLikePointerType(pointerType) && ignoreMouse) return;
|
|
13288
|
+
if (isMouseLikePointerType(pointerType, true) && ignoreMouse) return;
|
|
12972
13289
|
if (open && toggle && (dataRef.current.openEvent ? dataRef.current.openEvent.type === 'click' : true)) {
|
|
12973
13290
|
onOpenChange(false, event.nativeEvent, 'click');
|
|
12974
13291
|
} else {
|
|
@@ -13509,7 +13826,7 @@ const defaultOptions$1 = {
|
|
|
13509
13826
|
placement: 'bottom-start',
|
|
13510
13827
|
middleware: [offset$2(5), flip$2(), shift$2()],
|
|
13511
13828
|
};
|
|
13512
|
-
function FloatUI({ children, ariaLabel, isOpen: controlledIsOpen, setIsOpen: controlledSetIsOpen, isPortal = false, portalOptions = {}, floatingOptions = defaultOptions$1, className, }) {
|
|
13829
|
+
function FloatUI({ children, ariaLabel, isOpen: controlledIsOpen, setIsOpen: controlledSetIsOpen, isPortal = false, portalOptions = {}, floatingOptions = defaultOptions$1, className, hover = false, }) {
|
|
13513
13830
|
const [internalIsOpen, setInternalIsOpen] = useState(false);
|
|
13514
13831
|
// Determine whether the component is controlled or uncontrolled
|
|
13515
13832
|
const isControlled = controlledIsOpen !== undefined && controlledSetIsOpen !== undefined;
|
|
@@ -13528,9 +13845,11 @@ function FloatUI({ children, ariaLabel, isOpen: controlledIsOpen, setIsOpen: con
|
|
|
13528
13845
|
const { refs, floatingStyles, context } = useFloating(Object.assign(Object.assign({}, floatingOptions), { open: isOpen, onOpenChange: setIsOpen, elements: {
|
|
13529
13846
|
reference: referenceElementRef.current,
|
|
13530
13847
|
} }));
|
|
13531
|
-
|
|
13848
|
+
// Can't call hooks conditionally so this enabled option is needed.
|
|
13849
|
+
const click = useClick(context, { enabled: !hover });
|
|
13850
|
+
const hoverHook = useHover(context, { enabled: hover });
|
|
13532
13851
|
const dismiss = useDismiss(context);
|
|
13533
|
-
const { getReferenceProps, getFloatingProps } = useInteractions([click, dismiss]);
|
|
13852
|
+
const { getReferenceProps, getFloatingProps } = useInteractions([click, hoverHook, dismiss]);
|
|
13534
13853
|
const tooltipContent = (jsx("div", Object.assign({ ref: refs.setFloating }, getFloatingProps(), { style: floatingStyles, role: "dialog", "aria-label": ariaLabel, className: `floatui-container ${className}`, children: jsx("div", { ref: floatUIContentRef, className: "floatui-content", children: content }) })));
|
|
13535
13854
|
return (jsxs(Fragment, { children: [jsx("div", Object.assign({ ref: refs.setReference }, getReferenceProps(), { children: trigger })), isOpen &&
|
|
13536
13855
|
(isPortal ? (jsx(FloatingPortal, { id: portalOptions === null || portalOptions === void 0 ? void 0 : portalOptions.rootId, children: tooltipContent })) : (tooltipContent))] }));
|