@chayns-components/emoji-input 5.6.6 β†’ 5.6.8

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 (26) hide show
  1. package/lib/cjs/build.test.js +34 -0
  2. package/lib/cjs/build.test.js.map +1 -0
  3. package/lib/cjs/components/emoji-picker/emoji-picker-emojis/EmojiPickerEmojis.js +48 -219
  4. package/lib/cjs/components/emoji-picker/emoji-picker-emojis/EmojiPickerEmojis.js.map +1 -1
  5. package/lib/cjs/components/emoji-picker/emoji-picker-emojis/EmojiPickerEmojis.test.js +316 -0
  6. package/lib/cjs/components/emoji-picker/emoji-picker-emojis/EmojiPickerEmojis.test.js.map +1 -0
  7. package/lib/cjs/components/emoji-picker/emoji-picker-emojis/emoji/Emoji.js +1 -0
  8. package/lib/cjs/components/emoji-picker/emoji-picker-emojis/emoji/Emoji.js.map +1 -1
  9. package/lib/cjs/components/emoji-picker/emoji-picker-emojis/emoji-picker-emoji-list/EmojiPickerEmojiList.js +109 -0
  10. package/lib/cjs/components/emoji-picker/emoji-picker-emojis/emoji-picker-emoji-list/EmojiPickerEmojiList.js.map +1 -0
  11. package/lib/esm/build.test.js +32 -0
  12. package/lib/esm/build.test.js.map +1 -0
  13. package/lib/esm/components/emoji-picker/emoji-picker-emojis/EmojiPickerEmojis.js +47 -218
  14. package/lib/esm/components/emoji-picker/emoji-picker-emojis/EmojiPickerEmojis.js.map +1 -1
  15. package/lib/esm/components/emoji-picker/emoji-picker-emojis/EmojiPickerEmojis.test.js +312 -0
  16. package/lib/esm/components/emoji-picker/emoji-picker-emojis/EmojiPickerEmojis.test.js.map +1 -0
  17. package/lib/esm/components/emoji-picker/emoji-picker-emojis/emoji/Emoji.js +1 -0
  18. package/lib/esm/components/emoji-picker/emoji-picker-emojis/emoji/Emoji.js.map +1 -1
  19. package/lib/esm/components/emoji-picker/emoji-picker-emojis/emoji-picker-emoji-list/EmojiPickerEmojiList.js +101 -0
  20. package/lib/esm/components/emoji-picker/emoji-picker-emojis/emoji-picker-emoji-list/EmojiPickerEmojiList.js.map +1 -0
  21. package/lib/types/components/emoji-picker/emoji-picker-emojis/emoji-picker-emoji-list/EmojiPickerEmojiList.d.ts +15 -0
  22. package/package.json +2 -2
  23. package/lib/types/components/emoji-input/EmojiInput.test.d.ts +0 -1
  24. package/lib/types/utils/emoji.test.d.ts +0 -1
  25. package/lib/types/utils/selection.test.d.ts +0 -1
  26. package/lib/types/utils/text.test.d.ts +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmojiPickerEmojis.test.js","names":["fireEvent","render","screen","waitFor","React","ThemeProvider","beforeEach","describe","expect","it","vi","EmojiPickerEmojis","fixtures","hoisted","emojis","emoji","name","skin_tone_support","addHistory","fn","history","mock","default","slug","slice","Object","fromEntries","map","data","useEmojiHistory","addOrUpdateEmojiInHistory","historyEmojis","useRef","useIsMeasuredClone","setup","onSelect","renderPicker","searchString","selectedCategory","createElement","theme","view","container","querySelectorAll","toHaveLength","update","search","category","rerender","key","ctrlKey","keyDown","document","navigate","index","selected","element","getComputedStyle","backgroundColor","toBe","mockReset","getByRole","focus","toHaveBeenCalledTimes","toHaveBeenCalledWith","activeElement","not","toHaveBeenCalled","querySelector","toBeNull","each","direction","toHaveBeenLastCalledWith","mockClear","click","contextMenu"],"sources":["../../../../../src/components/emoji-picker/emoji-picker-emojis/EmojiPickerEmojis.test.tsx"],"sourcesContent":["import { fireEvent, render, screen, waitFor } from '@testing-library/react';\nimport React from 'react';\nimport { ThemeProvider } from 'styled-components';\nimport { beforeEach, describe, expect, it, vi } from 'vitest';\nimport EmojiPickerEmojis from './EmojiPickerEmojis';\nimport type { Category } from '../../../types/category';\n\nconst fixtures = vi.hoisted(() => ({\n emojis: [\n { emoji: 'πŸ˜€', name: 'grinning face', skin_tone_support: false },\n { emoji: 'πŸ˜ƒ', name: 'smiling face', skin_tone_support: false },\n { emoji: 'πŸ˜„', name: 'laughing face', skin_tone_support: false },\n { emoji: '🐈', name: 'cat', skin_tone_support: false },\n { emoji: 'πŸ‘', name: 'thumbs up', skin_tone_support: true },\n { emoji: 'πŸ‘Ž', name: 'thumbs down', skin_tone_support: true },\n { emoji: 'πŸ‘‹', name: 'waving hand', skin_tone_support: true },\n { emoji: '🀝', name: 'handshake', skin_tone_support: true },\n ],\n addHistory: vi.fn(),\n history: [] as { emoji: string; name: string; skin_tone_support: boolean }[],\n}));\n\nvi.mock('unicode-emoji-json/data-by-group.json', () => ({\n default: [\n { slug: 'smileys_emotion', emojis: fixtures.emojis },\n { slug: 'people_body', emojis: fixtures.emojis.slice(4) },\n ],\n}));\nvi.mock('unicode-emoji-json/data-by-emoji.json', () => ({\n default: Object.fromEntries(fixtures.emojis.map(({ emoji, ...data }) => [emoji, data])),\n}));\nvi.mock('../../../hooks/emojiHistory', () => ({\n useEmojiHistory: () => ({\n addOrUpdateEmojiInHistory: fixtures.addHistory,\n historyEmojis: fixtures.history.slice(),\n }),\n}));\nvi.mock('@chayns-components/core', async () => {\n const { useRef } = await import('react');\n return {\n ...(await import('../../../../../core/src/hooks/ref')),\n useIsMeasuredClone: () => [false, useRef<HTMLDivElement>(null)] as const,\n };\n});\n\nconst setup = async () => {\n const onSelect = vi.fn();\n const renderPicker = (searchString = '', selectedCategory: Category = 'smileys_emotion') => (\n <ThemeProvider theme={{ 'secondary-102': 'rgb(255, 0, 0)' }}>\n <input aria-label=\"Search\" />\n <EmojiPickerEmojis\n onSelect={onSelect}\n searchString={searchString}\n selectedCategory={selectedCategory}\n />\n </ThemeProvider>\n );\n const view = render(renderPicker());\n await waitFor(() => expect(view.container.querySelectorAll('[data-emoji]')).toHaveLength(8));\n return {\n ...view,\n onSelect,\n update: (search = '', category?: Category) => view.rerender(renderPicker(search, category)),\n };\n};\n\nconst key = (key: string, ctrlKey = false) => fireEvent.keyDown(document, { key, ctrlKey });\nconst navigate = () => {\n for (let index = 0; index < 7; index += 1) key('ArrowRight');\n};\nconst selected = (element: Element) =>\n expect(getComputedStyle(element).backgroundColor).toBe('rgb(255, 0, 0)');\n\nbeforeEach(() => {\n fixtures.addHistory.mockReset();\n fixtures.history = [];\n});\n\ndescribe('EmojiPickerEmojis changing results', () => {\n it('resets to the first result before Enter after narrowing the search', async () => {\n const { onSelect, update } = await setup();\n navigate();\n screen.getByRole('textbox', { name: 'Search' }).focus();\n update('thumbs');\n key('Enter');\n expect(onSelect).toHaveBeenCalledTimes(1);\n expect(onSelect).toHaveBeenCalledWith('πŸ‘', true);\n expect(document.activeElement).toBe(screen.getByRole('textbox', { name: 'Search' }));\n });\n\n it('does not select the hint or throw on Enter and Ctrl+Enter without results', async () => {\n const { onSelect, update, container } = await setup();\n navigate();\n update('no-matching-emoji-9284');\n key('Enter');\n key('Enter', true);\n expect(onSelect).not.toHaveBeenCalled();\n expect(container.querySelector('[data-emoji]')).toBeNull();\n expect(container.querySelector('[tabindex=\"0\"]')).toBeNull();\n });\n\n it.each(['thumbs', 'no-matching-emoji-9284'])(\n 'handles every arrow after searching for %s',\n async (search) => {\n const { onSelect, update, container } = await setup();\n navigate();\n update(search);\n for (const direction of ['ArrowRight', 'ArrowLeft', 'ArrowUp', 'ArrowDown'])\n key(direction);\n key('Enter');\n if (search === 'thumbs') {\n expect(onSelect).toHaveBeenCalledTimes(1);\n expect(onSelect).toHaveBeenCalledWith('πŸ‘', true);\n selected(container.querySelector('[data-emoji=\"πŸ‘\"]')!);\n } else expect(onSelect).not.toHaveBeenCalled();\n },\n );\n\n it('recovers after clearing an empty search', async () => {\n const { onSelect, update, container } = await setup();\n navigate();\n update('no-matching-emoji-9284');\n key('ArrowRight');\n update('');\n key('ArrowRight');\n key('Enter');\n expect(onSelect).toHaveBeenCalledTimes(1);\n expect(onSelect).toHaveBeenCalledWith('πŸ˜ƒ', true);\n selected(container.querySelector('[data-emoji=\"πŸ˜ƒ\"]')!);\n });\n\n it('resets on category changes and keeps an empty history unselectable', async () => {\n const { onSelect, update } = await setup();\n navigate();\n update('', 'people_body');\n key('Enter');\n expect(onSelect).toHaveBeenLastCalledWith('πŸ‘', true);\n onSelect.mockClear();\n update('', 'history');\n key('ArrowRight');\n key('ArrowDown');\n key('Enter');\n expect(onSelect).not.toHaveBeenCalled();\n });\n\n it('uses visible positions for highlight, keyboard selection, and mouse selection including index zero', async () => {\n const { onSelect, update, container } = await setup();\n update('thumbs');\n selected(container.querySelector('[data-emoji=\"πŸ‘\"]')!);\n key('ArrowRight');\n selected(container.querySelector('[data-emoji=\"πŸ‘Ž\"]')!);\n key('Enter');\n expect(onSelect).toHaveBeenLastCalledWith('πŸ‘Ž', true);\n fireEvent.click(container.querySelector('[data-emoji=\"πŸ‘\"]')!);\n selected(container.querySelector('[data-emoji=\"πŸ‘\"]')!);\n expect(onSelect).toHaveBeenLastCalledWith('πŸ‘', false);\n });\n\n it('opens the skin tone popup for the visible right-clicked emoji after filtering', async () => {\n const { update, onSelect, container } = await setup();\n update('thumbs');\n fireEvent.contextMenu(container.querySelector('[data-emoji=\"πŸ‘Ž\"]')!);\n selected(container.querySelector('[data-emoji=\"πŸ‘Ž\"]')!);\n key('ArrowRight');\n key('Enter');\n expect(onSelect).toHaveBeenCalledTimes(1);\n expect(onSelect).toHaveBeenCalledWith('πŸ‘ŽπŸΌ', false);\n });\n\n it('closes a stale popup on result changes and resumes grid controls', async () => {\n const { update, onSelect, container } = await setup();\n update('thumbs');\n key('Enter', true);\n expect(container.querySelector('[data-skin-tone]')).not.toBeNull();\n update('cat');\n expect(container.querySelector('[data-skin-tone]')).toBeNull();\n key('ArrowRight');\n key('Enter');\n expect(onSelect).toHaveBeenCalledTimes(1);\n expect(onSelect).toHaveBeenCalledWith('🐈', true);\n });\n\n it('dismisses the old popup even when its emoji remains in a smaller result list', async () => {\n const { update, onSelect, container } = await setup();\n update('thumbs');\n fireEvent.contextMenu(container.querySelector('[data-emoji=\"πŸ‘\"]')!);\n expect(container.querySelector('[data-skin-tone]')).not.toBeNull();\n update('thumbs up');\n expect(container.querySelector('[data-skin-tone]')).toBeNull();\n selected(container.querySelector('[data-emoji=\"πŸ‘\"]')!);\n key('Enter');\n expect(onSelect).toHaveBeenCalledTimes(1);\n expect(onSelect).toHaveBeenCalledWith('πŸ‘', true);\n });\n\n it('does not carry an unsupported Ctrl+Enter popup request to the next emoji', async () => {\n const { update, onSelect, container } = await setup();\n update('cat');\n key('Enter', true);\n update('thumbs');\n expect(container.querySelector('[data-skin-tone]')).toBeNull();\n key('ArrowRight');\n key('Enter');\n expect(onSelect).toHaveBeenCalledTimes(1);\n expect(onSelect).toHaveBeenCalledWith('πŸ‘Ž', true);\n });\n\n it('keeps navigation stable when history is returned as a fresh array', async () => {\n fixtures.history = fixtures.emojis.slice(0, 3);\n const { update, onSelect, container } = await setup();\n update('', 'history');\n key('ArrowRight');\n update('', 'history');\n key('ArrowRight');\n selected(container.querySelector('[data-emoji=\"πŸ˜„\"]')!);\n expect(container.querySelectorAll('[data-emoji][tabindex=\"0\"]')).toHaveLength(1);\n key('Enter');\n expect(onSelect).toHaveBeenCalledTimes(1);\n expect(onSelect).toHaveBeenCalledWith('πŸ˜„', true);\n });\n\n it('clears a search popup when returning to history with the same visible emoji', async () => {\n fixtures.history = [fixtures.emojis[4]!];\n const { update, container } = await setup();\n update('thumbs up', 'history');\n key('Enter', true);\n expect(container.querySelector('[data-skin-tone]')).not.toBeNull();\n update('', 'history');\n expect(container.querySelector('[data-skin-tone]')).toBeNull();\n key('Enter', true);\n expect(container.querySelector('[data-skin-tone]')).toBeNull();\n });\n\n it('keeps normal six-column keyboard navigation and history callbacks', async () => {\n const { onSelect, container } = await setup();\n key('ArrowDown');\n selected(container.querySelector('[data-emoji=\"πŸ‘‹\"]')!);\n key('Enter');\n expect(onSelect).toHaveBeenCalledTimes(1);\n expect(onSelect).toHaveBeenCalledWith('πŸ‘‹', true);\n expect(fixtures.addHistory).toHaveBeenCalledTimes(1);\n expect(fixtures.addHistory).toHaveBeenCalledWith({\n emoji: 'πŸ‘‹',\n name: 'waving hand',\n skin_tone_support: true,\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
@@ -112,6 +112,7 @@ const Emoji = ({
112
112
  return /*#__PURE__*/React.createElement(StyledEmoji, {
113
113
  ref: emojiRef,
114
114
  $isSelected: isSelected,
115
+ tabIndex: isSelected ? 0 : -1,
115
116
  "data-emoji": emoji,
116
117
  "data-name": name,
117
118
  "data-skin-tone-support": isSkinToneSupported,
@@ -1 +1 @@
1
- {"version":3,"file":"Emoji.js","names":["AnimatePresence","React","useCallback","useEffect","useRef","useState","AnchorAlignment","StyledEmoji","SkinTonePopup","skinTonePopupContentSize","Emoji","emoji","isSelected","name","isSkinToneSupported","onPopupVisibilityChange","onSelect","shouldShowSkinTonePopup","onRightClick","index","emojiList","shouldShowPopup","setShouldShowPopup","skinTonePopupAnchorAlignment","setSkinTonePopupAnchorAlignment","Top","skinTonePopupAnchorOffset","setSkinTonePopupAnchorOffset","skinTonePopupOverlayPosition","setSkinTonePopupOverlayPosition","top","skinTonePopupPosition","setSkinTonePopupPosition","left","emojiRef","handleClick","calculatePopupPosition","current","element","parentElement","height","elementHeight","elementLeft","elementTop","width","elementWidth","getBoundingClientRect","parentHeight","parentLeft","parentTop","parentWidth","scrollTop","anchorAlignment","anchorOffset","maxLeft","minLeft","Bottom","handleContextMenu","event","preventDefault","stopPropagation","handleHidePopup","createElement","ref","$isSelected","className","onClick","onContextMenu","initial","key","onHidePopup","overlayPosition","position","displayName"],"sources":["../../../../../../src/components/emoji-picker/emoji-picker-emojis/emoji/Emoji.tsx"],"sourcesContent":["import { AnimatePresence } from 'motion/react';\nimport React, { FC, MouseEvent, useCallback, useEffect, useRef, useState } from 'react';\nimport { AnchorAlignment } from '../../../../constants/alignment';\nimport { StyledEmoji } from './Emoji.styles';\nimport SkinTonePopup, { SkinTonePopupProps } from './skin-tone-popup/SkinTonePopup';\nimport { skinTonePopupContentSize } from './skin-tone-popup/SkinTonePopup.styles';\n\nexport type EmojiProps = {\n emoji: string;\n isSelected: boolean;\n name: string;\n index: number;\n isSkinToneSupported: boolean;\n onPopupVisibilityChange: (isVisible: boolean) => void;\n onSelect: (emoji: string) => void;\n onRightClick: (newIndex: number) => void;\n shouldShowSkinTonePopup: boolean;\n emojiList: { [x: string]: { skin_tone_support: any } };\n};\n\nconst Emoji: FC<EmojiProps> = ({\n emoji,\n isSelected,\n name,\n isSkinToneSupported,\n onPopupVisibilityChange,\n onSelect,\n shouldShowSkinTonePopup,\n onRightClick,\n index,\n emojiList,\n}) => {\n const [shouldShowPopup, setShouldShowPopup] = useState(false);\n const [skinTonePopupAnchorAlignment, setSkinTonePopupAnchorAlignment] = useState(\n AnchorAlignment.Top,\n );\n const [skinTonePopupAnchorOffset, setSkinTonePopupAnchorOffset] = useState(0);\n const [skinTonePopupOverlayPosition, setSkinTonePopupOverlayPosition] = useState<\n SkinTonePopupProps['overlayPosition']\n >({ top: 0 });\n const [skinTonePopupPosition, setSkinTonePopupPosition] = useState<\n SkinTonePopupProps['position']\n >({ left: 0, top: 0 });\n\n const emojiRef = useRef<HTMLDivElement>(null);\n\n const handleClick = useCallback(() => {\n onSelect(emoji);\n }, [emoji, onSelect]);\n\n const calculatePopupPosition = useCallback(() => {\n if (!emojiRef.current) {\n return;\n }\n\n const element = emojiRef.current;\n const { parentElement } = emojiRef.current;\n\n if (parentElement) {\n const {\n height: elementHeight,\n left: elementLeft,\n top: elementTop,\n width: elementWidth,\n } = element.getBoundingClientRect();\n\n const {\n height: parentHeight,\n left: parentLeft,\n top: parentTop,\n width: parentWidth,\n } = parentElement.getBoundingClientRect();\n\n const { scrollTop } = parentElement;\n\n let anchorAlignment = AnchorAlignment.Top;\n let anchorOffset = 0;\n\n let left =\n elementLeft - parentLeft - skinTonePopupContentSize.width / 2 + elementWidth / 2;\n\n let top = elementTop - parentTop + elementHeight + scrollTop;\n\n const maxLeft = parentWidth - skinTonePopupContentSize.width - 12;\n const minLeft = 12;\n\n if (left < minLeft) {\n anchorOffset = left - minLeft;\n left = minLeft;\n } else if (left > maxLeft) {\n anchorOffset = left - maxLeft;\n left = maxLeft;\n }\n\n if (top + skinTonePopupContentSize.height > parentHeight + scrollTop) {\n anchorAlignment = AnchorAlignment.Bottom;\n top -= elementHeight + skinTonePopupContentSize.height;\n }\n\n if (isSkinToneSupported) {\n setSkinTonePopupAnchorAlignment(anchorAlignment);\n setSkinTonePopupAnchorOffset(anchorOffset);\n setSkinTonePopupPosition({ left, top });\n setSkinTonePopupOverlayPosition({ top: scrollTop });\n setShouldShowPopup(true);\n }\n }\n }, [isSkinToneSupported]);\n\n const handleContextMenu = useCallback(\n (event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n if (isSkinToneSupported) {\n onRightClick(index);\n calculatePopupPosition();\n }\n },\n [calculatePopupPosition, index, isSkinToneSupported, onRightClick],\n );\n\n useEffect(() => {\n if (\n emojiRef.current &&\n shouldShowSkinTonePopup &&\n skinTonePopupPosition.top === 0 &&\n skinTonePopupPosition.left === 0\n ) {\n calculatePopupPosition();\n }\n }, [\n calculatePopupPosition,\n index,\n isSkinToneSupported,\n shouldShowSkinTonePopup,\n skinTonePopupPosition,\n ]);\n\n useEffect(() => {\n if (shouldShowSkinTonePopup) {\n setShouldShowPopup(shouldShowSkinTonePopup);\n }\n }, [shouldShowSkinTonePopup]);\n\n const handleHidePopup = useCallback(() => {\n setShouldShowPopup(false);\n }, []);\n\n useEffect(() => {\n onPopupVisibilityChange(shouldShowPopup);\n }, [onPopupVisibilityChange, shouldShowPopup]);\n\n return (\n <StyledEmoji\n ref={emojiRef}\n $isSelected={isSelected}\n data-emoji={emoji}\n data-name={name}\n data-skin-tone-support={isSkinToneSupported}\n className=\"prevent-lose-focus\"\n onClick={handleClick}\n onContextMenu={handleContextMenu}\n >\n {emoji}\n <AnimatePresence initial={false}>\n {shouldShowPopup && (\n <SkinTonePopup\n anchorAlignment={skinTonePopupAnchorAlignment}\n anchorOffset={skinTonePopupAnchorOffset}\n emoji={emoji}\n key={emoji}\n onHidePopup={handleHidePopup}\n onSelect={onSelect}\n overlayPosition={skinTonePopupOverlayPosition}\n position={skinTonePopupPosition}\n emojiList={emojiList}\n />\n )}\n </AnimatePresence>\n </StyledEmoji>\n );\n};\n\nEmoji.displayName = 'Emoji';\n\nexport default Emoji;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"Emoji.js","names":["AnimatePresence","React","useCallback","useEffect","useRef","useState","AnchorAlignment","StyledEmoji","SkinTonePopup","skinTonePopupContentSize","Emoji","emoji","isSelected","name","isSkinToneSupported","onPopupVisibilityChange","onSelect","shouldShowSkinTonePopup","onRightClick","index","emojiList","shouldShowPopup","setShouldShowPopup","skinTonePopupAnchorAlignment","setSkinTonePopupAnchorAlignment","Top","skinTonePopupAnchorOffset","setSkinTonePopupAnchorOffset","skinTonePopupOverlayPosition","setSkinTonePopupOverlayPosition","top","skinTonePopupPosition","setSkinTonePopupPosition","left","emojiRef","handleClick","calculatePopupPosition","current","element","parentElement","height","elementHeight","elementLeft","elementTop","width","elementWidth","getBoundingClientRect","parentHeight","parentLeft","parentTop","parentWidth","scrollTop","anchorAlignment","anchorOffset","maxLeft","minLeft","Bottom","handleContextMenu","event","preventDefault","stopPropagation","handleHidePopup","createElement","ref","$isSelected","tabIndex","className","onClick","onContextMenu","initial","key","onHidePopup","overlayPosition","position","displayName"],"sources":["../../../../../../src/components/emoji-picker/emoji-picker-emojis/emoji/Emoji.tsx"],"sourcesContent":["import { AnimatePresence } from 'motion/react';\nimport React, { FC, MouseEvent, useCallback, useEffect, useRef, useState } from 'react';\nimport { AnchorAlignment } from '../../../../constants/alignment';\nimport { StyledEmoji } from './Emoji.styles';\nimport SkinTonePopup, { SkinTonePopupProps } from './skin-tone-popup/SkinTonePopup';\nimport { skinTonePopupContentSize } from './skin-tone-popup/SkinTonePopup.styles';\n\nexport type EmojiProps = {\n emoji: string;\n isSelected: boolean;\n name: string;\n index: number;\n isSkinToneSupported: boolean;\n onPopupVisibilityChange: (isVisible: boolean) => void;\n onSelect: (emoji: string) => void;\n onRightClick: (newIndex: number) => void;\n shouldShowSkinTonePopup: boolean;\n emojiList: { [x: string]: { skin_tone_support: any } };\n};\n\nconst Emoji: FC<EmojiProps> = ({\n emoji,\n isSelected,\n name,\n isSkinToneSupported,\n onPopupVisibilityChange,\n onSelect,\n shouldShowSkinTonePopup,\n onRightClick,\n index,\n emojiList,\n}) => {\n const [shouldShowPopup, setShouldShowPopup] = useState(false);\n const [skinTonePopupAnchorAlignment, setSkinTonePopupAnchorAlignment] = useState(\n AnchorAlignment.Top,\n );\n const [skinTonePopupAnchorOffset, setSkinTonePopupAnchorOffset] = useState(0);\n const [skinTonePopupOverlayPosition, setSkinTonePopupOverlayPosition] = useState<\n SkinTonePopupProps['overlayPosition']\n >({ top: 0 });\n const [skinTonePopupPosition, setSkinTonePopupPosition] = useState<\n SkinTonePopupProps['position']\n >({ left: 0, top: 0 });\n\n const emojiRef = useRef<HTMLDivElement>(null);\n\n const handleClick = useCallback(() => {\n onSelect(emoji);\n }, [emoji, onSelect]);\n\n const calculatePopupPosition = useCallback(() => {\n if (!emojiRef.current) {\n return;\n }\n\n const element = emojiRef.current;\n const { parentElement } = emojiRef.current;\n\n if (parentElement) {\n const {\n height: elementHeight,\n left: elementLeft,\n top: elementTop,\n width: elementWidth,\n } = element.getBoundingClientRect();\n\n const {\n height: parentHeight,\n left: parentLeft,\n top: parentTop,\n width: parentWidth,\n } = parentElement.getBoundingClientRect();\n\n const { scrollTop } = parentElement;\n\n let anchorAlignment = AnchorAlignment.Top;\n let anchorOffset = 0;\n\n let left =\n elementLeft - parentLeft - skinTonePopupContentSize.width / 2 + elementWidth / 2;\n\n let top = elementTop - parentTop + elementHeight + scrollTop;\n\n const maxLeft = parentWidth - skinTonePopupContentSize.width - 12;\n const minLeft = 12;\n\n if (left < minLeft) {\n anchorOffset = left - minLeft;\n left = minLeft;\n } else if (left > maxLeft) {\n anchorOffset = left - maxLeft;\n left = maxLeft;\n }\n\n if (top + skinTonePopupContentSize.height > parentHeight + scrollTop) {\n anchorAlignment = AnchorAlignment.Bottom;\n top -= elementHeight + skinTonePopupContentSize.height;\n }\n\n if (isSkinToneSupported) {\n setSkinTonePopupAnchorAlignment(anchorAlignment);\n setSkinTonePopupAnchorOffset(anchorOffset);\n setSkinTonePopupPosition({ left, top });\n setSkinTonePopupOverlayPosition({ top: scrollTop });\n setShouldShowPopup(true);\n }\n }\n }, [isSkinToneSupported]);\n\n const handleContextMenu = useCallback(\n (event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n if (isSkinToneSupported) {\n onRightClick(index);\n calculatePopupPosition();\n }\n },\n [calculatePopupPosition, index, isSkinToneSupported, onRightClick],\n );\n\n useEffect(() => {\n if (\n emojiRef.current &&\n shouldShowSkinTonePopup &&\n skinTonePopupPosition.top === 0 &&\n skinTonePopupPosition.left === 0\n ) {\n calculatePopupPosition();\n }\n }, [\n calculatePopupPosition,\n index,\n isSkinToneSupported,\n shouldShowSkinTonePopup,\n skinTonePopupPosition,\n ]);\n\n useEffect(() => {\n if (shouldShowSkinTonePopup) {\n setShouldShowPopup(shouldShowSkinTonePopup);\n }\n }, [shouldShowSkinTonePopup]);\n\n const handleHidePopup = useCallback(() => {\n setShouldShowPopup(false);\n }, []);\n\n useEffect(() => {\n onPopupVisibilityChange(shouldShowPopup);\n }, [onPopupVisibilityChange, shouldShowPopup]);\n\n return (\n <StyledEmoji\n ref={emojiRef}\n $isSelected={isSelected}\n tabIndex={isSelected ? 0 : -1}\n data-emoji={emoji}\n data-name={name}\n data-skin-tone-support={isSkinToneSupported}\n className=\"prevent-lose-focus\"\n onClick={handleClick}\n onContextMenu={handleContextMenu}\n >\n {emoji}\n <AnimatePresence initial={false}>\n {shouldShowPopup && (\n <SkinTonePopup\n anchorAlignment={skinTonePopupAnchorAlignment}\n anchorOffset={skinTonePopupAnchorOffset}\n emoji={emoji}\n key={emoji}\n onHidePopup={handleHidePopup}\n onSelect={onSelect}\n overlayPosition={skinTonePopupOverlayPosition}\n position={skinTonePopupPosition}\n emojiList={emojiList}\n />\n )}\n </AnimatePresence>\n </StyledEmoji>\n );\n};\n\nEmoji.displayName = 'Emoji';\n\nexport default Emoji;\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,101 @@
1
+ import { useCombinedRefs, useIsMeasuredClone } from '@chayns-components/core';
2
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
3
+ import Emoji from '../emoji/Emoji';
4
+ import { StyledEmojiPickerEmojis, StyledEmojiPickerEmojisNoContentInfo } from '../EmojiPickerEmojis.styles';
5
+ const EMOJIS_PER_ROW = 6;
6
+ const EmojiPickerEmojiList = ({
7
+ emojis,
8
+ emojiList,
9
+ isHistory,
10
+ onSelect
11
+ }) => {
12
+ const [shouldPreventListener, ref] = useIsMeasuredClone();
13
+ const [focusedIndex, setFocusedIndex] = useState(0);
14
+ const [shouldShowSkinTonePopup, setShouldShowSkinTonePopup] = useState(false);
15
+ const emojiRef = useRef(null);
16
+ const shouldPreventEmojiControlsRef = useRef(false);
17
+ const combinedRef = useCombinedRefs(emojiRef, ref);
18
+ const handlePopupVisibilityChange = useCallback(isVisible => {
19
+ setShouldShowSkinTonePopup(isVisible);
20
+ shouldPreventEmojiControlsRef.current = isVisible;
21
+ }, []);
22
+ const handleSelect = useCallback((emoji, index, shouldRestoreInputFocus = false) => {
23
+ setFocusedIndex(index);
24
+ onSelect(emoji, shouldRestoreInputFocus);
25
+ }, [onSelect]);
26
+ useEffect(() => {
27
+ const handleKeyDown = event => {
28
+ if (shouldPreventListener || shouldPreventEmojiControlsRef.current) return;
29
+ const isArrowKey = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key);
30
+ if (!isArrowKey && event.key !== 'Enter') return;
31
+ const container = emojiRef.current;
32
+ const elements = container?.querySelectorAll(':scope > [data-emoji]');
33
+ const currentElement = elements?.[focusedIndex];
34
+ if (event.key === 'Enter') {
35
+ if (!currentElement) return;
36
+ const {
37
+ emoji,
38
+ name,
39
+ skinToneSupport
40
+ } = currentElement.dataset;
41
+ if (!emoji || !name || !skinToneSupport) return;
42
+ if (event.ctrlKey) {
43
+ if (skinToneSupport === 'true') handlePopupVisibilityChange(true);
44
+ return;
45
+ }
46
+ handleSelect({
47
+ emoji,
48
+ name,
49
+ skin_tone_support: skinToneSupport === 'true'
50
+ }, focusedIndex, true);
51
+ return;
52
+ }
53
+ event.preventDefault();
54
+ if (event.ctrlKey || !container || !elements?.length) return;
55
+ let newIndex = currentElement ? focusedIndex : 0;
56
+ if (event.key === 'ArrowUp') newIndex = (newIndex - EMOJIS_PER_ROW) % elements.length;else if (event.key === 'ArrowDown') newIndex = (newIndex + EMOJIS_PER_ROW) % elements.length;else if (event.key === 'ArrowLeft') newIndex = (newIndex - 1) % elements.length;else newIndex = (newIndex + 1) % elements.length;
57
+ if (newIndex < 0) newIndex = elements.length - 1;
58
+ const newElement = elements[newIndex];
59
+ if (!newElement) return;
60
+ setFocusedIndex(newIndex);
61
+ const containerRect = container.getBoundingClientRect();
62
+ const elementRect = newElement.getBoundingClientRect();
63
+ if (elementRect.bottom > containerRect.bottom) {
64
+ container.scrollTop += elementRect.bottom - containerRect.bottom;
65
+ } else if (elementRect.top < containerRect.top) {
66
+ container.scrollTop -= containerRect.top - elementRect.top;
67
+ }
68
+ };
69
+ document.addEventListener('keydown', handleKeyDown);
70
+ return () => document.removeEventListener('keydown', handleKeyDown);
71
+ }, [focusedIndex, handlePopupVisibilityChange, handleSelect, shouldPreventListener]);
72
+ const shouldShowNoContentInfo = emojis.length === 0;
73
+ return /*#__PURE__*/React.createElement(StyledEmojiPickerEmojis, {
74
+ className: "chayns-scrollbar",
75
+ $shouldPreventScroll: shouldShowSkinTonePopup,
76
+ $shouldShowNoContentInfo: shouldShowNoContentInfo,
77
+ ref: combinedRef
78
+ }, emojis.map(({
79
+ emoji,
80
+ name,
81
+ skin_tone_support
82
+ }, index) => /*#__PURE__*/React.createElement(Emoji, {
83
+ key: emoji,
84
+ emoji: emoji,
85
+ name: name,
86
+ index: index,
87
+ isSelected: index === focusedIndex,
88
+ isSkinToneSupported: !isHistory && skin_tone_support,
89
+ shouldShowSkinTonePopup: index === focusedIndex && !isHistory && skin_tone_support && shouldShowSkinTonePopup,
90
+ onRightClick: setFocusedIndex,
91
+ onPopupVisibilityChange: handlePopupVisibilityChange,
92
+ onSelect: selectedEmoji => handleSelect({
93
+ emoji: selectedEmoji,
94
+ name,
95
+ skin_tone_support
96
+ }, index),
97
+ emojiList: emojiList
98
+ })), shouldShowNoContentInfo && /*#__PURE__*/React.createElement(StyledEmojiPickerEmojisNoContentInfo, null, "Hier werden die zuletzt verwendeten Emojis angezeigt, die \xFCber diese Auswahl gew\xE4hlt wurden."));
99
+ };
100
+ export default EmojiPickerEmojiList;
101
+ //# sourceMappingURL=EmojiPickerEmojiList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmojiPickerEmojiList.js","names":["useCombinedRefs","useIsMeasuredClone","React","useCallback","useEffect","useRef","useState","Emoji","StyledEmojiPickerEmojis","StyledEmojiPickerEmojisNoContentInfo","EMOJIS_PER_ROW","EmojiPickerEmojiList","emojis","emojiList","isHistory","onSelect","shouldPreventListener","ref","focusedIndex","setFocusedIndex","shouldShowSkinTonePopup","setShouldShowSkinTonePopup","emojiRef","shouldPreventEmojiControlsRef","combinedRef","handlePopupVisibilityChange","isVisible","current","handleSelect","emoji","index","shouldRestoreInputFocus","handleKeyDown","event","isArrowKey","includes","key","container","elements","querySelectorAll","currentElement","name","skinToneSupport","dataset","ctrlKey","skin_tone_support","preventDefault","length","newIndex","newElement","containerRect","getBoundingClientRect","elementRect","bottom","scrollTop","top","document","addEventListener","removeEventListener","shouldShowNoContentInfo","createElement","className","$shouldPreventScroll","$shouldShowNoContentInfo","map","isSelected","isSkinToneSupported","onRightClick","onPopupVisibilityChange","selectedEmoji"],"sources":["../../../../../../src/components/emoji-picker/emoji-picker-emojis/emoji-picker-emoji-list/EmojiPickerEmojiList.tsx"],"sourcesContent":["import { useCombinedRefs, useIsMeasuredClone } from '@chayns-components/core';\nimport React, { FC, useCallback, useEffect, useRef, useState } from 'react';\nimport Emoji, { type EmojiProps } from '../emoji/Emoji';\nimport {\n StyledEmojiPickerEmojis,\n StyledEmojiPickerEmojisNoContentInfo,\n} from '../EmojiPickerEmojis.styles';\n\nexport interface PickerEmoji {\n emoji: string;\n name: string;\n skin_tone_support: boolean;\n}\n\ninterface EmojiPickerEmojiListProps {\n emojis: PickerEmoji[];\n emojiList: EmojiProps['emojiList'];\n isHistory: boolean;\n onSelect: (emoji: PickerEmoji, shouldRestoreInputFocus?: boolean) => void;\n}\n\nconst EMOJIS_PER_ROW = 6;\n\nconst EmojiPickerEmojiList: FC<EmojiPickerEmojiListProps> = ({\n emojis,\n emojiList,\n isHistory,\n onSelect,\n}) => {\n const [shouldPreventListener, ref] = useIsMeasuredClone<HTMLDivElement>();\n const [focusedIndex, setFocusedIndex] = useState(0);\n const [shouldShowSkinTonePopup, setShouldShowSkinTonePopup] = useState(false);\n const emojiRef = useRef<HTMLDivElement>(null);\n const shouldPreventEmojiControlsRef = useRef(false);\n const combinedRef = useCombinedRefs(emojiRef, ref);\n\n const handlePopupVisibilityChange = useCallback((isVisible: boolean) => {\n setShouldShowSkinTonePopup(isVisible);\n shouldPreventEmojiControlsRef.current = isVisible;\n }, []);\n\n const handleSelect = useCallback(\n (emoji: PickerEmoji, index: number, shouldRestoreInputFocus = false) => {\n setFocusedIndex(index);\n onSelect(emoji, shouldRestoreInputFocus);\n },\n [onSelect],\n );\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (shouldPreventListener || shouldPreventEmojiControlsRef.current) return;\n\n const isArrowKey = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(\n event.key,\n );\n if (!isArrowKey && event.key !== 'Enter') return;\n\n const container = emojiRef.current;\n const elements = container?.querySelectorAll<HTMLDivElement>(':scope > [data-emoji]');\n const currentElement = elements?.[focusedIndex];\n\n if (event.key === 'Enter') {\n if (!currentElement) return;\n\n const { emoji, name, skinToneSupport } = currentElement.dataset;\n if (!emoji || !name || !skinToneSupport) return;\n\n if (event.ctrlKey) {\n if (skinToneSupport === 'true') handlePopupVisibilityChange(true);\n return;\n }\n\n handleSelect(\n { emoji, name, skin_tone_support: skinToneSupport === 'true' },\n focusedIndex,\n true,\n );\n return;\n }\n\n event.preventDefault();\n if (event.ctrlKey || !container || !elements?.length) return;\n\n let newIndex = currentElement ? focusedIndex : 0;\n if (event.key === 'ArrowUp') newIndex = (newIndex - EMOJIS_PER_ROW) % elements.length;\n else if (event.key === 'ArrowDown')\n newIndex = (newIndex + EMOJIS_PER_ROW) % elements.length;\n else if (event.key === 'ArrowLeft') newIndex = (newIndex - 1) % elements.length;\n else newIndex = (newIndex + 1) % elements.length;\n\n if (newIndex < 0) newIndex = elements.length - 1;\n\n const newElement = elements[newIndex];\n if (!newElement) return;\n\n setFocusedIndex(newIndex);\n\n const containerRect = container.getBoundingClientRect();\n const elementRect = newElement.getBoundingClientRect();\n\n if (elementRect.bottom > containerRect.bottom) {\n container.scrollTop += elementRect.bottom - containerRect.bottom;\n } else if (elementRect.top < containerRect.top) {\n container.scrollTop -= containerRect.top - elementRect.top;\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [focusedIndex, handlePopupVisibilityChange, handleSelect, shouldPreventListener]);\n\n const shouldShowNoContentInfo = emojis.length === 0;\n\n return (\n <StyledEmojiPickerEmojis\n className=\"chayns-scrollbar\"\n $shouldPreventScroll={shouldShowSkinTonePopup}\n $shouldShowNoContentInfo={shouldShowNoContentInfo}\n ref={combinedRef}\n >\n {emojis.map(({ emoji, name, skin_tone_support }, index) => (\n <Emoji\n key={emoji}\n emoji={emoji}\n name={name}\n index={index}\n isSelected={index === focusedIndex}\n isSkinToneSupported={!isHistory && skin_tone_support}\n shouldShowSkinTonePopup={\n index === focusedIndex &&\n !isHistory &&\n skin_tone_support &&\n shouldShowSkinTonePopup\n }\n onRightClick={setFocusedIndex}\n onPopupVisibilityChange={handlePopupVisibilityChange}\n onSelect={(selectedEmoji) =>\n handleSelect({ emoji: selectedEmoji, name, skin_tone_support }, index)\n }\n emojiList={emojiList}\n />\n ))}\n {shouldShowNoContentInfo && (\n <StyledEmojiPickerEmojisNoContentInfo>\n Hier werden die zuletzt verwendeten Emojis angezeigt, die ΓΌber diese Auswahl\n gewΓ€hlt wurden.\n </StyledEmojiPickerEmojisNoContentInfo>\n )}\n </StyledEmojiPickerEmojis>\n );\n};\n\nexport default EmojiPickerEmojiList;\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,15 @@
1
+ import { FC } from 'react';
2
+ import { type EmojiProps } from '../emoji/Emoji';
3
+ export interface PickerEmoji {
4
+ emoji: string;
5
+ name: string;
6
+ skin_tone_support: boolean;
7
+ }
8
+ interface EmojiPickerEmojiListProps {
9
+ emojis: PickerEmoji[];
10
+ emojiList: EmojiProps['emojiList'];
11
+ isHistory: boolean;
12
+ onSelect: (emoji: PickerEmoji, shouldRestoreInputFocus?: boolean) => void;
13
+ }
14
+ declare const EmojiPickerEmojiList: FC<EmojiPickerEmojiListProps>;
15
+ export default EmojiPickerEmojiList;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chayns-components/emoji-input",
3
- "version": "5.6.6",
3
+ "version": "5.6.8",
4
4
  "description": "Input field that supports HTML elements and emojis",
5
5
  "sideEffects": false,
6
6
  "browserslist": [
@@ -91,5 +91,5 @@
91
91
  "publishConfig": {
92
92
  "access": "public"
93
93
  },
94
- "gitHead": "9ef8867c1e39db865556e9c2f285771b7cf34e90"
94
+ "gitHead": "9d888b15d6d4bf4a420ae01c3df46e177de27886"
95
95
  }
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};