@erudilabs/tooltip
Version:
A tooltip is a element used in conjunction with the cursor or mouse pointer to display information about an item without needing to click on it.
1 lines • 4.19 kB
Source Map (JSON)
{"version":3,"sources":["../src/tooltip.tsx"],"sourcesContent":["import { useState, PropsWithChildren, useRef, Fragment } from 'react'\n\nimport {\n useFloating,\n autoUpdate,\n offset,\n flip,\n inline,\n useInteractions,\n useHover,\n arrow,\n Placement,\n FloatingArrow,\n} from '@floating-ui/react'\n\nimport { mergeClassName } from '@erudilabs/merge-class-utils'\n\nexport type TooltipPlacementProps = Placement\n\nexport interface TooltipProps extends PropsWithChildren {\n className?: string\n content: string\n testId?: string\n placement?: TooltipPlacementProps\n}\nexport const Tooltip = (props: TooltipProps) => {\n const { children, content, className, testId, placement = 'top' } = props\n const arrowRef = useRef(null)\n const [isOpen, setIsOpen] = useState(false)\n const ARROW_HEIGHT = 8\n const GAP = 2\n\n const { x, y, strategy, refs, context } = useFloating({\n open: isOpen,\n onOpenChange: setIsOpen,\n middleware: [\n inline(),\n offset(ARROW_HEIGHT + GAP),\n flip({\n fallbackAxisSideDirection: 'start',\n fallbackPlacements: [\n 'top',\n 'right',\n 'bottom',\n 'left',\n 'top-start',\n 'top-end',\n 'right-start',\n 'right-end',\n 'bottom-start',\n 'bottom-end',\n 'left-start',\n 'left-end',\n ],\n }),\n arrow({\n element: arrowRef,\n }),\n ],\n placement,\n whileElementsMounted: autoUpdate,\n })\n const hover = useHover(context, { move: false })\n const { getReferenceProps, getFloatingProps } = useInteractions([hover])\n\n return (\n <Fragment>\n <div\n data-testid={testId}\n ref={refs.setReference}\n {...getReferenceProps()}\n className={mergeClassName('cursor-pointer inline-block', className)}\n >\n {children}\n </div>\n {isOpen && (\n <div\n ref={refs.setFloating}\n className={mergeClassName([\n 'block text-left absolute z-30 p-2 text-sm transition-opacity duration-300 rounded-lg shadow-sm max-w-[400px]',\n 'bg-gray-800',\n 'dark:bg-gray-200',\n ])}\n style={{\n position: strategy,\n top: y ?? 0,\n left: x ?? 0,\n width: 'max-content',\n }}\n {...getFloatingProps()}\n >\n <p className=\"text-gray-50 dark:text-black\">{content}</p>\n <FloatingArrow\n ref={arrowRef}\n context={context}\n className=\"fill-gray-800 dark:fill-gray-200\"\n />\n </div>\n )}\n </Fragment>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,UAA6B,QAAQ,gBAAgB;AAE9D;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,OACK;AAEP,SAAS,sBAAsB;AAoDzB,cASE,YATF;AA1CC,IAAM,UAAU,CAAC,UAAwB;AAC9C,QAAM,EAAE,UAAU,SAAS,WAAW,QAAQ,YAAY,MAAM,IAAI;AACpE,QAAM,WAAW,OAAO,IAAI;AAC5B,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,QAAM,eAAe;AACrB,QAAM,MAAM;AAEZ,QAAM,EAAE,GAAG,GAAG,UAAU,MAAM,QAAQ,IAAI,YAAY;AAAA,IACpD,MAAM;AAAA,IACN,cAAc;AAAA,IACd,YAAY;AAAA,MACV,OAAO;AAAA,MACP,OAAO,eAAe,GAAG;AAAA,MACzB,KAAK;AAAA,QACH,2BAA2B;AAAA,QAC3B,oBAAoB;AAAA,UAClB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AAAA,MACD,MAAM;AAAA,QACJ,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,IACA;AAAA,IACA,sBAAsB;AAAA,EACxB,CAAC;AACD,QAAM,QAAQ,SAAS,SAAS,EAAE,MAAM,MAAM,CAAC;AAC/C,QAAM,EAAE,mBAAmB,iBAAiB,IAAI,gBAAgB,CAAC,KAAK,CAAC;AAEvE,SACE,qBAAC,YACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,eAAa;AAAA,QACb,KAAK,KAAK;AAAA,SACN,kBAAkB,IAHvB;AAAA,QAIC,WAAW,eAAe,+BAA+B,SAAS;AAAA,QAEjE;AAAA;AAAA,IACH;AAAA,IACC,UACC;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,KAAK;AAAA,QACV,WAAW,eAAe;AAAA,UACxB;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AAAA,QACD,OAAO;AAAA,UACL,UAAU;AAAA,UACV,KAAK,gBAAK;AAAA,UACV,MAAM,gBAAK;AAAA,UACX,OAAO;AAAA,QACT;AAAA,SACI,iBAAiB,IAbtB;AAAA,QAeC;AAAA,8BAAC,OAAE,WAAU,gCAAgC,mBAAQ;AAAA,UACrD;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL;AAAA,cACA,WAAU;AAAA;AAAA,UACZ;AAAA;AAAA;AAAA,IACF;AAAA,KAEJ;AAEJ;","names":[]}