@frontify/fondue 9.11.1 → 9.12.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.
@@ -9,8 +9,8 @@ import { useFocusRing as ot, FocusScope as rt } from "@react-aria/focus";
9
9
  import { useOverlay as nt, DismissButton as L } from "@react-aria/overlays";
10
10
  import { useSelect as st, HiddenSelect as lt } from "@react-aria/select";
11
11
  import { mergeProps as at } from "@react-aria/utils";
12
- import { useSelectState as mt } from "@react-stately/select";
13
- import { merge as it } from "../../utilities/merge.es.js";
12
+ import { useSelectState as it } from "@react-stately/select";
13
+ import { merge as mt } from "../../utilities/merge.es.js";
14
14
  import { AnimatePresence as pt, motion as ct } from "framer-motion";
15
15
  import e, { useRef as d, useEffect as ut } from "react";
16
16
  import { useDropdownAutoHeight as ft, DEFAULT_DROPDOWN_MAX_HEIGHT as dt } from "./useDropdownAutoHeight.es.js";
@@ -18,7 +18,7 @@ import { Validation as F } from "../../utilities/validation.es.js";
18
18
  import { LoadingCircle as wt, LoadingCircleSize as gt } from "../LoadingCircle/LoadingCircle.es.js";
19
19
  import { createPortal as St } from "react-dom";
20
20
  import { usePopper as ht } from "react-popper";
21
- var Et = /* @__PURE__ */ ((t) => (t.Small = "Small", t.Large = "Large", t))(Et || {}), bt = /* @__PURE__ */ ((t) => (t.Start = "Start", t.End = "End", t))(bt || {}), yt = /* @__PURE__ */ ((t) => (t.Top = "Top", t.Bottom = "Bottom", t))(yt || {});
21
+ var yt = /* @__PURE__ */ ((t) => (t.Small = "Small", t.Large = "Large", t))(yt || {}), Et = /* @__PURE__ */ ((t) => (t.Start = "Start", t.End = "End", t))(Et || {}), bt = /* @__PURE__ */ ((t) => (t.Top = "Top", t.Bottom = "Bottom", t))(bt || {});
22
22
  const xt = (t, s) => K(A(t)).has(s) ? null : t.map(({ menuItems: o }) => o).flat().find(({ id: o }) => o.toString() === (s == null ? void 0 : s.toString())) || null, Gt = ({
23
23
  id: t,
24
24
  menuBlocks: s,
@@ -36,26 +36,27 @@ const xt = (t, s) => K(A(t)).has(s) ? null : t.map(({ menuItems: o }) => o).flat
36
36
  position: O = "Bottom"
37
37
  }) => {
38
38
  var D;
39
- const r = o ? xt(s, o) : null, S = J(R, s), n = mt({
39
+ const r = o ? xt(s, o) : null, S = J(R, s), n = it({
40
40
  ...S,
41
41
  defaultSelectedKey: o,
42
- onSelectionChange: (i) => w(i),
42
+ onSelectionChange: (m) => w(m),
43
43
  disabledKeys: K(A(s))
44
- }), l = d(null), { triggerProps: z, valueProps: V, menuProps: _ } = st({ ...S, isDisabled: a }, n, l), { buttonProps: h } = et({ ...z, isDisabled: a }, l), { isOpen: m } = n, { isFocusVisible: v, focusProps: W } = ot(), E = d(null), { overlayProps: $ } = nt({ isOpen: m, onClose: () => n.close(), shouldCloseOnBlur: !0, isDismissable: !0 }, E);
44
+ }), l = d(null), { triggerProps: z, valueProps: V, menuProps: _ } = st({ ...S, isDisabled: a }, n, l), { buttonProps: h } = et({ ...z, isDisabled: a }, l), { isOpen: i } = n, { isFocusVisible: v, focusProps: W } = ot(), y = d(null), { overlayProps: $ } = nt({ isOpen: i, onClose: () => n.close(), shouldCloseOnBlur: !0, isDismissable: !0 }, y);
45
45
  ut(() => {
46
46
  n.disabledKeys.has(o) || n.setSelectedKey(o);
47
47
  }, [o]);
48
- const { maxHeight: b } = ft(l, { isOpen: m, autoResize: u }), G = !u || b !== dt, U = r ? f.Active : f.Default, X = a ? f.Disabled : U, j = r ? Y[r.style || Z.Primary][X] : "tw-text-black-60", y = N ? () => {
48
+ const { maxHeight: E } = ft(l, { isOpen: i, autoResize: u }), G = !u || E !== dt, U = r ? f.Active : f.Default, X = a ? f.Disabled : U, j = r ? Y[r.style || Z.Primary][X] : "tw-text-black-60", b = N ? () => {
49
49
  n.setSelectedKey("");
50
- const i = n.collection.getFirstKey();
51
- i && n.selectionManager.setFocusedKey(i);
52
- } : void 0, x = !!r && !!y, C = d(null), q = {
50
+ const m = n.collection.getFirstKey();
51
+ m && n.selectionManager.setFocusedKey(m);
52
+ } : void 0, x = !!r && !!b, C = d(null), q = {
53
53
  ["Top-Start"]: "top-start",
54
54
  ["Top-End"]: "top-end",
55
55
  ["Bottom-Start"]: "bottom-start",
56
56
  ["Bottom-End"]: "bottom-end"
57
57
  }, P = ht(l == null ? void 0 : l.current, C.current, {
58
58
  placement: q[`${O}-${H}`],
59
+ strategy: "fixed",
59
60
  modifiers: [
60
61
  {
61
62
  name: "offset",
@@ -75,9 +76,9 @@ const xt = (t, s) => K(A(t)).has(s) ? null : t.map(({ menuItems: o }) => o).flat
75
76
  disabled: a,
76
77
  buttonProps: h,
77
78
  isFocusVisible: !a && v,
78
- isOpen: m,
79
+ isOpen: i,
79
80
  size: p === "Large" ? M.Large : M.Small,
80
- onClear: y,
81
+ onClear: b,
81
82
  showClear: x,
82
83
  validation: g
83
84
  }, /* @__PURE__ */ e.createElement(lt, {
@@ -88,7 +89,7 @@ const xt = (t, s) => K(A(t)).has(s) ? null : t.map(({ menuItems: o }) => o).flat
88
89
  id: tt(t),
89
90
  ref: l,
90
91
  "data-test-id": "dropdown-trigger",
91
- className: it([
92
+ className: mt([
92
93
  "tw-overflow-hidden tw-flex-auto tw-h-full tw-rounded tw-text-left tw-outline-none",
93
94
  p === "Small" ? "tw-py-2 tw-pl-3 tw-min-h-[34px]" : "tw-pl-5 tw-py-4 tw-min-h-[60px]",
94
95
  x ? "tw-pr-11" : "tw-pr-7",
@@ -99,7 +100,7 @@ const xt = (t, s) => K(A(t)).has(s) ? null : t.map(({ menuItems: o }) => o).flat
99
100
  title: (r == null ? void 0 : r.title) || B,
100
101
  decorator: c != null ? c : r == null ? void 0 : r.decorator,
101
102
  size: p === "Small" ? T.Small : T.Large
102
- }))), St(/* @__PURE__ */ e.createElement(pt, null, !a && m && G && /* @__PURE__ */ e.createElement(ct.div, {
103
+ }))), St(/* @__PURE__ */ e.createElement(pt, null, !a && i && G && /* @__PURE__ */ e.createElement(ct.div, {
103
104
  ref: C,
104
105
  style: {
105
106
  ...P.styles.popper,
@@ -116,8 +117,8 @@ const xt = (t, s) => K(A(t)).has(s) ? null : t.map(({ menuItems: o }) => o).flat
116
117
  restoreFocus: !0
117
118
  }, /* @__PURE__ */ e.createElement("div", {
118
119
  ...$,
119
- ref: E,
120
- style: u ? { maxHeight: b } : {},
120
+ ref: y,
121
+ style: u ? { maxHeight: E } : {},
121
122
  className: "tw-flex tw-flex-col",
122
123
  "data-test-id": "dropdown-menu",
123
124
  role: "dialog"
@@ -138,8 +139,8 @@ const xt = (t, s) => K(A(t)).has(s) ? null : t.map(({ menuItems: o }) => o).flat
138
139
  };
139
140
  export {
140
141
  Gt as Dropdown,
141
- bt as DropdownAlignment,
142
- yt as DropdownPosition,
143
- Et as DropdownSize
142
+ Et as DropdownAlignment,
143
+ bt as DropdownPosition,
144
+ yt as DropdownSize
144
145
  };
145
146
  //# sourceMappingURL=Dropdown.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.es.js","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["/* (c) Copyright Frontify Ltd., all rights reserved. */\n\nimport { getDisabledItemIds, getMenuItems, mapToAriaProps } from '@components/ActionMenu/Aria/helper';\nimport { MenuBlock, MenuItemType, SelectMenu } from '@components/Dropdown/SelectMenu/SelectMenu';\nimport { MenuItemStyle, MenuItemTextColorState, menuItemTextColorRecord } from '@components/MenuItem';\nimport { MenuItemContent, MenuItemContentSize } from '@components/MenuItem/MenuItemContent';\nimport { Trigger, TriggerSize } from '@components/Trigger/Trigger';\nimport { useMemoizedId } from '@hooks/useMemoizedId';\nimport { useButton } from '@react-aria/button';\nimport { FocusScope, useFocusRing } from '@react-aria/focus';\nimport { DismissButton, useOverlay } from '@react-aria/overlays';\nimport { HiddenSelect, useSelect } from '@react-aria/select';\nimport { mergeProps } from '@react-aria/utils';\nimport { useSelectState } from '@react-stately/select';\nimport { merge } from '@utilities/merge';\nimport { AnimatePresence, motion } from 'framer-motion';\nimport React, { FC, ReactElement, useEffect, useRef } from 'react';\nimport { DEFAULT_DROPDOWN_MAX_HEIGHT, useDropdownAutoHeight } from './useDropdownAutoHeight';\nimport { Validation } from '@utilities/validation';\nimport { LoadingCircle, LoadingCircleSize } from '@components/LoadingCircle';\nimport { createPortal } from 'react-dom';\nimport { usePopper } from 'react-popper';\nimport { VariationPlacement } from '@popperjs/core';\n\nexport enum DropdownSize {\n Small = 'Small',\n Large = 'Large',\n}\n\nexport enum DropdownAlignment {\n Start = 'Start',\n End = 'End',\n}\n\nexport enum DropdownPosition {\n Top = 'Top',\n Bottom = 'Bottom',\n}\n\nexport type DropdownProps = {\n id?: string;\n menuBlocks: MenuBlock[];\n onChange: (id?: string | number) => void;\n activeItemId?: string | number;\n placeholder?: string;\n size?: DropdownSize;\n disabled?: boolean;\n clearable?: boolean;\n ariaLabel?: string;\n decorator?: ReactElement;\n autoResize?: boolean;\n validation?: Validation;\n alignment?: DropdownAlignment;\n position?: DropdownPosition;\n};\n\nconst getActiveItem = (blocks: MenuBlock[], activeId: string | number): MenuItemType | null => {\n const disabledItems = getDisabledItemIds(getMenuItems(blocks));\n if (disabledItems.has(activeId)) {\n return null;\n }\n\n return (\n blocks\n .map(({ menuItems }) => menuItems)\n .flat()\n .find(({ id }) => id.toString() === activeId?.toString()) || null\n );\n};\n\nexport const Dropdown: FC<DropdownProps> = ({\n id: propId,\n menuBlocks,\n onChange,\n activeItemId,\n placeholder = 'Select item',\n size = DropdownSize.Small,\n disabled = false,\n clearable = false,\n ariaLabel = 'Dropdown',\n decorator,\n autoResize = true,\n validation = Validation.Default,\n alignment = DropdownAlignment.Start,\n position = DropdownPosition.Bottom,\n}) => {\n const activeItem = !!activeItemId ? getActiveItem(menuBlocks, activeItemId) : null;\n const props = mapToAriaProps(ariaLabel, menuBlocks);\n const state = useSelectState({\n ...props,\n defaultSelectedKey: activeItemId,\n onSelectionChange: (key) => onChange(key),\n disabledKeys: getDisabledItemIds(getMenuItems(menuBlocks)),\n });\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n\n const { triggerProps, valueProps, menuProps } = useSelect({ ...props, isDisabled: disabled }, state, triggerRef);\n\n const { buttonProps } = useButton({ ...triggerProps, isDisabled: disabled }, triggerRef);\n const { isOpen } = state;\n const { isFocusVisible, focusProps } = useFocusRing();\n const overlayRef = useRef<HTMLDivElement | null>(null);\n const { overlayProps } = useOverlay(\n { isOpen, onClose: () => state.close(), shouldCloseOnBlur: true, isDismissable: true },\n overlayRef,\n );\n\n useEffect(() => {\n if (state.disabledKeys.has(activeItemId as string)) {\n return;\n }\n\n state.setSelectedKey(activeItemId as string);\n }, [activeItemId]);\n\n const { maxHeight } = useDropdownAutoHeight(triggerRef, { isOpen, autoResize });\n\n const heightIsReady = !autoResize || maxHeight !== DEFAULT_DROPDOWN_MAX_HEIGHT;\n\n const enabledTextColorState = activeItem ? MenuItemTextColorState.Active : MenuItemTextColorState.Default;\n const textState = disabled ? MenuItemTextColorState.Disabled : enabledTextColorState;\n\n const textColorClass = activeItem\n ? menuItemTextColorRecord[activeItem.style || MenuItemStyle.Primary][textState]\n : 'tw-text-black-60';\n\n const onClear = clearable\n ? () => {\n state.setSelectedKey('');\n const first = state.collection.getFirstKey();\n if (first) {\n state.selectionManager.setFocusedKey(first);\n }\n }\n : undefined;\n\n const showClear = !!activeItem && !!onClear;\n const dropdownRef = useRef<HTMLDivElement | null>(null);\n\n const placementMap: Record<string, VariationPlacement> = {\n ['Top-Start']: 'top-start',\n ['Top-End']: 'top-end',\n ['Bottom-Start']: 'bottom-start',\n ['Bottom-End']: 'bottom-end',\n };\n const popperInstance = usePopper(triggerRef?.current, dropdownRef.current, {\n placement: placementMap[`${position}-${alignment}`],\n modifiers: [\n {\n name: 'offset',\n options: {\n offset: [0, 8],\n },\n },\n {\n name: 'flip',\n enabled: false,\n },\n ],\n });\n\n return (\n <div className=\"tw-relative tw-w-full tw-font-sans tw-text-s\">\n <Trigger\n disabled={disabled}\n buttonProps={buttonProps}\n isFocusVisible={!disabled && isFocusVisible}\n isOpen={isOpen}\n size={size === DropdownSize.Large ? TriggerSize.Large : TriggerSize.Small}\n onClear={onClear}\n showClear={showClear}\n validation={validation}\n >\n <HiddenSelect state={state} triggerRef={triggerRef} />\n <button\n {...mergeProps(buttonProps, focusProps)}\n id={useMemoizedId(propId)}\n ref={triggerRef}\n data-test-id=\"dropdown-trigger\"\n className={merge([\n 'tw-overflow-hidden tw-flex-auto tw-h-full tw-rounded tw-text-left tw-outline-none',\n size === DropdownSize.Small\n ? 'tw-py-2 tw-pl-3 tw-min-h-[34px]'\n : 'tw-pl-5 tw-py-4 tw-min-h-[60px]',\n showClear ? 'tw-pr-11' : 'tw-pr-7',\n textColorClass,\n ])}\n >\n <MenuItemContent\n ariaProps={valueProps}\n title={activeItem?.title || placeholder}\n decorator={decorator ?? activeItem?.decorator}\n size={size === DropdownSize.Small ? MenuItemContentSize.Small : MenuItemContentSize.Large}\n />\n </button>\n </Trigger>\n {createPortal(\n <AnimatePresence>\n {!disabled && isOpen && heightIsReady && (\n <motion.div\n ref={dropdownRef}\n style={{\n ...popperInstance.styles.popper,\n width: triggerRef.current?.getBoundingClientRect().width,\n minWidth: 'fit-content',\n }}\n {...popperInstance.attributes.popper}\n className=\"tw-absolute tw-p-0 tw-shadow-mid tw-list-none tw-m-0 tw-z-[120000] tw-min-w-full tw-overflow-hidden\"\n key=\"content\"\n initial={{ height: 0 }}\n animate={{ height: 'auto' }}\n transition={{ ease: [0.04, 0.62, 0.23, 0.98], duration: 0.5 }}\n >\n <FocusScope restoreFocus>\n <div\n {...overlayProps}\n ref={overlayRef}\n style={autoResize ? { maxHeight } : {}}\n className=\"tw-flex tw-flex-col\"\n data-test-id=\"dropdown-menu\"\n role=\"dialog\"\n >\n <DismissButton onDismiss={() => close()} />\n <SelectMenu\n ariaProps={menuProps}\n state={state}\n menuBlocks={menuBlocks}\n scrollable\n />\n <DismissButton onDismiss={() => close()} />\n </div>\n </FocusScope>\n </motion.div>\n )}\n </AnimatePresence>,\n document.body,\n )}\n {validation === Validation.Loading && (\n <span className=\"tw-absolute tw-top-[-0.55rem] tw-right-[-0.55rem] tw-bg-white tw-rounded-full tw-p-[2px] tw-border tw-border-black-10\">\n <LoadingCircle size={LoadingCircleSize.ExtraSmall} />\n </span>\n )}\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Dropdown.es.js","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["/* (c) Copyright Frontify Ltd., all rights reserved. */\n\nimport { getDisabledItemIds, getMenuItems, mapToAriaProps } from '@components/ActionMenu/Aria/helper';\nimport { MenuBlock, MenuItemType, SelectMenu } from '@components/Dropdown/SelectMenu/SelectMenu';\nimport { MenuItemStyle, MenuItemTextColorState, menuItemTextColorRecord } from '@components/MenuItem';\nimport { MenuItemContent, MenuItemContentSize } from '@components/MenuItem/MenuItemContent';\nimport { Trigger, TriggerSize } from '@components/Trigger/Trigger';\nimport { useMemoizedId } from '@hooks/useMemoizedId';\nimport { useButton } from '@react-aria/button';\nimport { FocusScope, useFocusRing } from '@react-aria/focus';\nimport { DismissButton, useOverlay } from '@react-aria/overlays';\nimport { HiddenSelect, useSelect } from '@react-aria/select';\nimport { mergeProps } from '@react-aria/utils';\nimport { useSelectState } from '@react-stately/select';\nimport { merge } from '@utilities/merge';\nimport { AnimatePresence, motion } from 'framer-motion';\nimport React, { FC, ReactElement, useEffect, useRef } from 'react';\nimport { DEFAULT_DROPDOWN_MAX_HEIGHT, useDropdownAutoHeight } from './useDropdownAutoHeight';\nimport { Validation } from '@utilities/validation';\nimport { LoadingCircle, LoadingCircleSize } from '@components/LoadingCircle';\nimport { createPortal } from 'react-dom';\nimport { usePopper } from 'react-popper';\nimport { VariationPlacement } from '@popperjs/core';\n\nexport enum DropdownSize {\n Small = 'Small',\n Large = 'Large',\n}\n\nexport enum DropdownAlignment {\n Start = 'Start',\n End = 'End',\n}\n\nexport enum DropdownPosition {\n Top = 'Top',\n Bottom = 'Bottom',\n}\n\nexport type DropdownProps = {\n id?: string;\n menuBlocks: MenuBlock[];\n onChange: (id?: string | number) => void;\n activeItemId?: string | number;\n placeholder?: string;\n size?: DropdownSize;\n disabled?: boolean;\n clearable?: boolean;\n ariaLabel?: string;\n decorator?: ReactElement;\n autoResize?: boolean;\n validation?: Validation;\n alignment?: DropdownAlignment;\n position?: DropdownPosition;\n};\n\nconst getActiveItem = (blocks: MenuBlock[], activeId: string | number): MenuItemType | null => {\n const disabledItems = getDisabledItemIds(getMenuItems(blocks));\n if (disabledItems.has(activeId)) {\n return null;\n }\n\n return (\n blocks\n .map(({ menuItems }) => menuItems)\n .flat()\n .find(({ id }) => id.toString() === activeId?.toString()) || null\n );\n};\n\nexport const Dropdown: FC<DropdownProps> = ({\n id: propId,\n menuBlocks,\n onChange,\n activeItemId,\n placeholder = 'Select item',\n size = DropdownSize.Small,\n disabled = false,\n clearable = false,\n ariaLabel = 'Dropdown',\n decorator,\n autoResize = true,\n validation = Validation.Default,\n alignment = DropdownAlignment.Start,\n position = DropdownPosition.Bottom,\n}) => {\n const activeItem = !!activeItemId ? getActiveItem(menuBlocks, activeItemId) : null;\n const props = mapToAriaProps(ariaLabel, menuBlocks);\n const state = useSelectState({\n ...props,\n defaultSelectedKey: activeItemId,\n onSelectionChange: (key) => onChange(key),\n disabledKeys: getDisabledItemIds(getMenuItems(menuBlocks)),\n });\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n\n const { triggerProps, valueProps, menuProps } = useSelect({ ...props, isDisabled: disabled }, state, triggerRef);\n\n const { buttonProps } = useButton({ ...triggerProps, isDisabled: disabled }, triggerRef);\n const { isOpen } = state;\n const { isFocusVisible, focusProps } = useFocusRing();\n const overlayRef = useRef<HTMLDivElement | null>(null);\n const { overlayProps } = useOverlay(\n { isOpen, onClose: () => state.close(), shouldCloseOnBlur: true, isDismissable: true },\n overlayRef,\n );\n\n useEffect(() => {\n if (state.disabledKeys.has(activeItemId as string)) {\n return;\n }\n\n state.setSelectedKey(activeItemId as string);\n }, [activeItemId]);\n\n const { maxHeight } = useDropdownAutoHeight(triggerRef, { isOpen, autoResize });\n\n const heightIsReady = !autoResize || maxHeight !== DEFAULT_DROPDOWN_MAX_HEIGHT;\n\n const enabledTextColorState = activeItem ? MenuItemTextColorState.Active : MenuItemTextColorState.Default;\n const textState = disabled ? MenuItemTextColorState.Disabled : enabledTextColorState;\n\n const textColorClass = activeItem\n ? menuItemTextColorRecord[activeItem.style || MenuItemStyle.Primary][textState]\n : 'tw-text-black-60';\n\n const onClear = clearable\n ? () => {\n state.setSelectedKey('');\n const first = state.collection.getFirstKey();\n if (first) {\n state.selectionManager.setFocusedKey(first);\n }\n }\n : undefined;\n\n const showClear = !!activeItem && !!onClear;\n const dropdownRef = useRef<HTMLDivElement | null>(null);\n\n const placementMap: Record<string, VariationPlacement> = {\n ['Top-Start']: 'top-start',\n ['Top-End']: 'top-end',\n ['Bottom-Start']: 'bottom-start',\n ['Bottom-End']: 'bottom-end',\n };\n const popperInstance = usePopper(triggerRef?.current, dropdownRef.current, {\n placement: placementMap[`${position}-${alignment}`],\n strategy: 'fixed',\n modifiers: [\n {\n name: 'offset',\n options: {\n offset: [0, 8],\n },\n },\n {\n name: 'flip',\n enabled: false,\n },\n ],\n });\n\n return (\n <div className=\"tw-relative tw-w-full tw-font-sans tw-text-s\">\n <Trigger\n disabled={disabled}\n buttonProps={buttonProps}\n isFocusVisible={!disabled && isFocusVisible}\n isOpen={isOpen}\n size={size === DropdownSize.Large ? TriggerSize.Large : TriggerSize.Small}\n onClear={onClear}\n showClear={showClear}\n validation={validation}\n >\n <HiddenSelect state={state} triggerRef={triggerRef} />\n <button\n {...mergeProps(buttonProps, focusProps)}\n id={useMemoizedId(propId)}\n ref={triggerRef}\n data-test-id=\"dropdown-trigger\"\n className={merge([\n 'tw-overflow-hidden tw-flex-auto tw-h-full tw-rounded tw-text-left tw-outline-none',\n size === DropdownSize.Small\n ? 'tw-py-2 tw-pl-3 tw-min-h-[34px]'\n : 'tw-pl-5 tw-py-4 tw-min-h-[60px]',\n showClear ? 'tw-pr-11' : 'tw-pr-7',\n textColorClass,\n ])}\n >\n <MenuItemContent\n ariaProps={valueProps}\n title={activeItem?.title || placeholder}\n decorator={decorator ?? activeItem?.decorator}\n size={size === DropdownSize.Small ? MenuItemContentSize.Small : MenuItemContentSize.Large}\n />\n </button>\n </Trigger>\n {createPortal(\n <AnimatePresence>\n {!disabled && isOpen && heightIsReady && (\n <motion.div\n ref={dropdownRef}\n style={{\n ...popperInstance.styles.popper,\n width: triggerRef.current?.getBoundingClientRect().width,\n minWidth: 'fit-content',\n }}\n {...popperInstance.attributes.popper}\n className=\"tw-absolute tw-p-0 tw-shadow-mid tw-list-none tw-m-0 tw-z-[120000] tw-min-w-full tw-overflow-hidden\"\n key=\"content\"\n initial={{ height: 0 }}\n animate={{ height: 'auto' }}\n transition={{ ease: [0.04, 0.62, 0.23, 0.98], duration: 0.5 }}\n >\n <FocusScope restoreFocus>\n <div\n {...overlayProps}\n ref={overlayRef}\n style={autoResize ? { maxHeight } : {}}\n className=\"tw-flex tw-flex-col\"\n data-test-id=\"dropdown-menu\"\n role=\"dialog\"\n >\n <DismissButton onDismiss={() => close()} />\n <SelectMenu\n ariaProps={menuProps}\n state={state}\n menuBlocks={menuBlocks}\n scrollable\n />\n <DismissButton onDismiss={() => close()} />\n </div>\n </FocusScope>\n </motion.div>\n )}\n </AnimatePresence>,\n document.body,\n )}\n {validation === Validation.Loading && (\n <span className=\"tw-absolute tw-top-[-0.55rem] tw-right-[-0.55rem] tw-bg-white tw-rounded-full tw-p-[2px] tw-border tw-border-black-10\">\n <LoadingCircle size={LoadingCircleSize.ExtraSmall} />\n </span>\n )}\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -2,9 +2,9 @@ import { Button as I, ButtonStyle as _, ButtonSize as P } from "../Button/Button
2
2
  import { IconSize as $ } from "../../foundation/Icon/IconSize.es.js";
3
3
  import { useLink as re } from "@react-aria/link";
4
4
  import { FOCUS_VISIBLE_STYLE as oe } from "../../utilities/focusStyle.es.js";
5
- import { merge as m } from "../../utilities/merge.es.js";
5
+ import { merge as d } from "../../utilities/merge.es.js";
6
6
  import e, { useRef as f, useMemo as ae, useState as V, useCallback as E, cloneElement as x } from "react";
7
- import { BrightHeader as se, brightHeaderArrowBackgroundColors as B } from "./BrightHeader.es.js";
7
+ import { BrightHeader as se, brightHeaderArrowBackgroundColors as k } from "./BrightHeader.es.js";
8
8
  import { usePopper as le } from "react-popper";
9
9
  import { createPortal as ce } from "react-dom";
10
10
  const Y = {
@@ -15,7 +15,7 @@ const Y = {
15
15
  large: "tw-pb-4"
16
16
  };
17
17
  var ne = /* @__PURE__ */ ((t) => (t.Top = "Top", t.Right = "Right", t.Bottom = "Bottom", t.Left = "Left", t))(ne || {}), we = /* @__PURE__ */ ((t) => (t.Start = "Start", t.Middle = "Middle", t.End = "End", t))(we || {});
18
- const me = {
18
+ const de = {
19
19
  ["Top-Start"]: "top-start",
20
20
  ["Top-End"]: "top-end",
21
21
  ["Bottom-Start"]: "bottom-start",
@@ -28,48 +28,49 @@ const me = {
28
28
  ["Right-Middle"]: "right",
29
29
  ["Bottom-Middle"]: "bottom",
30
30
  ["Left-Middle"]: "left"
31
- }, de = (t, a, w) => {
31
+ }, me = (t, a, w) => {
32
32
  switch (!0) {
33
33
  case t.toString().includes("Top".toLowerCase()):
34
34
  return "before:tw-border-t-0 before:tw-border-l-0 tw-bottom-[-6px] before:tw-bg-black-100 before:dark:tw-bg-white";
35
35
  case t.toString().includes("Right".toLowerCase()):
36
- return m([
36
+ return d([
37
37
  "before:tw-border-t-0 before:tw-border-r-0 tw-left-[-6px]",
38
- a && w === "Start" ? B[a] : "before:tw-bg-black-100 before:dark:tw-bg-white"
38
+ a && w === "Start" ? k[a] : "before:tw-bg-black-100 before:dark:tw-bg-white"
39
39
  ]);
40
40
  case t.toString().includes("Bottom".toLowerCase()):
41
- return m([
41
+ return d([
42
42
  "before:tw-border-b-0 before:tw-border-r-0 tw-top-[-6px]",
43
- a ? B[a] : "before:tw-bg-black-100 before:dark:tw-bg-white"
43
+ a ? k[a] : "before:tw-bg-black-100 before:dark:tw-bg-white"
44
44
  ]);
45
45
  case t.toString().includes("Left".toLowerCase()):
46
- return m([
46
+ return d([
47
47
  "before:tw-border-b-0 before:tw-border-l-0 tw-right-[-6px]",
48
- a && w === "Start" ? B[a] : "before:tw-bg-black-100 before:dark:tw-bg-white"
48
+ a && w === "Start" ? k[a] : "before:tw-bg-black-100 before:dark:tw-bg-white"
49
49
  ]);
50
50
  default:
51
51
  return "before:tw-border-b-0 before:tw-border-r-0 tw-top-[-6px] before:tw-bg-black-100 before:dark:tw-bg-white";
52
52
  }
53
- }, Be = ({
53
+ }, ke = ({
54
54
  content: t,
55
55
  tooltipIcon: a,
56
56
  heading: w,
57
57
  headingIcon: u,
58
58
  linkUrl: l,
59
59
  linkLabel: S,
60
- brightHeader: d,
60
+ brightHeader: m,
61
61
  buttons: r,
62
62
  children: q,
63
- position: k = "Bottom",
63
+ position: B = "Top",
64
64
  alignment: g = "Middle",
65
65
  withArrow: b,
66
66
  flip: D = !0,
67
- triggerElement: M,
67
+ triggerElement: y,
68
68
  hoverDelay: G = 200
69
69
  }) => {
70
- var z, T;
71
- const o = f(null), y = f(null), { linkProps: J } = re({}, y), K = ae(() => l || d || r || w || u, [l, d, r, w, u]), Q = me[`${k}-${g}`], s = f(null), p = f(null), [W, X] = V(null), Z = b ? 10 : 5, i = le(o == null ? void 0 : o.current, s.current, {
70
+ var T, z;
71
+ const o = f(null), M = f(null), { linkProps: J } = re({}, M), K = ae(() => l || m || r || w || u, [l, m, r, w, u]), Q = de[`${B}-${g}`], s = f(null), p = f(null), [W, X] = V(null), Z = b ? 10 : 5, i = le(o == null ? void 0 : o.current, s.current, {
72
72
  placement: Q,
73
+ strategy: "fixed",
73
74
  modifiers: [
74
75
  {
75
76
  name: "arrow",
@@ -88,7 +89,7 @@ const me = {
88
89
  enabled: D
89
90
  }
90
91
  ]
91
- }), R = (T = (z = i.state) == null ? void 0 : z.placement) != null ? T : k, A = de(R, d, g), [H, c] = V(!1), h = f(null), U = E(() => {
92
+ }), R = (z = (T = i.state) == null ? void 0 : T.placement) != null ? z : B, A = me(R, m, g), [H, c] = V(!1), h = f(null), U = E(() => {
92
93
  h.current && clearTimeout(h.current), c(!0);
93
94
  }, [o == null ? void 0 : o.current]), L = E(() => {
94
95
  h.current = setTimeout(() => c(!1), G);
@@ -105,7 +106,7 @@ const me = {
105
106
  return /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement("div", {
106
107
  ...te,
107
108
  ref: p
108
- }, M && x(M, {
109
+ }, y && x(y, {
109
110
  ref: o
110
111
  })), ce(/* @__PURE__ */ e.createElement("div", null, H && /* @__PURE__ */ e.createElement("div", {
111
112
  ref: s,
@@ -117,10 +118,10 @@ const me = {
117
118
  onFocus: () => c(!0),
118
119
  onMouseOver: (n) => N(n.nativeEvent),
119
120
  onMouseLeave: L
120
- }, d && /* @__PURE__ */ e.createElement(se, {
121
- headerStyle: d
121
+ }, m && /* @__PURE__ */ e.createElement(se, {
122
+ headerStyle: m
122
123
  }), /* @__PURE__ */ e.createElement("div", {
123
- className: m([
124
+ className: d([
124
125
  "tw-px-4",
125
126
  K ? Y.small : Y.large,
126
127
  l ? j.small : j.large
@@ -138,11 +139,11 @@ const me = {
138
139
  }, t)), l && /* @__PURE__ */ e.createElement("a", {
139
140
  ...J,
140
141
  "data-test-id": "tooltip-link",
141
- ref: y,
142
+ ref: M,
142
143
  href: l,
143
144
  target: "_blank",
144
145
  rel: "noopener noreferrer",
145
- className: m([
146
+ className: d([
146
147
  "tw-text-xs tw-text-black-40 dark:tw-text-black-80 tw-underline tw-mt-1",
147
148
  oe
148
149
  ]),
@@ -168,14 +169,14 @@ const me = {
168
169
  "data-popper-arrow": b,
169
170
  ref: X,
170
171
  style: i.styles.arrow,
171
- className: m([
172
+ className: d([
172
173
  b && "tw-popper-arrow tw-absolute tw-w-3 tw-h-3 tw-pointer-events-none before:tw-absolute before:tw-w-3 before:tw-h-3 before:tw-rotate-45 before:tw-border before:tw-border-line",
173
174
  b && A
174
175
  ])
175
176
  })), q)), document.body));
176
177
  };
177
178
  export {
178
- Be as Tooltip,
179
+ ke as Tooltip,
179
180
  we as TooltipAlignment,
180
181
  ne as TooltipPosition
181
182
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.es.js","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["/* (c) Copyright Frontify Ltd., all rights reserved. */\n\nimport { Button, ButtonSize, ButtonStyle } from '@components/Button/Button';\nimport { IconSize } from '@foundation/Icon/IconSize';\nimport { useLink } from '@react-aria/link';\nimport { FOCUS_VISIBLE_STYLE } from '@utilities/focusStyle';\nimport { merge } from '@utilities/merge';\nimport React, {\n HTMLAttributes,\n PropsWithChildren,\n ReactChild,\n ReactElement,\n ReactNode,\n cloneElement,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { BrightHeader, BrightHeaderStyle, brightHeaderArrowBackgroundColors } from './BrightHeader';\nimport { usePopper } from 'react-popper';\nimport { createPortal } from 'react-dom';\nimport { Placement } from '@popperjs/core';\n\nexport type TooltipButton = {\n label: string;\n action: () => void;\n};\n\nexport type TooltipProps = PropsWithChildren<{\n triggerElement?: ReactElement;\n content: ReactNode;\n tooltipIcon?: ReactElement;\n heading?: ReactNode;\n headingIcon?: ReactElement;\n linkUrl?: string;\n linkLabel?: string;\n brightHeader?: BrightHeaderStyle;\n buttons?: [TooltipButton, TooltipButton] | [TooltipButton];\n children?: ReactChild;\n position?: TooltipPosition;\n alignment?: TooltipAlignment;\n flip?: boolean;\n withArrow?: boolean;\n hoverDelay?: number;\n}>;\n\n/**\n * This is a temporary workaround because for some yet unknown reasons `tailwindcss` in clarify purges the `tw-pb-3.5` and `tw-pt-3.5` class.\n */\nconst paddingsTop = {\n small: 'tw-pt-3.5',\n large: 'tw-pt-4',\n};\n\nconst paddingsBottom = {\n small: 'tw-pb-3.5',\n large: 'tw-pb-4',\n};\n\nexport enum TooltipPosition {\n Top = 'Top',\n Right = 'Right',\n Bottom = 'Bottom',\n Left = 'Left',\n}\n\nexport enum TooltipAlignment {\n Start = 'Start',\n Middle = 'Middle',\n End = 'End',\n}\n\nconst placementMap: Record<`${TooltipPosition}-${TooltipAlignment}`, Placement> = {\n ['Top-Start']: 'top-start',\n ['Top-End']: 'top-end',\n ['Bottom-Start']: 'bottom-start',\n ['Bottom-End']: 'bottom-end',\n ['Left-Start']: 'left-start',\n ['Left-End']: 'left-end',\n ['Right-Start']: 'right-start',\n ['Right-End']: 'right-end',\n ['Top-Middle']: 'top',\n ['Right-Middle']: 'right',\n ['Bottom-Middle']: 'bottom',\n ['Left-Middle']: 'left',\n};\n\nconst getArrowClasses = (currentPlacement: string, brightHeader: BrightHeaderStyle | undefined, alignment: string) => {\n switch (true) {\n case currentPlacement.toString().includes(TooltipPosition.Top.toLowerCase()):\n return 'before:tw-border-t-0 before:tw-border-l-0 tw-bottom-[-6px] before:tw-bg-black-100 before:dark:tw-bg-white';\n case currentPlacement.toString().includes(TooltipPosition.Right.toLowerCase()):\n return merge([\n 'before:tw-border-t-0 before:tw-border-r-0 tw-left-[-6px]',\n brightHeader && alignment === TooltipAlignment.Start\n ? brightHeaderArrowBackgroundColors[brightHeader]\n : 'before:tw-bg-black-100 before:dark:tw-bg-white',\n ]);\n case currentPlacement.toString().includes(TooltipPosition.Bottom.toLowerCase()):\n return merge([\n 'before:tw-border-b-0 before:tw-border-r-0 tw-top-[-6px]',\n brightHeader\n ? brightHeaderArrowBackgroundColors[brightHeader]\n : 'before:tw-bg-black-100 before:dark:tw-bg-white',\n ]);\n case currentPlacement.toString().includes(TooltipPosition.Left.toLowerCase()):\n return merge([\n 'before:tw-border-b-0 before:tw-border-l-0 tw-right-[-6px]',\n brightHeader && alignment === TooltipAlignment.Start\n ? brightHeaderArrowBackgroundColors[brightHeader]\n : 'before:tw-bg-black-100 before:dark:tw-bg-white',\n ]);\n default:\n return 'before:tw-border-b-0 before:tw-border-r-0 tw-top-[-6px] before:tw-bg-black-100 before:dark:tw-bg-white';\n }\n};\n\nexport const Tooltip = ({\n content,\n tooltipIcon,\n heading,\n headingIcon,\n linkUrl,\n linkLabel,\n brightHeader,\n buttons,\n children,\n position = TooltipPosition.Bottom,\n alignment = TooltipAlignment.Middle,\n withArrow,\n flip = true,\n triggerElement,\n hoverDelay = 200,\n}: TooltipProps) => {\n const triggerRefElement = useRef<HTMLElement | HTMLDivElement | HTMLButtonElement | null>(null);\n const linkRef = useRef<HTMLAnchorElement | null>(null);\n const { linkProps } = useLink({}, linkRef);\n const hasLargePaddingTop = useMemo(\n () => linkUrl || brightHeader || buttons || heading || headingIcon,\n [linkUrl, brightHeader, buttons, heading, headingIcon],\n );\n\n const placement = placementMap[`${position}-${alignment}`];\n const tooltipContainerRef = useRef<HTMLDivElement | null>(null);\n const triggerElementContainerRef = useRef<HTMLDivElement | null>(null);\n const [arrowElement, setArrowElement] = useState<HTMLDivElement | null>(null);\n\n const tooltipOffset = withArrow ? 10 : 5;\n const popperInstance = usePopper(triggerRefElement?.current, tooltipContainerRef.current, {\n placement,\n modifiers: [\n {\n name: 'arrow',\n options: {\n element: arrowElement,\n },\n },\n {\n name: 'offset',\n options: {\n offset: [0, tooltipOffset],\n },\n },\n {\n name: 'flip',\n enabled: flip,\n },\n ],\n });\n\n const currentPlacement = popperInstance.state?.placement ?? position;\n const arrowStyling = getArrowClasses(currentPlacement, brightHeader, alignment);\n const [isOpen, setIsOpen] = useState(false);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleShowTooltipOnHover = useCallback(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n setIsOpen(true);\n }, [triggerRefElement?.current]);\n\n const handleHideTooltipOnHover = useCallback(() => {\n timeoutRef.current = setTimeout(() => setIsOpen(false), hoverDelay);\n }, [triggerRefElement?.current, tooltipContainerRef?.current]);\n\n const checkIfHovered = useCallback(\n (event) => {\n const hoveredElement = event.path ?? event.composedPath?.();\n const hoverSources = [triggerRefElement, triggerElementContainerRef, tooltipContainerRef];\n\n if (hoveredElement && hoverSources.some((el) => hoveredElement.includes(el?.current))) {\n handleShowTooltipOnHover();\n }\n },\n [triggerRefElement?.current, tooltipContainerRef?.current, triggerElementContainerRef?.current],\n );\n\n const hasInteractiveElements = !!(buttons?.length || linkUrl?.length);\n const triggerProps: HTMLAttributes<HTMLElement> = {\n onMouseOver: (event) => checkIfHovered(event.nativeEvent),\n onMouseLeave: handleHideTooltipOnHover,\n onFocus: () => setIsOpen(true),\n onBlur: () => (!hasInteractiveElements ? setIsOpen(false) : null),\n };\n\n return (\n <>\n <div {...triggerProps} ref={triggerElementContainerRef}>\n {triggerElement &&\n cloneElement(triggerElement, {\n ref: triggerRefElement,\n })}\n </div>\n {createPortal(\n <div>\n {isOpen && (\n <div\n ref={tooltipContainerRef}\n className=\"tw-popper-container tw-inline-block tw-max-w-[200px] tw-bg-black-100 dark:tw-bg-white tw-rounded-md tw-shadow-mid tw-text-white dark:tw-text-black-100 tw-z-[120000]\"\n data-test-id=\"tooltip\"\n role=\"tooltip\"\n style={popperInstance.styles.popper}\n {...popperInstance.attributes.popper}\n onFocus={() => setIsOpen(true)}\n onMouseOver={(event) => checkIfHovered(event.nativeEvent)}\n onMouseLeave={handleHideTooltipOnHover}\n >\n {brightHeader && <BrightHeader headerStyle={brightHeader} />}\n <div\n className={merge([\n 'tw-px-4',\n hasLargePaddingTop ? paddingsTop.small : paddingsTop.large,\n linkUrl ? paddingsBottom.small : paddingsBottom.large,\n ])}\n >\n {heading && (\n <h4 className=\"tw-flex tw-text-m tw-font-bold tw-mb-1\">\n {headingIcon && (\n <span className=\"tw-mr-1.5\">\n {cloneElement(headingIcon, { size: IconSize.Size20 })}\n </span>\n )}\n {heading}\n </h4>\n )}\n <div className=\"tw-flex\">\n {tooltipIcon && (\n <span className=\"tw-shrink-0 tw-mr-1\">\n {cloneElement(tooltipIcon, { size: IconSize.Size16 })}\n </span>\n )}\n <p className=\"tw-text-s\">{content}</p>\n </div>\n {linkUrl && (\n <a\n {...linkProps}\n data-test-id=\"tooltip-link\"\n ref={linkRef}\n href={linkUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={merge([\n 'tw-text-xs tw-text-black-40 dark:tw-text-black-80 tw-underline tw-mt-1',\n FOCUS_VISIBLE_STYLE,\n ])}\n onBlur={() => (buttons && buttons.length > 0 ? null : setIsOpen(false))}\n >\n {linkLabel ?? 'Click here to learn more.'}\n </a>\n )}\n {buttons && (\n <div className=\"tw-flex tw-flex-row-reverse tw-gap-x-1 tw-mt-4\">\n {buttons.length > 0 && (\n <div\n onBlur={() => (buttons && buttons.length < 2 ? setIsOpen(false) : null)}\n >\n <Button\n style={ButtonStyle.Primary}\n size={ButtonSize.Small}\n inverted\n onClick={buttons[0].action}\n >\n {buttons[0].label}\n </Button>\n </div>\n )}\n {buttons.length === 2 && (\n <div onBlur={() => setIsOpen(false)}>\n <Button\n style={ButtonStyle.Secondary}\n size={ButtonSize.Small}\n inverted\n onClick={buttons[1].action}\n >\n {buttons[1].label}\n </Button>\n </div>\n )}\n </div>\n )}\n <div\n data-test-id=\"popover-arrow\"\n data-popper-arrow={withArrow}\n ref={setArrowElement}\n style={popperInstance.styles.arrow}\n className={merge([\n withArrow &&\n 'tw-popper-arrow tw-absolute tw-w-3 tw-h-3 tw-pointer-events-none before:tw-absolute before:tw-w-3 before:tw-h-3 before:tw-rotate-45 before:tw-border before:tw-border-line',\n withArrow && arrowStyling,\n ])}\n />\n </div>\n {children}\n </div>\n )}\n </div>,\n document.body,\n )}\n </>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Tooltip.es.js","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["/* (c) Copyright Frontify Ltd., all rights reserved. */\n\nimport { Button, ButtonSize, ButtonStyle } from '@components/Button/Button';\nimport { IconSize } from '@foundation/Icon/IconSize';\nimport { useLink } from '@react-aria/link';\nimport { FOCUS_VISIBLE_STYLE } from '@utilities/focusStyle';\nimport { merge } from '@utilities/merge';\nimport React, {\n HTMLAttributes,\n PropsWithChildren,\n ReactChild,\n ReactElement,\n ReactNode,\n cloneElement,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { BrightHeader, BrightHeaderStyle, brightHeaderArrowBackgroundColors } from './BrightHeader';\nimport { usePopper } from 'react-popper';\nimport { createPortal } from 'react-dom';\nimport { Placement } from '@popperjs/core';\n\nexport type TooltipButton = {\n label: string;\n action: () => void;\n};\n\nexport type TooltipProps = PropsWithChildren<{\n triggerElement?: ReactElement;\n content: ReactNode;\n tooltipIcon?: ReactElement;\n heading?: ReactNode;\n headingIcon?: ReactElement;\n linkUrl?: string;\n linkLabel?: string;\n brightHeader?: BrightHeaderStyle;\n buttons?: [TooltipButton, TooltipButton] | [TooltipButton];\n children?: ReactChild;\n position?: TooltipPosition;\n alignment?: TooltipAlignment;\n flip?: boolean;\n withArrow?: boolean;\n hoverDelay?: number;\n}>;\n\n/**\n * This is a temporary workaround because for some yet unknown reasons `tailwindcss` in clarify purges the `tw-pb-3.5` and `tw-pt-3.5` class.\n */\nconst paddingsTop = {\n small: 'tw-pt-3.5',\n large: 'tw-pt-4',\n};\n\nconst paddingsBottom = {\n small: 'tw-pb-3.5',\n large: 'tw-pb-4',\n};\n\nexport enum TooltipPosition {\n Top = 'Top',\n Right = 'Right',\n Bottom = 'Bottom',\n Left = 'Left',\n}\n\nexport enum TooltipAlignment {\n Start = 'Start',\n Middle = 'Middle',\n End = 'End',\n}\n\nconst placementMap: Record<`${TooltipPosition}-${TooltipAlignment}`, Placement> = {\n ['Top-Start']: 'top-start',\n ['Top-End']: 'top-end',\n ['Bottom-Start']: 'bottom-start',\n ['Bottom-End']: 'bottom-end',\n ['Left-Start']: 'left-start',\n ['Left-End']: 'left-end',\n ['Right-Start']: 'right-start',\n ['Right-End']: 'right-end',\n ['Top-Middle']: 'top',\n ['Right-Middle']: 'right',\n ['Bottom-Middle']: 'bottom',\n ['Left-Middle']: 'left',\n};\n\nconst getArrowClasses = (currentPlacement: string, brightHeader: BrightHeaderStyle | undefined, alignment: string) => {\n switch (true) {\n case currentPlacement.toString().includes(TooltipPosition.Top.toLowerCase()):\n return 'before:tw-border-t-0 before:tw-border-l-0 tw-bottom-[-6px] before:tw-bg-black-100 before:dark:tw-bg-white';\n case currentPlacement.toString().includes(TooltipPosition.Right.toLowerCase()):\n return merge([\n 'before:tw-border-t-0 before:tw-border-r-0 tw-left-[-6px]',\n brightHeader && alignment === TooltipAlignment.Start\n ? brightHeaderArrowBackgroundColors[brightHeader]\n : 'before:tw-bg-black-100 before:dark:tw-bg-white',\n ]);\n case currentPlacement.toString().includes(TooltipPosition.Bottom.toLowerCase()):\n return merge([\n 'before:tw-border-b-0 before:tw-border-r-0 tw-top-[-6px]',\n brightHeader\n ? brightHeaderArrowBackgroundColors[brightHeader]\n : 'before:tw-bg-black-100 before:dark:tw-bg-white',\n ]);\n case currentPlacement.toString().includes(TooltipPosition.Left.toLowerCase()):\n return merge([\n 'before:tw-border-b-0 before:tw-border-l-0 tw-right-[-6px]',\n brightHeader && alignment === TooltipAlignment.Start\n ? brightHeaderArrowBackgroundColors[brightHeader]\n : 'before:tw-bg-black-100 before:dark:tw-bg-white',\n ]);\n default:\n return 'before:tw-border-b-0 before:tw-border-r-0 tw-top-[-6px] before:tw-bg-black-100 before:dark:tw-bg-white';\n }\n};\n\nexport const Tooltip = ({\n content,\n tooltipIcon,\n heading,\n headingIcon,\n linkUrl,\n linkLabel,\n brightHeader,\n buttons,\n children,\n position = TooltipPosition.Top,\n alignment = TooltipAlignment.Middle,\n withArrow,\n flip = true,\n triggerElement,\n hoverDelay = 200,\n}: TooltipProps) => {\n const triggerRefElement = useRef<HTMLElement | HTMLDivElement | HTMLButtonElement | null>(null);\n const linkRef = useRef<HTMLAnchorElement | null>(null);\n const { linkProps } = useLink({}, linkRef);\n const hasLargePaddingTop = useMemo(\n () => linkUrl || brightHeader || buttons || heading || headingIcon,\n [linkUrl, brightHeader, buttons, heading, headingIcon],\n );\n\n const placement = placementMap[`${position}-${alignment}`];\n const tooltipContainerRef = useRef<HTMLDivElement | null>(null);\n const triggerElementContainerRef = useRef<HTMLDivElement | null>(null);\n const [arrowElement, setArrowElement] = useState<HTMLDivElement | null>(null);\n\n const tooltipOffset = withArrow ? 10 : 5;\n const popperInstance = usePopper(triggerRefElement?.current, tooltipContainerRef.current, {\n placement,\n strategy: 'fixed',\n modifiers: [\n {\n name: 'arrow',\n options: {\n element: arrowElement,\n },\n },\n {\n name: 'offset',\n options: {\n offset: [0, tooltipOffset],\n },\n },\n {\n name: 'flip',\n enabled: flip,\n },\n ],\n });\n\n const currentPlacement = popperInstance.state?.placement ?? position;\n const arrowStyling = getArrowClasses(currentPlacement, brightHeader, alignment);\n const [isOpen, setIsOpen] = useState(false);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleShowTooltipOnHover = useCallback(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n setIsOpen(true);\n }, [triggerRefElement?.current]);\n\n const handleHideTooltipOnHover = useCallback(() => {\n timeoutRef.current = setTimeout(() => setIsOpen(false), hoverDelay);\n }, [triggerRefElement?.current, tooltipContainerRef?.current]);\n\n const checkIfHovered = useCallback(\n (event) => {\n const hoveredElement = event.path ?? event.composedPath?.();\n const hoverSources = [triggerRefElement, triggerElementContainerRef, tooltipContainerRef];\n\n if (hoveredElement && hoverSources.some((el) => hoveredElement.includes(el?.current))) {\n handleShowTooltipOnHover();\n }\n },\n [triggerRefElement?.current, tooltipContainerRef?.current, triggerElementContainerRef?.current],\n );\n\n const hasInteractiveElements = !!(buttons?.length || linkUrl?.length);\n const triggerProps: HTMLAttributes<HTMLElement> = {\n onMouseOver: (event) => checkIfHovered(event.nativeEvent),\n onMouseLeave: handleHideTooltipOnHover,\n onFocus: () => setIsOpen(true),\n onBlur: () => (!hasInteractiveElements ? setIsOpen(false) : null),\n };\n\n return (\n <>\n <div {...triggerProps} ref={triggerElementContainerRef}>\n {triggerElement &&\n cloneElement(triggerElement, {\n ref: triggerRefElement,\n })}\n </div>\n {createPortal(\n <div>\n {isOpen && (\n <div\n ref={tooltipContainerRef}\n className=\"tw-popper-container tw-inline-block tw-max-w-[200px] tw-bg-black-100 dark:tw-bg-white tw-rounded-md tw-shadow-mid tw-text-white dark:tw-text-black-100 tw-z-[120000]\"\n data-test-id=\"tooltip\"\n role=\"tooltip\"\n style={popperInstance.styles.popper}\n {...popperInstance.attributes.popper}\n onFocus={() => setIsOpen(true)}\n onMouseOver={(event) => checkIfHovered(event.nativeEvent)}\n onMouseLeave={handleHideTooltipOnHover}\n >\n {brightHeader && <BrightHeader headerStyle={brightHeader} />}\n <div\n className={merge([\n 'tw-px-4',\n hasLargePaddingTop ? paddingsTop.small : paddingsTop.large,\n linkUrl ? paddingsBottom.small : paddingsBottom.large,\n ])}\n >\n {heading && (\n <h4 className=\"tw-flex tw-text-m tw-font-bold tw-mb-1\">\n {headingIcon && (\n <span className=\"tw-mr-1.5\">\n {cloneElement(headingIcon, { size: IconSize.Size20 })}\n </span>\n )}\n {heading}\n </h4>\n )}\n <div className=\"tw-flex\">\n {tooltipIcon && (\n <span className=\"tw-shrink-0 tw-mr-1\">\n {cloneElement(tooltipIcon, { size: IconSize.Size16 })}\n </span>\n )}\n <p className=\"tw-text-s\">{content}</p>\n </div>\n {linkUrl && (\n <a\n {...linkProps}\n data-test-id=\"tooltip-link\"\n ref={linkRef}\n href={linkUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={merge([\n 'tw-text-xs tw-text-black-40 dark:tw-text-black-80 tw-underline tw-mt-1',\n FOCUS_VISIBLE_STYLE,\n ])}\n onBlur={() => (buttons && buttons.length > 0 ? null : setIsOpen(false))}\n >\n {linkLabel ?? 'Click here to learn more.'}\n </a>\n )}\n {buttons && (\n <div className=\"tw-flex tw-flex-row-reverse tw-gap-x-1 tw-mt-4\">\n {buttons.length > 0 && (\n <div\n onBlur={() => (buttons && buttons.length < 2 ? setIsOpen(false) : null)}\n >\n <Button\n style={ButtonStyle.Primary}\n size={ButtonSize.Small}\n inverted\n onClick={buttons[0].action}\n >\n {buttons[0].label}\n </Button>\n </div>\n )}\n {buttons.length === 2 && (\n <div onBlur={() => setIsOpen(false)}>\n <Button\n style={ButtonStyle.Secondary}\n size={ButtonSize.Small}\n inverted\n onClick={buttons[1].action}\n >\n {buttons[1].label}\n </Button>\n </div>\n )}\n </div>\n )}\n <div\n data-test-id=\"popover-arrow\"\n data-popper-arrow={withArrow}\n ref={setArrowElement}\n style={popperInstance.styles.arrow}\n className={merge([\n withArrow &&\n 'tw-popper-arrow tw-absolute tw-w-3 tw-h-3 tw-pointer-events-none before:tw-absolute before:tw-w-3 before:tw-h-3 before:tw-rotate-45 before:tw-border before:tw-border-line',\n withArrow && arrowStyling,\n ])}\n />\n </div>\n {children}\n </div>\n )}\n </div>,\n document.body,\n )}\n </>\n );\n};\n"],"names":[],"mappings":"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"}