@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.
@@ -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;
@@ -6,3 +6,4 @@ export default meta;
6
6
  type Story = StoryObj<FloatUIProps>;
7
7
  export declare const Uncontrolled: Story;
8
8
  export declare const Controlled: Story;
9
+ export declare const Hover: Story;
@@ -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: 'fas',
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
- const click = useClick(context);
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))] }));