@plenustech/design-system 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +8 -0
  2. package/dist/components/actions/ButtonTile/ButtonTile.module.css.cjs +1 -1
  3. package/dist/components/actions/ButtonTile/ButtonTile.module.css.js +10 -10
  4. package/dist/components/actions/Toolbar/Toolbar.cjs +1 -1
  5. package/dist/components/actions/Toolbar/Toolbar.cjs.map +1 -1
  6. package/dist/components/actions/Toolbar/Toolbar.js +64 -53
  7. package/dist/components/actions/Toolbar/Toolbar.js.map +1 -1
  8. package/dist/components/data-display/CodeBlock/syntax.cjs +10 -3
  9. package/dist/components/data-display/CodeBlock/syntax.cjs.map +1 -1
  10. package/dist/components/data-display/CodeBlock/syntax.js +68 -48
  11. package/dist/components/data-display/CodeBlock/syntax.js.map +1 -1
  12. package/dist/components/data-display/Timeline/Timeline.cjs +1 -1
  13. package/dist/components/data-display/Timeline/Timeline.cjs.map +1 -1
  14. package/dist/components/data-display/Timeline/Timeline.js +6 -6
  15. package/dist/components/data-display/Timeline/Timeline.js.map +1 -1
  16. package/dist/components/data-display/Timeline/Timeline.module.css.cjs +1 -1
  17. package/dist/components/data-display/Timeline/Timeline.module.css.js +18 -16
  18. package/dist/components/data-display/Timeline/Timeline.module.css.js.map +1 -1
  19. package/dist/components/forms/Checkbox/Checkbox.module.css.cjs +1 -1
  20. package/dist/components/forms/Checkbox/Checkbox.module.css.js +5 -5
  21. package/dist/components/forms/CheckboxGroup/CheckboxGroup.module.css.cjs +1 -1
  22. package/dist/components/forms/CheckboxGroup/CheckboxGroup.module.css.js +1 -1
  23. package/dist/components/forms/Field/Field.cjs +1 -1
  24. package/dist/components/forms/Field/Field.cjs.map +1 -1
  25. package/dist/components/forms/Field/Field.js +22 -22
  26. package/dist/components/forms/Field/Field.js.map +1 -1
  27. package/dist/components/forms/Field/Field.module.css.cjs +1 -1
  28. package/dist/components/forms/Field/Field.module.css.js +19 -17
  29. package/dist/components/forms/Field/Field.module.css.js.map +1 -1
  30. package/dist/components/forms/InputText/InputText.cjs +1 -1
  31. package/dist/components/forms/InputText/InputText.cjs.map +1 -1
  32. package/dist/components/forms/InputText/InputText.js +24 -24
  33. package/dist/components/forms/InputText/InputText.js.map +1 -1
  34. package/dist/components/forms/InputText/InputText.module.css.cjs +1 -1
  35. package/dist/components/forms/InputText/InputText.module.css.js +9 -7
  36. package/dist/components/forms/InputText/InputText.module.css.js.map +1 -1
  37. package/dist/components/forms/RadioGroup/RadioGroup.module.css.cjs +1 -1
  38. package/dist/components/forms/RadioGroup/RadioGroup.module.css.js +4 -4
  39. package/dist/components/forms/Select/Select.cjs.map +1 -1
  40. package/dist/components/forms/Select/Select.js.map +1 -1
  41. package/dist/components/forms/Switch/Switch.module.css.cjs +1 -1
  42. package/dist/components/forms/Switch/Switch.module.css.js +6 -6
  43. package/dist/components/icons/suite.cjs +1 -0
  44. package/dist/components/icons/suite.js +10894 -0
  45. package/dist/components/navigation/Pagination/Pagination.cjs +1 -1
  46. package/dist/components/navigation/Pagination/Pagination.cjs.map +1 -1
  47. package/dist/components/navigation/Pagination/Pagination.js +71 -44
  48. package/dist/components/navigation/Pagination/Pagination.js.map +1 -1
  49. package/dist/components/navigation/Pagination/Pagination.module.css.cjs +1 -1
  50. package/dist/components/navigation/Pagination/Pagination.module.css.js +18 -14
  51. package/dist/components/navigation/Pagination/Pagination.module.css.js.map +1 -1
  52. package/dist/components/overlays/Menu/Menu.cjs +1 -1
  53. package/dist/components/overlays/Menu/Menu.cjs.map +1 -1
  54. package/dist/components/overlays/Menu/Menu.js +37 -36
  55. package/dist/components/overlays/Menu/Menu.js.map +1 -1
  56. package/dist/components/overlays/Menu/keyShortcuts.cjs +2 -0
  57. package/dist/components/overlays/Menu/keyShortcuts.cjs.map +1 -0
  58. package/dist/components/overlays/Menu/keyShortcuts.js +55 -0
  59. package/dist/components/overlays/Menu/keyShortcuts.js.map +1 -0
  60. package/dist/components/overlays/Tooltip/Tooltip.cjs +1 -1
  61. package/dist/components/overlays/Tooltip/Tooltip.cjs.map +1 -1
  62. package/dist/components/overlays/Tooltip/Tooltip.js +81 -56
  63. package/dist/components/overlays/Tooltip/Tooltip.js.map +1 -1
  64. package/dist/design-system.css +1 -1
  65. package/dist/icons.cjs +2 -0
  66. package/dist/icons.cjs.map +1 -0
  67. package/dist/icons.js +2054 -0
  68. package/dist/icons.js.map +1 -0
  69. package/dist/types/components/data-display/CodeBlock/syntax.d.ts +1 -1
  70. package/dist/types/components/data-display/Timeline/Timeline.d.ts +4 -1
  71. package/dist/types/components/data-display/Timeline/index.d.ts +1 -1
  72. package/dist/types/components/forms/Field/Field.d.ts +1 -1
  73. package/dist/types/components/forms/InputText/InputText.d.ts +1 -1
  74. package/dist/types/components/forms/Select/Select.d.ts +5 -1
  75. package/dist/types/components/icons/suite.d.ts +2051 -0
  76. package/dist/types/components/navigation/Pagination/Pagination.d.ts +13 -1
  77. package/dist/types/components/navigation/Pagination/index.d.ts +1 -1
  78. package/dist/types/components/overlays/Menu/Menu.d.ts +3 -1
  79. package/dist/types/components/overlays/Menu/keyShortcuts.d.ts +2 -0
  80. package/dist/types/components/overlays/Tooltip/Tooltip.d.ts +26 -5
  81. package/dist/types/icons.d.ts +6 -0
  82. package/dist/types/index.d.ts +2 -2
  83. package/package.json +8 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.js","sources":["../../../../src/components/overlays/Menu/Menu.tsx"],"sourcesContent":["import {\n cloneElement,\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { FocusScope } from '@react-aria/focus';\nimport { useOverlay, useOverlayPosition } from '@react-aria/overlays';\nimport { useMergedRefs } from '../../../hooks/useMergedRefs';\nimport { useSelection, type SelectionItem } from '../../../hooks/useSelection';\nimport { IconCheck } from '../../icons';\nimport styles from './Menu.module.css';\n\nexport interface MenuItem {\n /** Com ele, o item e de marcar e mostra o visto quando marcado, como o tipo atual de um bloco. */\n checked?: boolean;\n disabled?: boolean;\n /** Icone decorativo antes do texto. */\n icon?: ReactNode;\n key: string;\n label: string;\n onSelect?: () => void;\n /** Atalho escrito a direita, como `Ctrl+D`, e anunciado em `aria-keyshortcuts`. */\n shortcut?: string;\n /** `danger` para a acao que destroi, como remover. */\n tone?: 'danger';\n}\n\n/** Grupo de itens, com titulo opcional; entre dois grupos, o menu desenha o divisor. */\nexport interface MenuSection {\n items: readonly MenuItem[];\n key: string;\n title?: string;\n}\n\nexport interface MenuProps {\n children: ReactElement<Record<string, unknown>>;\n /** Abertura inicial no modo nao controlado. */\n defaultOpen?: boolean;\n items: readonly (MenuItem | MenuSection)[];\n label: string;\n /** Avisa cada abertura e fechamento pedidos pelo gatilho, pelo teclado, pela opcao ou pelo clique fora. */\n onOpenChange?: (open: boolean) => void;\n /** Controla a abertura; sem ele, o menu guarda o proprio estado. */\n open?: boolean;\n}\n\n/** Encadeia o manipulador do gatilho ao do menu, em vez de substitui-lo. */\nfunction encadear<E>(proprio: ((evento: E) => void) | undefined, seguinte: (evento: E) => void) {\n return (evento: E) => {\n proprio?.(evento);\n seguinte(evento);\n };\n}\n\nexport function Menu({ children, defaultOpen = false, items, label, onOpenChange, open: controlledOpen }: MenuProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [openedWith, setOpenedWith] = useState<'first' | 'last'>('first');\n const open = controlledOpen ?? internalOpen;\n\n function setOpen(proximo: boolean) {\n setInternalOpen(proximo);\n onOpenChange?.(proximo);\n }\n\n function abrir(from: 'first' | 'last') {\n setOpenedWith(from);\n setOpen(true);\n }\n\n // O foco volta na hora, antes de o `onSelect` montar o que vem depois, como um campo com `autoFocus` ou\n // um Dialog, que guarda o elemento em foco para devolver. Clique fora nao devolve: o foco e de quem foi clicado.\n function fechar(devolverFoco: boolean) {\n setOpen(false);\n\n if (devolverFoco) {\n triggerRef.current?.focus();\n }\n }\n\n const dono = children.props;\n const mergedTriggerRef = useMergedRefs(triggerRef, dono.ref as Ref<HTMLElement> | undefined);\n const trigger = cloneElement(children, {\n ref: mergedTriggerRef,\n 'aria-haspopup': 'menu',\n 'aria-expanded': open,\n onClick: encadear(dono.onClick as (evento: unknown) => void, () =>\n open ? fechar(true) : abrir('first'),\n ),\n onKeyDown: encadear(dono.onKeyDown as (evento: KeyboardEvent) => void, (event: KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n abrir(event.key === 'ArrowDown' ? 'first' : 'last');\n }\n }),\n });\n\n return (\n <>\n {trigger}\n {open &&\n typeof document !== 'undefined' &&\n createPortal(\n // O escopo proprio poe o menu na arvore de escopos do Dialog, cujo `contain` puxaria o foco de volta.\n // Sem `contain` aqui: ele disputaria o foco com o gatilho quando o menu fecha.\n <FocusScope>\n <MenuList\n items={items}\n label={label}\n openedWith={openedWith}\n onClose={fechar}\n triggerRef={triggerRef}\n />\n </FocusScope>,\n document.body,\n )}\n </>\n );\n}\n\nfunction ehSecao(entrada: MenuItem | MenuSection): entrada is MenuSection {\n return 'items' in entrada;\n}\n\nfunction MenuList({\n items: entradas,\n label,\n onClose,\n openedWith,\n triggerRef,\n}: {\n items: readonly (MenuItem | MenuSection)[];\n label: string;\n onClose: (devolverFoco: boolean) => void;\n openedWith: 'first' | 'last';\n triggerRef: React.RefObject<HTMLElement | null>;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const nodes = useRef(new Map<string, HTMLElement>());\n // O teclado percorre os itens de todos os grupos como uma lista so.\n const items = useMemo(() => entradas.flatMap((entrada) => (ehSecao(entrada) ? entrada.items : [entrada])), [entradas]);\n const collection = useMemo<SelectionItem[]>(\n () => items.map((item) => ({ key: item.key, disabled: item.disabled, textValue: item.label })),\n [items],\n );\n const selection = useSelection({ items: collection, mode: 'none' });\n const { focusedKey, focusFirst, focusLast, focusNext, focusPrevious, search } = selection;\n\n // useOverlayPosition entrega toda a altura disponivel; limitamos para que\n // uma lista longa nao ocupe a tela inteira.\n // Sem isto o gatilho conta como \"fora\": o ponteiro fecha o menu e o clique\n // dele reabre em seguida, e o menu pisca sem abrir.\n const { overlayProps } = useOverlay(\n {\n isOpen: true,\n onClose: () => onClose(false),\n isDismissable: true,\n shouldCloseOnBlur: false,\n shouldCloseOnInteractOutside: (elemento) => !triggerRef.current?.contains(elemento),\n },\n ref,\n );\n const { overlayProps: positionProps } = useOverlayPosition({\n targetRef: triggerRef,\n overlayRef: ref,\n placement: 'bottom start',\n offset: 6,\n containerPadding: 8,\n isOpen: true,\n });\n\n const alturaMaxima = Math.min(Number(positionProps.style?.maxHeight) || 360, 360);\n\n useEffect(() => {\n if (openedWith === 'last') {\n focusLast();\n } else {\n focusFirst();\n }\n // Posicao inicial depende apenas de como o menu foi aberto.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (focusedKey) {\n nodes.current.get(focusedKey)?.focus();\n }\n }, [focusedKey]);\n\n function acionar(item: MenuItem) {\n if (item.disabled) {\n return;\n }\n\n onClose(true);\n item.onSelect?.();\n }\n\n function renderizarItem(item: MenuItem) {\n const marcavel = item.checked !== undefined;\n\n return (\n <button\n aria-checked={marcavel ? item.checked : undefined}\n aria-keyshortcuts={item.shortcut}\n className={[styles.item, item.tone === 'danger' && styles.danger].filter(Boolean).join(' ')}\n disabled={item.disabled}\n key={item.key}\n onClick={() => acionar(item)}\n ref={(node) => {\n if (node) {\n nodes.current.set(item.key, node);\n } else {\n nodes.current.delete(item.key);\n }\n }}\n role={marcavel ? 'menuitemcheckbox' : 'menuitem'}\n tabIndex={focusedKey === item.key ? 0 : -1}\n type=\"button\"\n >\n {item.icon && (\n <span aria-hidden=\"true\" className={styles.icon}>\n {item.icon}\n </span>\n )}\n <span className={styles.label}>{item.label}</span>\n {item.shortcut && (\n <kbd aria-hidden=\"true\" className={styles.shortcut}>\n {item.shortcut}\n </kbd>\n )}\n {marcavel && <IconCheck className={[styles.check, item.checked && styles.checkOn].filter(Boolean).join(' ')} />}\n </button>\n );\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n focusNext();\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n focusPrevious();\n } else if (event.key === 'Home') {\n event.preventDefault();\n focusFirst();\n } else if (event.key === 'End') {\n event.preventDefault();\n focusLast();\n } else if (event.key === 'Escape' || event.key === 'Tab') {\n onClose(true);\n } else if (event.key.length === 1 && !event.metaKey && !event.ctrlKey) {\n search(event.key);\n }\n }\n\n return (\n <div\n {...overlayProps}\n data-react-aria-top-layer=\"true\"\n ref={ref}\n className={styles.menu}\n style={{ ...positionProps.style, maxHeight: alturaMaxima }}\n role=\"menu\"\n aria-label={label}\n onKeyDown={(event) => {\n // Espalhar overlayProps antes nao basta: este onKeyDown o substituiria.\n handleKeyDown(event);\n overlayProps.onKeyDown?.(event);\n }}\n >\n {entradas.map((entrada, indice) => {\n if (!ehSecao(entrada)) {\n return renderizarItem(entrada);\n }\n\n return (\n <div aria-label={entrada.title} className={styles.section} key={entrada.key} role=\"group\">\n {indice > 0 && <div aria-hidden=\"true\" className={styles.divider} />}\n {entrada.title && (\n <div aria-hidden=\"true\" className={styles.sectionTitle}>\n {entrada.title}\n </div>\n )}\n {entrada.items.map(renderizarItem)}\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":["encadear","proprio","seguinte","evento","Menu","children","defaultOpen","items","label","onOpenChange","controlledOpen","triggerRef","useRef","internalOpen","setInternalOpen","useState","openedWith","setOpenedWith","open","setOpen","proximo","abrir","from","fechar","devolverFoco","_a","dono","mergedTriggerRef","useMergedRefs","trigger","cloneElement","event","jsxs","Fragment","createPortal","FocusScope","jsx","MenuList","ehSecao","entrada","entradas","onClose","ref","nodes","useMemo","collection","item","selection","useSelection","focusedKey","focusFirst","focusLast","focusNext","focusPrevious","search","overlayProps","useOverlay","elemento","positionProps","useOverlayPosition","alturaMaxima","useEffect","acionar","renderizarItem","marcavel","styles","node","IconCheck","handleKeyDown","indice"],"mappings":"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"}
1
+ {"version":3,"file":"Menu.js","sources":["../../../../src/components/overlays/Menu/Menu.tsx"],"sourcesContent":["import {\n cloneElement,\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { FocusScope } from '@react-aria/focus';\nimport { useOverlay, useOverlayPosition } from '@react-aria/overlays';\nimport { useMergedRefs } from '../../../hooks/useMergedRefs';\nimport { useSelection, type SelectionItem } from '../../../hooks/useSelection';\nimport { IconCheck } from '../../icons';\nimport { toAriaKeyShortcuts } from './keyShortcuts';\nimport styles from './Menu.module.css';\n\nexport interface MenuItem {\n /** Com ele, o item e de marcar e mostra o visto quando marcado, como o tipo atual de um bloco. */\n checked?: boolean;\n disabled?: boolean;\n /** Icone decorativo antes do texto. */\n icon?: ReactNode;\n key: string;\n label: string;\n onSelect?: () => void;\n /** Atalho escrito à direita, como `Ctrl+D` ou `⌘⇧D`; convertido nos nomes de tecla de `aria-keyshortcuts`. */\n shortcut?: string;\n /** Valor de `aria-keyshortcuts` quando a conversão do `shortcut` não basta, como `Control+Shift+D Meta+Shift+D`. */\n shortcutKeys?: string;\n /** `danger` para a acao que destroi, como remover. */\n tone?: 'danger';\n}\n\n/** Grupo de itens, com titulo opcional; entre dois grupos, o menu desenha o divisor. */\nexport interface MenuSection {\n items: readonly MenuItem[];\n key: string;\n title?: string;\n}\n\nexport interface MenuProps {\n children: ReactElement<Record<string, unknown>>;\n /** Abertura inicial no modo nao controlado. */\n defaultOpen?: boolean;\n items: readonly (MenuItem | MenuSection)[];\n label: string;\n /** Avisa cada abertura e fechamento pedidos pelo gatilho, pelo teclado, pela opcao ou pelo clique fora. */\n onOpenChange?: (open: boolean) => void;\n /** Controla a abertura; sem ele, o menu guarda o proprio estado. */\n open?: boolean;\n}\n\n/** Encadeia o manipulador do gatilho ao do menu, em vez de substitui-lo. */\nfunction encadear<E>(proprio: ((evento: E) => void) | undefined, seguinte: (evento: E) => void) {\n return (evento: E) => {\n proprio?.(evento);\n seguinte(evento);\n };\n}\n\nexport function Menu({ children, defaultOpen = false, items, label, onOpenChange, open: controlledOpen }: MenuProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [openedWith, setOpenedWith] = useState<'first' | 'last'>('first');\n const open = controlledOpen ?? internalOpen;\n\n function setOpen(proximo: boolean) {\n setInternalOpen(proximo);\n onOpenChange?.(proximo);\n }\n\n function abrir(from: 'first' | 'last') {\n setOpenedWith(from);\n setOpen(true);\n }\n\n // O foco volta na hora, antes de o `onSelect` montar o que vem depois, como um campo com `autoFocus` ou\n // um Dialog, que guarda o elemento em foco para devolver. Clique fora nao devolve: o foco e de quem foi clicado.\n function fechar(devolverFoco: boolean) {\n setOpen(false);\n\n if (devolverFoco) {\n triggerRef.current?.focus();\n }\n }\n\n const dono = children.props;\n const mergedTriggerRef = useMergedRefs(triggerRef, dono.ref as Ref<HTMLElement> | undefined);\n const trigger = cloneElement(children, {\n ref: mergedTriggerRef,\n 'aria-haspopup': 'menu',\n 'aria-expanded': open,\n onClick: encadear(dono.onClick as (evento: unknown) => void, () =>\n open ? fechar(true) : abrir('first'),\n ),\n onKeyDown: encadear(dono.onKeyDown as (evento: KeyboardEvent) => void, (event: KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n abrir(event.key === 'ArrowDown' ? 'first' : 'last');\n }\n }),\n });\n\n return (\n <>\n {trigger}\n {open &&\n typeof document !== 'undefined' &&\n createPortal(\n // O escopo proprio poe o menu na arvore de escopos do Dialog, cujo `contain` puxaria o foco de volta.\n // Sem `contain` aqui: ele disputaria o foco com o gatilho quando o menu fecha.\n <FocusScope>\n <MenuList\n items={items}\n label={label}\n openedWith={openedWith}\n onClose={fechar}\n triggerRef={triggerRef}\n />\n </FocusScope>,\n document.body,\n )}\n </>\n );\n}\n\nfunction ehSecao(entrada: MenuItem | MenuSection): entrada is MenuSection {\n return 'items' in entrada;\n}\n\nfunction MenuList({\n items: entradas,\n label,\n onClose,\n openedWith,\n triggerRef,\n}: {\n items: readonly (MenuItem | MenuSection)[];\n label: string;\n onClose: (devolverFoco: boolean) => void;\n openedWith: 'first' | 'last';\n triggerRef: React.RefObject<HTMLElement | null>;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const nodes = useRef(new Map<string, HTMLElement>());\n // O teclado percorre os itens de todos os grupos como uma lista so.\n const items = useMemo(() => entradas.flatMap((entrada) => (ehSecao(entrada) ? entrada.items : [entrada])), [entradas]);\n const collection = useMemo<SelectionItem[]>(\n () => items.map((item) => ({ key: item.key, disabled: item.disabled, textValue: item.label })),\n [items],\n );\n const selection = useSelection({ items: collection, mode: 'none' });\n const { focusedKey, focusFirst, focusLast, focusNext, focusPrevious, search } = selection;\n\n // useOverlayPosition entrega toda a altura disponivel; limitamos para que\n // uma lista longa nao ocupe a tela inteira.\n // Sem isto o gatilho conta como \"fora\": o ponteiro fecha o menu e o clique\n // dele reabre em seguida, e o menu pisca sem abrir.\n const { overlayProps } = useOverlay(\n {\n isOpen: true,\n onClose: () => onClose(false),\n isDismissable: true,\n shouldCloseOnBlur: false,\n shouldCloseOnInteractOutside: (elemento) => !triggerRef.current?.contains(elemento),\n },\n ref,\n );\n const { overlayProps: positionProps } = useOverlayPosition({\n targetRef: triggerRef,\n overlayRef: ref,\n placement: 'bottom start',\n offset: 6,\n containerPadding: 8,\n isOpen: true,\n });\n\n const alturaMaxima = Math.min(Number(positionProps.style?.maxHeight) || 360, 360);\n\n useEffect(() => {\n if (openedWith === 'last') {\n focusLast();\n } else {\n focusFirst();\n }\n // Posicao inicial depende apenas de como o menu foi aberto.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (focusedKey) {\n nodes.current.get(focusedKey)?.focus();\n }\n }, [focusedKey]);\n\n function acionar(item: MenuItem) {\n if (item.disabled) {\n return;\n }\n\n onClose(true);\n item.onSelect?.();\n }\n\n function renderizarItem(item: MenuItem) {\n const marcavel = item.checked !== undefined;\n\n return (\n <button\n aria-checked={marcavel ? item.checked : undefined}\n aria-keyshortcuts={item.shortcutKeys ?? (item.shortcut ? toAriaKeyShortcuts(item.shortcut) : undefined)}\n className={[styles.item, item.tone === 'danger' && styles.danger].filter(Boolean).join(' ')}\n disabled={item.disabled}\n key={item.key}\n onClick={() => acionar(item)}\n ref={(node) => {\n if (node) {\n nodes.current.set(item.key, node);\n } else {\n nodes.current.delete(item.key);\n }\n }}\n role={marcavel ? 'menuitemcheckbox' : 'menuitem'}\n tabIndex={focusedKey === item.key ? 0 : -1}\n type=\"button\"\n >\n {item.icon && (\n <span aria-hidden=\"true\" className={styles.icon}>\n {item.icon}\n </span>\n )}\n <span className={styles.label}>{item.label}</span>\n {item.shortcut && (\n <kbd aria-hidden=\"true\" className={styles.shortcut}>\n {item.shortcut}\n </kbd>\n )}\n {marcavel && <IconCheck className={[styles.check, item.checked && styles.checkOn].filter(Boolean).join(' ')} />}\n </button>\n );\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n focusNext();\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n focusPrevious();\n } else if (event.key === 'Home') {\n event.preventDefault();\n focusFirst();\n } else if (event.key === 'End') {\n event.preventDefault();\n focusLast();\n } else if (event.key === 'Escape' || event.key === 'Tab') {\n onClose(true);\n } else if (event.key.length === 1 && !event.metaKey && !event.ctrlKey) {\n search(event.key);\n }\n }\n\n return (\n <div\n {...overlayProps}\n data-react-aria-top-layer=\"true\"\n ref={ref}\n className={styles.menu}\n style={{ ...positionProps.style, maxHeight: alturaMaxima }}\n role=\"menu\"\n aria-label={label}\n onKeyDown={(event) => {\n // Espalhar overlayProps antes nao basta: este onKeyDown o substituiria.\n handleKeyDown(event);\n overlayProps.onKeyDown?.(event);\n }}\n >\n {entradas.map((entrada, indice) => {\n if (!ehSecao(entrada)) {\n return renderizarItem(entrada);\n }\n\n return (\n <div aria-label={entrada.title} className={styles.section} key={entrada.key} role=\"group\">\n {indice > 0 && <div aria-hidden=\"true\" className={styles.divider} />}\n {entrada.title && (\n <div aria-hidden=\"true\" className={styles.sectionTitle}>\n {entrada.title}\n </div>\n )}\n {entrada.items.map(renderizarItem)}\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":["encadear","proprio","seguinte","evento","Menu","children","defaultOpen","items","label","onOpenChange","controlledOpen","triggerRef","useRef","internalOpen","setInternalOpen","useState","openedWith","setOpenedWith","open","setOpen","proximo","abrir","from","fechar","devolverFoco","_a","dono","mergedTriggerRef","useMergedRefs","trigger","cloneElement","event","jsxs","Fragment","createPortal","FocusScope","jsx","MenuList","ehSecao","entrada","entradas","onClose","ref","nodes","useMemo","collection","item","selection","useSelection","focusedKey","focusFirst","focusLast","focusNext","focusPrevious","search","overlayProps","useOverlay","elemento","positionProps","useOverlayPosition","alturaMaxima","useEffect","acionar","renderizarItem","marcavel","toAriaKeyShortcuts","styles","node","IconCheck","handleKeyDown","indice"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o={"⌘":"Meta",cmd:"Meta",command:"Meta",meta:"Meta","⌥":"Alt",alt:"Alt",opt:"Alt",option:"Alt","⇧":"Shift",shift:"Shift","⌃":"Control",ctrl:"Control",control:"Control",esc:"Escape",escape:"Escape",del:"Delete",delete:"Delete","⌫":"Backspace",backspace:"Backspace","↵":"Enter",enter:"Enter",return:"Enter","⇥":"Tab",tab:"Tab",space:"Space",espaço:"Space","+":"Plus","↑":"ArrowUp",up:"ArrowUp","↓":"ArrowDown",down:"ArrowDown","←":"ArrowLeft",left:"ArrowLeft","→":"ArrowRight",right:"ArrowRight",home:"Home",end:"End",pageup:"PageUp",pagedown:"PageDown"};function r(e){const t=o[e.toLowerCase()];return t||(e.length===1||/^f\d{1,2}$/i.test(e)?e.toUpperCase():e)}function a(e){return(e.replace(/([⌘⌥⇧⌃])(?=[^+])/g,"$1+").match(/[^+]+|\+$/g)??[]).map(r).join("+")}function n(e){return e.replace(/\s*\+\s*/g,"+").replace(/([^+]),/g,"$1 ").split(/\s+/).filter(Boolean).map(a).join(" ")}exports.toAriaKeyShortcuts=n;
2
+ //# sourceMappingURL=keyShortcuts.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyShortcuts.cjs","sources":["../../../../src/components/overlays/Menu/keyShortcuts.ts"],"sourcesContent":["// Nomes de tecla que a especificação ARIA espera em `aria-keyshortcuts`, pela grafia escrita em minúsculas.\nconst KEY_NAMES: Record<string, string> = {\n '⌘': 'Meta',\n cmd: 'Meta',\n command: 'Meta',\n meta: 'Meta',\n '⌥': 'Alt',\n alt: 'Alt',\n opt: 'Alt',\n option: 'Alt',\n '⇧': 'Shift',\n shift: 'Shift',\n '⌃': 'Control',\n ctrl: 'Control',\n control: 'Control',\n esc: 'Escape',\n escape: 'Escape',\n del: 'Delete',\n delete: 'Delete',\n '⌫': 'Backspace',\n backspace: 'Backspace',\n '↵': 'Enter',\n enter: 'Enter',\n return: 'Enter',\n '⇥': 'Tab',\n tab: 'Tab',\n space: 'Space',\n espaço: 'Space',\n '+': 'Plus',\n '↑': 'ArrowUp',\n up: 'ArrowUp',\n '↓': 'ArrowDown',\n down: 'ArrowDown',\n '←': 'ArrowLeft',\n left: 'ArrowLeft',\n '→': 'ArrowRight',\n right: 'ArrowRight',\n home: 'Home',\n end: 'End',\n pageup: 'PageUp',\n pagedown: 'PageDown',\n};\n\nfunction toKeyName(key: string) {\n const name = KEY_NAMES[key.toLowerCase()];\n\n if (name) {\n return name;\n }\n\n return key.length === 1 || /^f\\d{1,2}$/i.test(key) ? key.toUpperCase() : key;\n}\n\nfunction toKeyCombination(shortcut: string) {\n // Os símbolos do macOS vêm colados (`⌘⇧D`); o `+` final de `Ctrl++` é a própria tecla.\n const separated = shortcut.replace(/([⌘⌥⇧⌃])(?=[^+])/g, '$1+');\n\n return (separated.match(/[^+]+|\\+$/g) ?? []).map(toKeyName).join('+');\n}\n\n/** Converte o atalho escrito, como `Ctrl+Shift+D` ou `⌘K, Ctrl+K`, no valor de `aria-keyshortcuts`. */\nexport function toAriaKeyShortcuts(shortcut: string) {\n return shortcut\n .replace(/\\s*\\+\\s*/g, '+')\n .replace(/([^+]),/g, '$1 ')\n .split(/\\s+/)\n .filter(Boolean)\n .map(toKeyCombination)\n .join(' ');\n}\n"],"names":["KEY_NAMES","toKeyName","key","name","toKeyCombination","shortcut","toAriaKeyShortcuts"],"mappings":"gFACA,MAAMA,EAAoC,CACxC,IAAK,OACL,IAAK,OACL,QAAS,OACT,KAAM,OACN,IAAK,MACL,IAAK,MACL,IAAK,MACL,OAAQ,MACR,IAAK,QACL,MAAO,QACP,IAAK,UACL,KAAM,UACN,QAAS,UACT,IAAK,SACL,OAAQ,SACR,IAAK,SACL,OAAQ,SACR,IAAK,YACL,UAAW,YACX,IAAK,QACL,MAAO,QACP,OAAQ,QACR,IAAK,MACL,IAAK,MACL,MAAO,QACP,OAAQ,QACR,IAAK,OACL,IAAK,UACL,GAAI,UACJ,IAAK,YACL,KAAM,YACN,IAAK,YACL,KAAM,YACN,IAAK,aACL,MAAO,aACP,KAAM,OACN,IAAK,MACL,OAAQ,SACR,SAAU,UACZ,EAEA,SAASC,EAAUC,EAAa,CAC9B,MAAMC,EAAOH,EAAUE,EAAI,YAAA,CAAa,EAExC,OAAIC,IAIGD,EAAI,SAAW,GAAK,cAAc,KAAKA,CAAG,EAAIA,EAAI,YAAA,EAAgBA,EAC3E,CAEA,SAASE,EAAiBC,EAAkB,CAI1C,OAFkBA,EAAS,QAAQ,oBAAqB,KAAK,EAE3C,MAAM,YAAY,GAAK,IAAI,IAAIJ,CAAS,EAAE,KAAK,GAAG,CACtE,CAGO,SAASK,EAAmBD,EAAkB,CACnD,OAAOA,EACJ,QAAQ,YAAa,GAAG,EACxB,QAAQ,WAAY,KAAK,EACzB,MAAM,KAAK,EACX,OAAO,OAAO,EACd,IAAID,CAAgB,EACpB,KAAK,GAAG,CACb"}
@@ -0,0 +1,55 @@
1
+ const o = {
2
+ "⌘": "Meta",
3
+ cmd: "Meta",
4
+ command: "Meta",
5
+ meta: "Meta",
6
+ "⌥": "Alt",
7
+ alt: "Alt",
8
+ opt: "Alt",
9
+ option: "Alt",
10
+ "⇧": "Shift",
11
+ shift: "Shift",
12
+ "⌃": "Control",
13
+ ctrl: "Control",
14
+ control: "Control",
15
+ esc: "Escape",
16
+ escape: "Escape",
17
+ del: "Delete",
18
+ delete: "Delete",
19
+ "⌫": "Backspace",
20
+ backspace: "Backspace",
21
+ "↵": "Enter",
22
+ enter: "Enter",
23
+ return: "Enter",
24
+ "⇥": "Tab",
25
+ tab: "Tab",
26
+ space: "Space",
27
+ espaço: "Space",
28
+ "+": "Plus",
29
+ "↑": "ArrowUp",
30
+ up: "ArrowUp",
31
+ "↓": "ArrowDown",
32
+ down: "ArrowDown",
33
+ "←": "ArrowLeft",
34
+ left: "ArrowLeft",
35
+ "→": "ArrowRight",
36
+ right: "ArrowRight",
37
+ home: "Home",
38
+ end: "End",
39
+ pageup: "PageUp",
40
+ pagedown: "PageDown"
41
+ };
42
+ function r(e) {
43
+ const t = o[e.toLowerCase()];
44
+ return t || (e.length === 1 || /^f\d{1,2}$/i.test(e) ? e.toUpperCase() : e);
45
+ }
46
+ function a(e) {
47
+ return (e.replace(/([⌘⌥⇧⌃])(?=[^+])/g, "$1+").match(/[^+]+|\+$/g) ?? []).map(r).join("+");
48
+ }
49
+ function n(e) {
50
+ return e.replace(/\s*\+\s*/g, "+").replace(/([^+]),/g, "$1 ").split(/\s+/).filter(Boolean).map(a).join(" ");
51
+ }
52
+ export {
53
+ n as toAriaKeyShortcuts
54
+ };
55
+ //# sourceMappingURL=keyShortcuts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyShortcuts.js","sources":["../../../../src/components/overlays/Menu/keyShortcuts.ts"],"sourcesContent":["// Nomes de tecla que a especificação ARIA espera em `aria-keyshortcuts`, pela grafia escrita em minúsculas.\nconst KEY_NAMES: Record<string, string> = {\n '⌘': 'Meta',\n cmd: 'Meta',\n command: 'Meta',\n meta: 'Meta',\n '⌥': 'Alt',\n alt: 'Alt',\n opt: 'Alt',\n option: 'Alt',\n '⇧': 'Shift',\n shift: 'Shift',\n '⌃': 'Control',\n ctrl: 'Control',\n control: 'Control',\n esc: 'Escape',\n escape: 'Escape',\n del: 'Delete',\n delete: 'Delete',\n '⌫': 'Backspace',\n backspace: 'Backspace',\n '↵': 'Enter',\n enter: 'Enter',\n return: 'Enter',\n '⇥': 'Tab',\n tab: 'Tab',\n space: 'Space',\n espaço: 'Space',\n '+': 'Plus',\n '↑': 'ArrowUp',\n up: 'ArrowUp',\n '↓': 'ArrowDown',\n down: 'ArrowDown',\n '←': 'ArrowLeft',\n left: 'ArrowLeft',\n '→': 'ArrowRight',\n right: 'ArrowRight',\n home: 'Home',\n end: 'End',\n pageup: 'PageUp',\n pagedown: 'PageDown',\n};\n\nfunction toKeyName(key: string) {\n const name = KEY_NAMES[key.toLowerCase()];\n\n if (name) {\n return name;\n }\n\n return key.length === 1 || /^f\\d{1,2}$/i.test(key) ? key.toUpperCase() : key;\n}\n\nfunction toKeyCombination(shortcut: string) {\n // Os símbolos do macOS vêm colados (`⌘⇧D`); o `+` final de `Ctrl++` é a própria tecla.\n const separated = shortcut.replace(/([⌘⌥⇧⌃])(?=[^+])/g, '$1+');\n\n return (separated.match(/[^+]+|\\+$/g) ?? []).map(toKeyName).join('+');\n}\n\n/** Converte o atalho escrito, como `Ctrl+Shift+D` ou `⌘K, Ctrl+K`, no valor de `aria-keyshortcuts`. */\nexport function toAriaKeyShortcuts(shortcut: string) {\n return shortcut\n .replace(/\\s*\\+\\s*/g, '+')\n .replace(/([^+]),/g, '$1 ')\n .split(/\\s+/)\n .filter(Boolean)\n .map(toKeyCombination)\n .join(' ');\n}\n"],"names":["KEY_NAMES","toKeyName","key","name","toKeyCombination","shortcut","toAriaKeyShortcuts"],"mappings":"AACA,MAAMA,IAAoC;AAAA,EACxC,KAAK;AAAA,EACL,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,OAAO;AAAA,EACP,KAAK;AAAA,EACL,MAAM;AAAA,EACN,SAAS;AAAA,EACT,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,WAAW;AAAA,EACX,KAAK;AAAA,EACL,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,KAAK;AAAA,EACL,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,UAAU;AACZ;AAEA,SAASC,EAAUC,GAAa;AAC9B,QAAMC,IAAOH,EAAUE,EAAI,YAAA,CAAa;AAExC,SAAIC,MAIGD,EAAI,WAAW,KAAK,cAAc,KAAKA,CAAG,IAAIA,EAAI,YAAA,IAAgBA;AAC3E;AAEA,SAASE,EAAiBC,GAAkB;AAI1C,UAFkBA,EAAS,QAAQ,qBAAqB,KAAK,EAE3C,MAAM,YAAY,KAAK,IAAI,IAAIJ,CAAS,EAAE,KAAK,GAAG;AACtE;AAGO,SAASK,EAAmBD,GAAkB;AACnD,SAAOA,EACJ,QAAQ,aAAa,GAAG,EACxB,QAAQ,YAAY,KAAK,EACzB,MAAM,KAAK,EACX,OAAO,OAAO,EACd,IAAID,CAAgB,EACpB,KAAK,GAAG;AACb;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),o=require("react"),g=require("react-dom"),R=require("@react-aria/overlays"),v=require("../../../hooks/useMergedRefs.cjs"),M=require("./Tooltip.module.css.cjs"),E=120;function c(t,u){return n=>{t==null||t(n),u(n)}}function j({children:t,content:u,delay:n=500,placement:f="top"}){const i=o.useRef(null),[a,s]=o.useState(!1),e=o.useRef(void 0),p=`tooltip-${o.useId()}`,d=o.useCallback(()=>{clearTimeout(e.current),s(!1)},[]),m=o.useCallback(()=>{clearTimeout(e.current),e.current=setTimeout(()=>s(!1),E)},[]);o.useEffect(()=>()=>clearTimeout(e.current),[]);const r=t.props,y=v.useMergedRefs(i,r.ref),T=o.cloneElement(t,{ref:y,"aria-describedby":a?[r["aria-describedby"],p].filter(Boolean).join(" "):r["aria-describedby"],onMouseEnter:c(r.onMouseEnter,()=>{clearTimeout(e.current),e.current=setTimeout(()=>s(!0),n)}),onMouseLeave:c(r.onMouseLeave,m),onFocus:c(r.onFocus,()=>s(!0)),onBlur:c(r.onBlur,d),onKeyDown:c(r.onKeyDown,b=>{b.key==="Escape"&&d()})});return l.jsxs(l.Fragment,{children:[T,a&&g.createPortal(l.jsx(q,{content:u,id:p,onMouseEnter:()=>clearTimeout(e.current),onMouseLeave:d,placement:f,triggerRef:i}),document.body)]})}function q({content:t,id:u,onMouseEnter:n,onMouseLeave:f,placement:i,triggerRef:a}){const s=o.useRef(null),{overlayProps:e}=R.useOverlayPosition({targetRef:a,overlayRef:s,placement:i,offset:6,isOpen:!0});return l.jsx("div",{ref:s,className:M.default.tooltip,"data-react-aria-top-layer":"true",id:u,onMouseEnter:n,onMouseLeave:f,role:"tooltip",style:e.style,children:t})}exports.Tooltip=j;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),n=require("react"),b=require("react-dom"),g=require("@react-aria/overlays"),x=require("../../../hooks/useMergedRefs.cjs"),S=require("./Tooltip.module.css.cjs"),L=120;function d(e,s){return r=>{e==null||e(r),s(r)}}function P(e){return e.anchorRef?l.jsx(B,{...e}):l.jsx(k,{...e})}function k({children:e,content:s,delay:r=500,onOpenChange:t,open:i,placement:f="top"}){const o=n.useRef(null),[a,E]=n.useState(!1),p=i??a,c=n.useRef(void 0),R=`tooltip-${n.useId()}`;function m(y){E(y),t==null||t(y)}function T(){clearTimeout(c.current),m(!1)}function j(){clearTimeout(c.current),c.current=setTimeout(()=>m(!1),L)}n.useEffect(()=>()=>clearTimeout(c.current),[]);const u=e.props,M=x.useMergedRefs(o,u.ref),q=n.cloneElement(e,{ref:M,"aria-describedby":p?[u["aria-describedby"],R].filter(Boolean).join(" "):u["aria-describedby"],onMouseEnter:d(u.onMouseEnter,()=>{clearTimeout(c.current),c.current=setTimeout(()=>m(!0),r)}),onMouseLeave:d(u.onMouseLeave,j),onFocus:d(u.onFocus,()=>m(!0)),onBlur:d(u.onBlur,T),onKeyDown:d(u.onKeyDown,y=>{y.key==="Escape"&&T()})});return l.jsxs(l.Fragment,{children:[q,p&&typeof document<"u"&&b.createPortal(l.jsx(v,{content:s,id:R,onMouseEnter:()=>clearTimeout(c.current),onMouseLeave:T,placement:f,triggerRef:o}),document.body)]})}function B({anchorRef:e,content:s,id:r,onOpenChange:t,open:i,placement:f="top"}){return n.useEffect(()=>{if(!i)return;function o(a){a.key==="Escape"&&(t==null||t(!1))}return document.addEventListener("keydown",o),()=>document.removeEventListener("keydown",o)},[t,i]),!i||typeof document>"u"?null:b.createPortal(l.jsx(v,{content:s,id:r,placement:f,triggerRef:e}),document.body)}function v({content:e,id:s,onMouseEnter:r,onMouseLeave:t,placement:i,triggerRef:f}){const o=n.useRef(null),{overlayProps:a}=g.useOverlayPosition({targetRef:f,overlayRef:o,placement:i,offset:6,isOpen:!0});return l.jsx("div",{ref:o,className:S.default.tooltip,"data-react-aria-top-layer":"true",id:s,onMouseEnter:r,onMouseLeave:t,role:"tooltip",style:a.style,children:e})}exports.Tooltip=P;
2
2
  //# sourceMappingURL=Tooltip.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.cjs","sources":["../../../../src/components/overlays/Tooltip/Tooltip.tsx"],"sourcesContent":["import {\n cloneElement,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { useOverlayPosition } from '@react-aria/overlays';\nimport { useMergedRefs } from '../../../hooks/useMergedRefs';\nimport styles from './Tooltip.module.css';\n\nexport type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';\n\nexport interface TooltipProps {\n children: ReactElement<Record<string, unknown>>;\n content: ReactNode;\n delay?: number;\n placement?: TooltipPlacement;\n}\n\n/** Tempo para o ponteiro atravessar a folga entre o gatilho e o balao. */\nconst TRAVESSIA = 120;\n\nfunction chain<E>(own: ((event: E) => void) | undefined, next: (event: E) => void) {\n return (event: E) => {\n own?.(event);\n next(event);\n };\n}\n\nexport function Tooltip({ children, content, delay = 500, placement = 'top' }: TooltipProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const [open, setOpen] = useState(false);\n const timer = useRef<ReturnType<typeof setTimeout>>(undefined);\n const id = `tooltip-${useId()}`;\n\n const hide = useCallback(() => {\n clearTimeout(timer.current);\n setOpen(false);\n }, []);\n\n // O balao aceita o ponteiro (WCAG 1.4.13): sair do gatilho espera a travessia ate ele antes de fechar.\n const hideSoon = useCallback(() => {\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setOpen(false), TRAVESSIA);\n }, []);\n\n useEffect(() => () => clearTimeout(timer.current), []);\n\n const props = children.props;\n const mergedTriggerRef = useMergedRefs(triggerRef, props.ref as Ref<HTMLElement> | undefined);\n const trigger = cloneElement(children, {\n ref: mergedTriggerRef,\n 'aria-describedby': open ? [props['aria-describedby'], id].filter(Boolean).join(' ') : props['aria-describedby'],\n onMouseEnter: chain(props.onMouseEnter as (e: MouseEvent) => void, () => {\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setOpen(true), delay);\n }),\n onMouseLeave: chain(props.onMouseLeave as (e: MouseEvent) => void, hideSoon),\n onFocus: chain(props.onFocus as (e: FocusEvent) => void, () => setOpen(true)),\n onBlur: chain(props.onBlur as (e: FocusEvent) => void, hide),\n onKeyDown: chain(props.onKeyDown as (e: KeyboardEvent) => void, (event) => {\n if (event.key === 'Escape') {\n hide();\n }\n }),\n });\n\n return (\n <>\n {trigger}\n {open &&\n createPortal(\n <TooltipBubble\n content={content}\n id={id}\n onMouseEnter={() => clearTimeout(timer.current)}\n onMouseLeave={hide}\n placement={placement}\n triggerRef={triggerRef}\n />,\n document.body,\n )}\n </>\n );\n}\n\nfunction TooltipBubble({\n content,\n id,\n onMouseEnter,\n onMouseLeave,\n placement,\n triggerRef,\n}: {\n content: ReactNode;\n id: string;\n onMouseEnter: () => void;\n onMouseLeave: () => void;\n placement: TooltipPlacement;\n triggerRef: React.RefObject<HTMLElement | null>;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const { overlayProps } = useOverlayPosition({\n targetRef: triggerRef,\n overlayRef: ref,\n placement,\n offset: 6,\n isOpen: true,\n });\n\n return (\n <div\n ref={ref}\n className={styles.tooltip}\n data-react-aria-top-layer=\"true\"\n id={id}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n role=\"tooltip\"\n style={overlayProps.style}\n >\n {content}\n </div>\n );\n}\n"],"names":["TRAVESSIA","chain","own","next","event","Tooltip","children","content","delay","placement","triggerRef","useRef","open","setOpen","useState","timer","id","useId","hide","useCallback","hideSoon","useEffect","props","mergedTriggerRef","useMergedRefs","trigger","cloneElement","jsxs","Fragment","createPortal","jsx","TooltipBubble","onMouseEnter","onMouseLeave","ref","overlayProps","useOverlayPosition","styles"],"mappings":"qRA6BMA,EAAY,IAElB,SAASC,EAASC,EAAuCC,EAA0B,CACjF,OAAQC,GAAa,CACnBF,GAAA,MAAAA,EAAME,GACND,EAAKC,CAAK,CACZ,CACF,CAEO,SAASC,EAAQ,CAAE,SAAAC,EAAU,QAAAC,EAAS,MAAAC,EAAQ,IAAK,UAAAC,EAAY,OAAuB,CAC3F,MAAMC,EAAaC,EAAAA,OAAoB,IAAI,EACrC,CAACC,EAAMC,CAAO,EAAIC,EAAAA,SAAS,EAAK,EAChCC,EAAQJ,EAAAA,OAAsC,MAAS,EACvDK,EAAK,WAAWC,EAAAA,MAAA,CAAO,GAEvBC,EAAOC,EAAAA,YAAY,IAAM,CAC7B,aAAaJ,EAAM,OAAO,EAC1BF,EAAQ,EAAK,CACf,EAAG,CAAA,CAAE,EAGCO,EAAWD,EAAAA,YAAY,IAAM,CACjC,aAAaJ,EAAM,OAAO,EAC1BA,EAAM,QAAU,WAAW,IAAMF,EAAQ,EAAK,EAAGb,CAAS,CAC5D,EAAG,CAAA,CAAE,EAELqB,EAAAA,UAAU,IAAM,IAAM,aAAaN,EAAM,OAAO,EAAG,CAAA,CAAE,EAErD,MAAMO,EAAQhB,EAAS,MACjBiB,EAAmBC,EAAAA,cAAcd,EAAYY,EAAM,GAAmC,EACtFG,EAAUC,EAAAA,aAAapB,EAAU,CACrC,IAAKiB,EACL,mBAAoBX,EAAO,CAACU,EAAM,kBAAkB,EAAGN,CAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAAIM,EAAM,kBAAkB,EAC/G,aAAcrB,EAAMqB,EAAM,aAAyC,IAAM,CACvE,aAAaP,EAAM,OAAO,EAC1BA,EAAM,QAAU,WAAW,IAAMF,EAAQ,EAAI,EAAGL,CAAK,CACvD,CAAC,EACD,aAAcP,EAAMqB,EAAM,aAAyCF,CAAQ,EAC3E,QAASnB,EAAMqB,EAAM,QAAoC,IAAMT,EAAQ,EAAI,CAAC,EAC5E,OAAQZ,EAAMqB,EAAM,OAAmCJ,CAAI,EAC3D,UAAWjB,EAAMqB,EAAM,UAA0ClB,GAAU,CACrEA,EAAM,MAAQ,UAChBc,EAAA,CAEJ,CAAC,CAAA,CACF,EAED,OACES,EAAAA,KAAAC,WAAA,CACG,SAAA,CAAAH,EACAb,GACCiB,EAAAA,aACEC,EAAAA,IAACC,EAAA,CACC,QAAAxB,EACA,GAAAS,EACA,aAAc,IAAM,aAAaD,EAAM,OAAO,EAC9C,aAAcG,EACd,UAAAT,EACA,WAAAC,CAAA,CAAA,EAEF,SAAS,IAAA,CACX,EACJ,CAEJ,CAEA,SAASqB,EAAc,CACrB,QAAAxB,EACA,GAAAS,EACA,aAAAgB,EACA,aAAAC,EACA,UAAAxB,EACA,WAAAC,CACF,EAOG,CACD,MAAMwB,EAAMvB,EAAAA,OAAuB,IAAI,EACjC,CAAE,aAAAwB,CAAA,EAAiBC,qBAAmB,CAC1C,UAAW1B,EACX,WAAYwB,EACZ,UAAAzB,EACA,OAAQ,EACR,OAAQ,EAAA,CACT,EAED,OACEqB,EAAAA,IAAC,MAAA,CACC,IAAAI,EACA,UAAWG,EAAAA,QAAO,QAClB,4BAA0B,OAC1B,GAAArB,EACA,aAAAgB,EACA,aAAAC,EACA,KAAK,UACL,MAAOE,EAAa,MAEnB,SAAA5B,CAAA,CAAA,CAGP"}
1
+ {"version":3,"file":"Tooltip.cjs","sources":["../../../../src/components/overlays/Tooltip/Tooltip.tsx"],"sourcesContent":["import {\n cloneElement,\n useEffect,\n useId,\n useRef,\n useState,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n type RefObject,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { useOverlayPosition } from '@react-aria/overlays';\nimport { useMergedRefs } from '../../../hooks/useMergedRefs';\nimport styles from './Tooltip.module.css';\n\nexport type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';\n\ninterface TooltipCommonProps {\n content: ReactNode;\n /** Avisa cada pedido de abrir ou fechar: ponteiro, foco, blur e Escape. */\n onOpenChange?: (open: boolean) => void;\n placement?: TooltipPlacement;\n}\n\ninterface TooltipOnChildProps extends TooltipCommonProps {\n anchorRef?: never;\n /** O gatilho: o Tooltip o clona, soma os manipuladores e liga a descrição por `aria-describedby`. */\n children: ReactElement<Record<string, unknown>>;\n delay?: number;\n id?: never;\n /** Controla a abertura; sem ele, o Tooltip guarda o próprio estado. */\n open?: boolean;\n}\n\ninterface TooltipOnAnchorProps extends TooltipCommonProps {\n /** Âncora que não é filho do Tooltip, como um elemento que precisa da própria referência e não pode ser clonado. */\n anchorRef: RefObject<HTMLElement | null>;\n children?: never;\n delay?: never;\n /** Id do balão. O produto o põe no `aria-describedby` da âncora enquanto `open`. */\n id: string;\n /** Com âncora externa, a abertura é sempre do produto. */\n open: boolean;\n}\n\nexport type TooltipProps = TooltipOnChildProps | TooltipOnAnchorProps;\n\n/** Tempo para o ponteiro atravessar a folga entre o gatilho e o balao. */\nconst TRAVESSIA = 120;\n\nfunction chain<E>(own: ((event: E) => void) | undefined, next: (event: E) => void) {\n return (event: E) => {\n own?.(event);\n next(event);\n };\n}\n\nexport function Tooltip(props: TooltipProps) {\n return props.anchorRef ? <TooltipOnAnchor {...props} /> : <TooltipOnChild {...props} />;\n}\n\nfunction TooltipOnChild({\n children,\n content,\n delay = 500,\n onOpenChange,\n open: controlledOpen,\n placement = 'top',\n}: TooltipOnChildProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const open = controlledOpen ?? internalOpen;\n const timer = useRef<ReturnType<typeof setTimeout>>(undefined);\n const id = `tooltip-${useId()}`;\n\n function setOpen(next: boolean) {\n setInternalOpen(next);\n onOpenChange?.(next);\n }\n\n function hide() {\n clearTimeout(timer.current);\n setOpen(false);\n }\n\n // O balão aceita o ponteiro (WCAG 1.4.13): sair do gatilho espera a travessia até ele antes de fechar.\n function hideSoon() {\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setOpen(false), TRAVESSIA);\n }\n\n useEffect(() => () => clearTimeout(timer.current), []);\n\n const props = children.props;\n const mergedTriggerRef = useMergedRefs(triggerRef, props.ref as Ref<HTMLElement> | undefined);\n const trigger = cloneElement(children, {\n ref: mergedTriggerRef,\n 'aria-describedby': open ? [props['aria-describedby'], id].filter(Boolean).join(' ') : props['aria-describedby'],\n onMouseEnter: chain(props.onMouseEnter as (e: MouseEvent) => void, () => {\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setOpen(true), delay);\n }),\n onMouseLeave: chain(props.onMouseLeave as (e: MouseEvent) => void, hideSoon),\n onFocus: chain(props.onFocus as (e: FocusEvent) => void, () => setOpen(true)),\n onBlur: chain(props.onBlur as (e: FocusEvent) => void, hide),\n onKeyDown: chain(props.onKeyDown as (e: KeyboardEvent) => void, (event) => {\n if (event.key === 'Escape') {\n hide();\n }\n }),\n });\n\n return (\n <>\n {trigger}\n {open &&\n typeof document !== 'undefined' &&\n createPortal(\n <TooltipBubble\n content={content}\n id={id}\n onMouseEnter={() => clearTimeout(timer.current)}\n onMouseLeave={hide}\n placement={placement}\n triggerRef={triggerRef}\n />,\n document.body,\n )}\n </>\n );\n}\n\nfunction TooltipOnAnchor({ anchorRef, content, id, onOpenChange, open, placement = 'top' }: TooltipOnAnchorProps) {\n // O foco pode estar fora da âncora, como no editor que a contém; o Escape vale em qualquer ponto da página.\n useEffect(() => {\n if (!open) {\n return;\n }\n\n function requestCloseOnEscape(event: globalThis.KeyboardEvent) {\n if (event.key === 'Escape') {\n onOpenChange?.(false);\n }\n }\n\n document.addEventListener('keydown', requestCloseOnEscape);\n return () => document.removeEventListener('keydown', requestCloseOnEscape);\n }, [onOpenChange, open]);\n\n if (!open || typeof document === 'undefined') {\n return null;\n }\n\n return createPortal(<TooltipBubble content={content} id={id} placement={placement} triggerRef={anchorRef} />, document.body);\n}\n\nfunction TooltipBubble({\n content,\n id,\n onMouseEnter,\n onMouseLeave,\n placement,\n triggerRef,\n}: {\n content: ReactNode;\n id: string;\n onMouseEnter?: () => void;\n onMouseLeave?: () => void;\n placement: TooltipPlacement;\n triggerRef: RefObject<HTMLElement | null>;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const { overlayProps } = useOverlayPosition({\n targetRef: triggerRef,\n overlayRef: ref,\n placement,\n offset: 6,\n isOpen: true,\n });\n\n return (\n <div\n ref={ref}\n className={styles.tooltip}\n data-react-aria-top-layer=\"true\"\n id={id}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n role=\"tooltip\"\n style={overlayProps.style}\n >\n {content}\n </div>\n );\n}\n"],"names":["TRAVESSIA","chain","own","next","event","Tooltip","props","jsx","TooltipOnAnchor","TooltipOnChild","children","content","delay","onOpenChange","controlledOpen","placement","triggerRef","useRef","internalOpen","setInternalOpen","useState","open","timer","id","useId","setOpen","hide","hideSoon","useEffect","mergedTriggerRef","useMergedRefs","trigger","cloneElement","jsxs","Fragment","createPortal","TooltipBubble","anchorRef","requestCloseOnEscape","onMouseEnter","onMouseLeave","ref","overlayProps","useOverlayPosition","styles"],"mappings":"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"}
@@ -1,84 +1,109 @@
1
- import { jsxs as v, Fragment as E, jsx as d } from "react/jsx-runtime";
2
- import { useRef as f, useState as M, useId as R, useCallback as p, useEffect as h, cloneElement as B } from "react";
3
- import { createPortal as S } from "react-dom";
4
- import { useOverlayPosition as j } from "@react-aria/overlays";
5
- import { useMergedRefs as x } from "../../../hooks/useMergedRefs.js";
6
- import F from "./Tooltip.module.css.js";
7
- const L = 120;
8
- function i(o, s) {
9
- return (n) => {
10
- o == null || o(n), s(n);
1
+ import { jsx as a, jsxs as S, Fragment as g } from "react/jsx-runtime";
2
+ import { useEffect as b, useRef as p, useState as j, useId as A, cloneElement as F } from "react";
3
+ import { createPortal as v } from "react-dom";
4
+ import { useOverlayPosition as I } from "@react-aria/overlays";
5
+ import { useMergedRefs as P } from "../../../hooks/useMergedRefs.js";
6
+ import x from "./Tooltip.module.css.js";
7
+ const D = 120;
8
+ function f(e, u) {
9
+ return (r) => {
10
+ e == null || e(r), u(r);
11
11
  };
12
12
  }
13
- function C({ children: o, content: s, delay: n = 500, placement: a = "top" }) {
14
- const u = f(null), [c, t] = M(!1), e = f(void 0), m = `tooltip-${R()}`, l = p(() => {
15
- clearTimeout(e.current), t(!1);
16
- }, []), y = p(() => {
17
- clearTimeout(e.current), e.current = setTimeout(() => t(!1), L);
18
- }, []);
19
- h(() => () => clearTimeout(e.current), []);
20
- const r = o.props, T = x(u, r.ref), b = B(o, {
21
- ref: T,
22
- "aria-describedby": c ? [r["aria-describedby"], m].filter(Boolean).join(" ") : r["aria-describedby"],
23
- onMouseEnter: i(r.onMouseEnter, () => {
24
- clearTimeout(e.current), e.current = setTimeout(() => t(!0), n);
13
+ function H(e) {
14
+ return e.anchorRef ? /* @__PURE__ */ a(q, { ...e }) : /* @__PURE__ */ a(K, { ...e });
15
+ }
16
+ function K({
17
+ children: e,
18
+ content: u,
19
+ delay: r = 500,
20
+ onOpenChange: t,
21
+ open: i,
22
+ placement: c = "top"
23
+ }) {
24
+ const o = p(null), [l, M] = j(!1), T = i ?? l, s = p(void 0), E = `tooltip-${A()}`;
25
+ function d(m) {
26
+ M(m), t == null || t(m);
27
+ }
28
+ function y() {
29
+ clearTimeout(s.current), d(!1);
30
+ }
31
+ function L() {
32
+ clearTimeout(s.current), s.current = setTimeout(() => d(!1), D);
33
+ }
34
+ b(() => () => clearTimeout(s.current), []);
35
+ const n = e.props, k = P(o, n.ref), B = F(e, {
36
+ ref: k,
37
+ "aria-describedby": T ? [n["aria-describedby"], E].filter(Boolean).join(" ") : n["aria-describedby"],
38
+ onMouseEnter: f(n.onMouseEnter, () => {
39
+ clearTimeout(s.current), s.current = setTimeout(() => d(!0), r);
25
40
  }),
26
- onMouseLeave: i(r.onMouseLeave, y),
27
- onFocus: i(r.onFocus, () => t(!0)),
28
- onBlur: i(r.onBlur, l),
29
- onKeyDown: i(r.onKeyDown, (g) => {
30
- g.key === "Escape" && l();
41
+ onMouseLeave: f(n.onMouseLeave, L),
42
+ onFocus: f(n.onFocus, () => d(!0)),
43
+ onBlur: f(n.onBlur, y),
44
+ onKeyDown: f(n.onKeyDown, (m) => {
45
+ m.key === "Escape" && y();
31
46
  })
32
47
  });
33
- return /* @__PURE__ */ v(E, { children: [
34
- b,
35
- c && S(
36
- /* @__PURE__ */ d(
37
- O,
48
+ return /* @__PURE__ */ S(g, { children: [
49
+ B,
50
+ T && typeof document < "u" && v(
51
+ /* @__PURE__ */ a(
52
+ R,
38
53
  {
39
- content: s,
40
- id: m,
41
- onMouseEnter: () => clearTimeout(e.current),
42
- onMouseLeave: l,
43
- placement: a,
44
- triggerRef: u
54
+ content: u,
55
+ id: E,
56
+ onMouseEnter: () => clearTimeout(s.current),
57
+ onMouseLeave: y,
58
+ placement: c,
59
+ triggerRef: o
45
60
  }
46
61
  ),
47
62
  document.body
48
63
  )
49
64
  ] });
50
65
  }
51
- function O({
52
- content: o,
53
- id: s,
54
- onMouseEnter: n,
55
- onMouseLeave: a,
56
- placement: u,
66
+ function q({ anchorRef: e, content: u, id: r, onOpenChange: t, open: i, placement: c = "top" }) {
67
+ return b(() => {
68
+ if (!i)
69
+ return;
70
+ function o(l) {
71
+ l.key === "Escape" && (t == null || t(!1));
72
+ }
73
+ return document.addEventListener("keydown", o), () => document.removeEventListener("keydown", o);
74
+ }, [t, i]), !i || typeof document > "u" ? null : v(/* @__PURE__ */ a(R, { content: u, id: r, placement: c, triggerRef: e }), document.body);
75
+ }
76
+ function R({
77
+ content: e,
78
+ id: u,
79
+ onMouseEnter: r,
80
+ onMouseLeave: t,
81
+ placement: i,
57
82
  triggerRef: c
58
83
  }) {
59
- const t = f(null), { overlayProps: e } = j({
84
+ const o = p(null), { overlayProps: l } = I({
60
85
  targetRef: c,
61
- overlayRef: t,
62
- placement: u,
86
+ overlayRef: o,
87
+ placement: i,
63
88
  offset: 6,
64
89
  isOpen: !0
65
90
  });
66
- return /* @__PURE__ */ d(
91
+ return /* @__PURE__ */ a(
67
92
  "div",
68
93
  {
69
- ref: t,
70
- className: F.tooltip,
94
+ ref: o,
95
+ className: x.tooltip,
71
96
  "data-react-aria-top-layer": "true",
72
- id: s,
73
- onMouseEnter: n,
74
- onMouseLeave: a,
97
+ id: u,
98
+ onMouseEnter: r,
99
+ onMouseLeave: t,
75
100
  role: "tooltip",
76
- style: e.style,
77
- children: o
101
+ style: l.style,
102
+ children: e
78
103
  }
79
104
  );
80
105
  }
81
106
  export {
82
- C as Tooltip
107
+ H as Tooltip
83
108
  };
84
109
  //# sourceMappingURL=Tooltip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.js","sources":["../../../../src/components/overlays/Tooltip/Tooltip.tsx"],"sourcesContent":["import {\n cloneElement,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { useOverlayPosition } from '@react-aria/overlays';\nimport { useMergedRefs } from '../../../hooks/useMergedRefs';\nimport styles from './Tooltip.module.css';\n\nexport type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';\n\nexport interface TooltipProps {\n children: ReactElement<Record<string, unknown>>;\n content: ReactNode;\n delay?: number;\n placement?: TooltipPlacement;\n}\n\n/** Tempo para o ponteiro atravessar a folga entre o gatilho e o balao. */\nconst TRAVESSIA = 120;\n\nfunction chain<E>(own: ((event: E) => void) | undefined, next: (event: E) => void) {\n return (event: E) => {\n own?.(event);\n next(event);\n };\n}\n\nexport function Tooltip({ children, content, delay = 500, placement = 'top' }: TooltipProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const [open, setOpen] = useState(false);\n const timer = useRef<ReturnType<typeof setTimeout>>(undefined);\n const id = `tooltip-${useId()}`;\n\n const hide = useCallback(() => {\n clearTimeout(timer.current);\n setOpen(false);\n }, []);\n\n // O balao aceita o ponteiro (WCAG 1.4.13): sair do gatilho espera a travessia ate ele antes de fechar.\n const hideSoon = useCallback(() => {\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setOpen(false), TRAVESSIA);\n }, []);\n\n useEffect(() => () => clearTimeout(timer.current), []);\n\n const props = children.props;\n const mergedTriggerRef = useMergedRefs(triggerRef, props.ref as Ref<HTMLElement> | undefined);\n const trigger = cloneElement(children, {\n ref: mergedTriggerRef,\n 'aria-describedby': open ? [props['aria-describedby'], id].filter(Boolean).join(' ') : props['aria-describedby'],\n onMouseEnter: chain(props.onMouseEnter as (e: MouseEvent) => void, () => {\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setOpen(true), delay);\n }),\n onMouseLeave: chain(props.onMouseLeave as (e: MouseEvent) => void, hideSoon),\n onFocus: chain(props.onFocus as (e: FocusEvent) => void, () => setOpen(true)),\n onBlur: chain(props.onBlur as (e: FocusEvent) => void, hide),\n onKeyDown: chain(props.onKeyDown as (e: KeyboardEvent) => void, (event) => {\n if (event.key === 'Escape') {\n hide();\n }\n }),\n });\n\n return (\n <>\n {trigger}\n {open &&\n createPortal(\n <TooltipBubble\n content={content}\n id={id}\n onMouseEnter={() => clearTimeout(timer.current)}\n onMouseLeave={hide}\n placement={placement}\n triggerRef={triggerRef}\n />,\n document.body,\n )}\n </>\n );\n}\n\nfunction TooltipBubble({\n content,\n id,\n onMouseEnter,\n onMouseLeave,\n placement,\n triggerRef,\n}: {\n content: ReactNode;\n id: string;\n onMouseEnter: () => void;\n onMouseLeave: () => void;\n placement: TooltipPlacement;\n triggerRef: React.RefObject<HTMLElement | null>;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const { overlayProps } = useOverlayPosition({\n targetRef: triggerRef,\n overlayRef: ref,\n placement,\n offset: 6,\n isOpen: true,\n });\n\n return (\n <div\n ref={ref}\n className={styles.tooltip}\n data-react-aria-top-layer=\"true\"\n id={id}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n role=\"tooltip\"\n style={overlayProps.style}\n >\n {content}\n </div>\n );\n}\n"],"names":["TRAVESSIA","chain","own","next","event","Tooltip","children","content","delay","placement","triggerRef","useRef","open","setOpen","useState","timer","id","useId","hide","useCallback","hideSoon","useEffect","props","mergedTriggerRef","useMergedRefs","trigger","cloneElement","jsxs","Fragment","createPortal","jsx","TooltipBubble","onMouseEnter","onMouseLeave","ref","overlayProps","useOverlayPosition","styles"],"mappings":";;;;;;AA6BA,MAAMA,IAAY;AAElB,SAASC,EAASC,GAAuCC,GAA0B;AACjF,SAAO,CAACC,MAAa;AACnB,IAAAF,KAAA,QAAAA,EAAME,IACND,EAAKC,CAAK;AAAA,EACZ;AACF;AAEO,SAASC,EAAQ,EAAE,UAAAC,GAAU,SAAAC,GAAS,OAAAC,IAAQ,KAAK,WAAAC,IAAY,SAAuB;AAC3F,QAAMC,IAAaC,EAAoB,IAAI,GACrC,CAACC,GAAMC,CAAO,IAAIC,EAAS,EAAK,GAChCC,IAAQJ,EAAsC,MAAS,GACvDK,IAAK,WAAWC,EAAA,CAAO,IAEvBC,IAAOC,EAAY,MAAM;AAC7B,iBAAaJ,EAAM,OAAO,GAC1BF,EAAQ,EAAK;AAAA,EACf,GAAG,CAAA,CAAE,GAGCO,IAAWD,EAAY,MAAM;AACjC,iBAAaJ,EAAM,OAAO,GAC1BA,EAAM,UAAU,WAAW,MAAMF,EAAQ,EAAK,GAAGb,CAAS;AAAA,EAC5D,GAAG,CAAA,CAAE;AAEL,EAAAqB,EAAU,MAAM,MAAM,aAAaN,EAAM,OAAO,GAAG,CAAA,CAAE;AAErD,QAAMO,IAAQhB,EAAS,OACjBiB,IAAmBC,EAAcd,GAAYY,EAAM,GAAmC,GACtFG,IAAUC,EAAapB,GAAU;AAAA,IACrC,KAAKiB;AAAA,IACL,oBAAoBX,IAAO,CAACU,EAAM,kBAAkB,GAAGN,CAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,IAAIM,EAAM,kBAAkB;AAAA,IAC/G,cAAcrB,EAAMqB,EAAM,cAAyC,MAAM;AACvE,mBAAaP,EAAM,OAAO,GAC1BA,EAAM,UAAU,WAAW,MAAMF,EAAQ,EAAI,GAAGL,CAAK;AAAA,IACvD,CAAC;AAAA,IACD,cAAcP,EAAMqB,EAAM,cAAyCF,CAAQ;AAAA,IAC3E,SAASnB,EAAMqB,EAAM,SAAoC,MAAMT,EAAQ,EAAI,CAAC;AAAA,IAC5E,QAAQZ,EAAMqB,EAAM,QAAmCJ,CAAI;AAAA,IAC3D,WAAWjB,EAAMqB,EAAM,WAAyC,CAAClB,MAAU;AACzE,MAAIA,EAAM,QAAQ,YAChBc,EAAA;AAAA,IAEJ,CAAC;AAAA,EAAA,CACF;AAED,SACE,gBAAAS,EAAAC,GAAA,EACG,UAAA;AAAA,IAAAH;AAAA,IACAb,KACCiB;AAAA,MACE,gBAAAC;AAAA,QAACC;AAAA,QAAA;AAAA,UACC,SAAAxB;AAAA,UACA,IAAAS;AAAA,UACA,cAAc,MAAM,aAAaD,EAAM,OAAO;AAAA,UAC9C,cAAcG;AAAA,UACd,WAAAT;AAAA,UACA,YAAAC;AAAA,QAAA;AAAA,MAAA;AAAA,MAEF,SAAS;AAAA,IAAA;AAAA,EACX,GACJ;AAEJ;AAEA,SAASqB,EAAc;AAAA,EACrB,SAAAxB;AAAA,EACA,IAAAS;AAAA,EACA,cAAAgB;AAAA,EACA,cAAAC;AAAA,EACA,WAAAxB;AAAA,EACA,YAAAC;AACF,GAOG;AACD,QAAMwB,IAAMvB,EAAuB,IAAI,GACjC,EAAE,cAAAwB,EAAA,IAAiBC,EAAmB;AAAA,IAC1C,WAAW1B;AAAA,IACX,YAAYwB;AAAA,IACZ,WAAAzB;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,EAAA,CACT;AAED,SACE,gBAAAqB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAI;AAAA,MACA,WAAWG,EAAO;AAAA,MAClB,6BAA0B;AAAA,MAC1B,IAAArB;AAAA,MACA,cAAAgB;AAAA,MACA,cAAAC;AAAA,MACA,MAAK;AAAA,MACL,OAAOE,EAAa;AAAA,MAEnB,UAAA5B;AAAA,IAAA;AAAA,EAAA;AAGP;"}
1
+ {"version":3,"file":"Tooltip.js","sources":["../../../../src/components/overlays/Tooltip/Tooltip.tsx"],"sourcesContent":["import {\n cloneElement,\n useEffect,\n useId,\n useRef,\n useState,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n type RefObject,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { useOverlayPosition } from '@react-aria/overlays';\nimport { useMergedRefs } from '../../../hooks/useMergedRefs';\nimport styles from './Tooltip.module.css';\n\nexport type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';\n\ninterface TooltipCommonProps {\n content: ReactNode;\n /** Avisa cada pedido de abrir ou fechar: ponteiro, foco, blur e Escape. */\n onOpenChange?: (open: boolean) => void;\n placement?: TooltipPlacement;\n}\n\ninterface TooltipOnChildProps extends TooltipCommonProps {\n anchorRef?: never;\n /** O gatilho: o Tooltip o clona, soma os manipuladores e liga a descrição por `aria-describedby`. */\n children: ReactElement<Record<string, unknown>>;\n delay?: number;\n id?: never;\n /** Controla a abertura; sem ele, o Tooltip guarda o próprio estado. */\n open?: boolean;\n}\n\ninterface TooltipOnAnchorProps extends TooltipCommonProps {\n /** Âncora que não é filho do Tooltip, como um elemento que precisa da própria referência e não pode ser clonado. */\n anchorRef: RefObject<HTMLElement | null>;\n children?: never;\n delay?: never;\n /** Id do balão. O produto o põe no `aria-describedby` da âncora enquanto `open`. */\n id: string;\n /** Com âncora externa, a abertura é sempre do produto. */\n open: boolean;\n}\n\nexport type TooltipProps = TooltipOnChildProps | TooltipOnAnchorProps;\n\n/** Tempo para o ponteiro atravessar a folga entre o gatilho e o balao. */\nconst TRAVESSIA = 120;\n\nfunction chain<E>(own: ((event: E) => void) | undefined, next: (event: E) => void) {\n return (event: E) => {\n own?.(event);\n next(event);\n };\n}\n\nexport function Tooltip(props: TooltipProps) {\n return props.anchorRef ? <TooltipOnAnchor {...props} /> : <TooltipOnChild {...props} />;\n}\n\nfunction TooltipOnChild({\n children,\n content,\n delay = 500,\n onOpenChange,\n open: controlledOpen,\n placement = 'top',\n}: TooltipOnChildProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const open = controlledOpen ?? internalOpen;\n const timer = useRef<ReturnType<typeof setTimeout>>(undefined);\n const id = `tooltip-${useId()}`;\n\n function setOpen(next: boolean) {\n setInternalOpen(next);\n onOpenChange?.(next);\n }\n\n function hide() {\n clearTimeout(timer.current);\n setOpen(false);\n }\n\n // O balão aceita o ponteiro (WCAG 1.4.13): sair do gatilho espera a travessia até ele antes de fechar.\n function hideSoon() {\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setOpen(false), TRAVESSIA);\n }\n\n useEffect(() => () => clearTimeout(timer.current), []);\n\n const props = children.props;\n const mergedTriggerRef = useMergedRefs(triggerRef, props.ref as Ref<HTMLElement> | undefined);\n const trigger = cloneElement(children, {\n ref: mergedTriggerRef,\n 'aria-describedby': open ? [props['aria-describedby'], id].filter(Boolean).join(' ') : props['aria-describedby'],\n onMouseEnter: chain(props.onMouseEnter as (e: MouseEvent) => void, () => {\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setOpen(true), delay);\n }),\n onMouseLeave: chain(props.onMouseLeave as (e: MouseEvent) => void, hideSoon),\n onFocus: chain(props.onFocus as (e: FocusEvent) => void, () => setOpen(true)),\n onBlur: chain(props.onBlur as (e: FocusEvent) => void, hide),\n onKeyDown: chain(props.onKeyDown as (e: KeyboardEvent) => void, (event) => {\n if (event.key === 'Escape') {\n hide();\n }\n }),\n });\n\n return (\n <>\n {trigger}\n {open &&\n typeof document !== 'undefined' &&\n createPortal(\n <TooltipBubble\n content={content}\n id={id}\n onMouseEnter={() => clearTimeout(timer.current)}\n onMouseLeave={hide}\n placement={placement}\n triggerRef={triggerRef}\n />,\n document.body,\n )}\n </>\n );\n}\n\nfunction TooltipOnAnchor({ anchorRef, content, id, onOpenChange, open, placement = 'top' }: TooltipOnAnchorProps) {\n // O foco pode estar fora da âncora, como no editor que a contém; o Escape vale em qualquer ponto da página.\n useEffect(() => {\n if (!open) {\n return;\n }\n\n function requestCloseOnEscape(event: globalThis.KeyboardEvent) {\n if (event.key === 'Escape') {\n onOpenChange?.(false);\n }\n }\n\n document.addEventListener('keydown', requestCloseOnEscape);\n return () => document.removeEventListener('keydown', requestCloseOnEscape);\n }, [onOpenChange, open]);\n\n if (!open || typeof document === 'undefined') {\n return null;\n }\n\n return createPortal(<TooltipBubble content={content} id={id} placement={placement} triggerRef={anchorRef} />, document.body);\n}\n\nfunction TooltipBubble({\n content,\n id,\n onMouseEnter,\n onMouseLeave,\n placement,\n triggerRef,\n}: {\n content: ReactNode;\n id: string;\n onMouseEnter?: () => void;\n onMouseLeave?: () => void;\n placement: TooltipPlacement;\n triggerRef: RefObject<HTMLElement | null>;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const { overlayProps } = useOverlayPosition({\n targetRef: triggerRef,\n overlayRef: ref,\n placement,\n offset: 6,\n isOpen: true,\n });\n\n return (\n <div\n ref={ref}\n className={styles.tooltip}\n data-react-aria-top-layer=\"true\"\n id={id}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n role=\"tooltip\"\n style={overlayProps.style}\n >\n {content}\n </div>\n );\n}\n"],"names":["TRAVESSIA","chain","own","next","event","Tooltip","props","jsx","TooltipOnAnchor","TooltipOnChild","children","content","delay","onOpenChange","controlledOpen","placement","triggerRef","useRef","internalOpen","setInternalOpen","useState","open","timer","id","useId","setOpen","hide","hideSoon","useEffect","mergedTriggerRef","useMergedRefs","trigger","cloneElement","jsxs","Fragment","createPortal","TooltipBubble","anchorRef","requestCloseOnEscape","onMouseEnter","onMouseLeave","ref","overlayProps","useOverlayPosition","styles"],"mappings":"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"}