@chayns-components/emoji-input 5.0.0-beta.122 → 5.0.0-beta.124

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.
@@ -40,19 +40,17 @@ const EmojiInput = _ref => {
40
40
  * When updating the HTML, the current cursor position is saved before replacing the content, so
41
41
  * that it can be set again afterward.
42
42
  */
43
- const handleUpdateText = (0, _react.useCallback)(text => {
43
+ const handleUpdateHTML = (0, _react.useCallback)(html => {
44
44
  if (!editorRef.current) {
45
45
  return;
46
46
  }
47
- const newInnerText = (0, _emoji.convertEmojisToUnicode)(text);
48
- const convertedQuotes = (0, _text.convertQuotes)(newInnerText);
49
- if (convertedQuotes !== editorRef.current.innerText) {
47
+ let newInnerHTML = (0, _emoji.convertEmojisToUnicode)(html);
48
+ newInnerHTML = (0, _text.convertBBCodes)(newInnerHTML);
49
+ // newInnerHTML = convertQuotes(newInnerHTML);
50
+
51
+ if (newInnerHTML !== editorRef.current.innerHTML) {
50
52
  (0, _selection.saveSelection)(editorRef.current);
51
- console.debug('TEST', {
52
- innerText: editorRef.current.innerText,
53
- convertedQuotes
54
- });
55
- editorRef.current.innerText = convertedQuotes;
53
+ editorRef.current.innerHTML = newInnerHTML;
56
54
  (0, _selection.restoreSelection)(editorRef.current);
57
55
  }
58
56
  }, []);
@@ -65,11 +63,11 @@ const EmojiInput = _ref => {
65
63
  if (!editorRef.current) {
66
64
  return;
67
65
  }
68
- handleUpdateText(editorRef.current.innerText);
66
+ handleUpdateHTML(editorRef.current.innerHTML);
69
67
  if (typeof onInput === 'function') {
70
68
  onInput(event);
71
69
  }
72
- }, [handleUpdateText, onInput]);
70
+ }, [handleUpdateHTML, onInput]);
73
71
 
74
72
  /**
75
73
  * This function prevents formatting from being adopted when texts are inserted. To do this, the
@@ -131,8 +129,8 @@ const EmojiInput = _ref => {
131
129
  }
132
130
  }, []);
133
131
  (0, _react.useEffect)(() => {
134
- handleUpdateText(value);
135
- }, [handleUpdateText, value]);
132
+ handleUpdateHTML(value);
133
+ }, [handleUpdateHTML, value]);
136
134
  (0, _react.useEffect)(() => {
137
135
  document.body.addEventListener('mousedown', handlePreventLoseFocus);
138
136
  return () => {
@@ -1 +1 @@
1
- {"version":3,"file":"EmojiInput.js","names":["_react","_interopRequireWildcard","require","_emoji","_environment","_insert","_selection","_text","_EmojiPickerPopup","_interopRequireDefault","_EmojiInput","obj","__esModule","default","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","EmojiInput","_ref","accessToken","inputId","isDisabled","onInput","onKeyDown","onPopupVisibilityChange","personId","placeholder","popupAlignment","rightElement","value","isMobile","useState","getIsMobile","editorRef","useRef","handleUpdateText","useCallback","text","current","newInnerText","convertEmojisToUnicode","convertedQuotes","convertQuotes","innerText","saveSelection","console","debug","restoreSelection","handleInput","event","handlePaste","preventDefault","clipboardData","getData","insertTextAtCursorPosition","editorElement","newEvent","Event","bubbles","dispatchEvent","handlePopupSelect","emoji","handlePreventLoseFocus","_element$parentElemen","element","target","classList","contains","parentElement","stopPropagation","useEffect","document","body","addEventListener","removeEventListener","createElement","StyledEmojiInput","StyledEmojiInputContent","isRightElementGiven","StyledEmojiInputEditor","contentEditable","id","onPaste","ref","alignment","onSelect","StyledEmojiInputRightWrapper","displayName","_default","exports"],"sources":["../../../src/components/emoji-input/EmojiInput.tsx"],"sourcesContent":["import React, {\n ChangeEvent,\n ChangeEventHandler,\n ClipboardEvent,\n FC,\n KeyboardEventHandler,\n ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport type { PopupAlignment } from '../../constants/alignment';\nimport { convertEmojisToUnicode } from '../../utils/emoji';\nimport { getIsMobile } from '../../utils/environment';\nimport { insertTextAtCursorPosition } from '../../utils/insert';\nimport { restoreSelection, saveSelection } from '../../utils/selection';\nimport { convertQuotes } from '../../utils/text';\nimport EmojiPickerPopup from '../emoji-picker-popup/EmojiPickerPopup';\nimport {\n StyledEmojiInput,\n StyledEmojiInputContent,\n StyledEmojiInputEditor,\n StyledEmojiInputRightWrapper,\n} from './EmojiInput.styles';\n\nexport type EmojiInputProps = {\n /**\n * Access token of the logged-in user. Is needed to load and save the history of the emojis.\n */\n accessToken?: string;\n /**\n * HTML id of the input element\n */\n inputId?: string;\n /**\n * Disables the input so that it cannot be changed anymore\n */\n isDisabled?: boolean;\n /**\n * Function that is executed when the text of the input changes\n */\n onInput?: ChangeEventHandler<HTMLDivElement>;\n /**\n * Function that is executed when a key is pressed down.\n */\n onKeyDown?: KeyboardEventHandler<HTMLDivElement>;\n /**\n * Function that is executed when the visibility of the popup changes.\n * @param {boolean} isVisible - Whether the popup is visible or not\n */\n onPopupVisibilityChange?: (isVisible: boolean) => void;\n /**\n * Person id of the logged-in user. Is needed to load and save the history of the emojis.\n */\n personId?: string;\n /**\n * Placeholder for the input field\n */\n placeholder?: string;\n /**\n * Sets the alignment of the popup to a fixed value. If this value is not set, the component\n * calculates the best position on its own. Use the imported 'PopupAlignment' enum to set this\n * value.\n */\n popupAlignment?: PopupAlignment;\n /**\n * Element that is rendered inside the EmojiInput on the right side.\n */\n rightElement?: ReactNode;\n /**\n * Value of the input field\n */\n value: string;\n};\n\nconst EmojiInput: FC<EmojiInputProps> = ({\n accessToken,\n inputId,\n isDisabled,\n onInput,\n onKeyDown,\n onPopupVisibilityChange,\n personId,\n placeholder,\n popupAlignment,\n rightElement,\n value,\n}) => {\n const [isMobile] = useState(getIsMobile());\n\n const editorRef = useRef<HTMLDivElement>(null);\n\n /**\n * This function updates the content of the 'contentEditable' element if the new text is\n * different from the previous content. So this is only true if, for example, a text like \":-)\"\n * has been replaced to the corresponding emoji.\n *\n * When updating the HTML, the current cursor position is saved before replacing the content, so\n * that it can be set again afterward.\n */\n const handleUpdateText = useCallback((text: string) => {\n if (!editorRef.current) {\n return;\n }\n\n const newInnerText = convertEmojisToUnicode(text);\n\n const convertedQuotes = convertQuotes(newInnerText);\n\n if (convertedQuotes !== editorRef.current.innerText) {\n saveSelection(editorRef.current);\n\n console.debug('TEST', {\n innerText: editorRef.current.innerText,\n convertedQuotes,\n });\n\n editorRef.current.innerText = convertedQuotes;\n\n restoreSelection(editorRef.current);\n }\n }, []);\n\n /**\n * This function handles the 'input' events of the 'contentEditable' element and also passes the\n * respective event up accordingly if the 'onInput' property is a function.\n */\n const handleInput = useCallback(\n (event: ChangeEvent<HTMLDivElement>) => {\n if (!editorRef.current) {\n return;\n }\n\n handleUpdateText(editorRef.current.innerText);\n\n if (typeof onInput === 'function') {\n onInput(event);\n }\n },\n [handleUpdateText, onInput]\n );\n\n /**\n * This function prevents formatting from being adopted when texts are inserted. To do this, the\n * plain text is read from the event after the default behavior has been prevented. The plain\n * text is then inserted at the correct position in the input field using the\n * 'insertTextAtCursorPosition' function.\n */\n const handlePaste = useCallback((event: ClipboardEvent<HTMLDivElement>) => {\n if (editorRef.current) {\n event.preventDefault();\n\n let text = event.clipboardData.getData('text/plain');\n\n text = convertEmojisToUnicode(text);\n\n insertTextAtCursorPosition({ editorElement: editorRef.current, text });\n\n const newEvent = new Event('input', { bubbles: true });\n\n editorRef.current.dispatchEvent(newEvent);\n }\n }, []);\n\n /**\n * This function uses the 'insertTextAtCursorPosition' function to insert the emoji at the\n * correct position in the editor element.\n *\n * At the end an 'input' event is dispatched, so that the function 'handleInput' is triggered,\n * which in turn executes the 'onInput' function from the props. So this serves to ensure that\n * the event is also passed through to the top when inserting via the popup.\n */\n const handlePopupSelect = useCallback((emoji: string) => {\n if (editorRef.current) {\n insertTextAtCursorPosition({ editorElement: editorRef.current, text: emoji });\n\n const event = new Event('input', { bubbles: true });\n\n editorRef.current.dispatchEvent(event);\n }\n }, []);\n\n /**\n * This function ensures that the input field does not lose focus when the popup is opened or an\n * emoji is selected in it. For this purpose the corresponding elements get the class\n * 'prevent-lose-focus'.\n *\n * The class can also be set to any other elements that should also not cause the input field to\n * lose focus.\n */\n const handlePreventLoseFocus = useCallback((event: MouseEvent) => {\n const element = event.target as Element;\n\n if (\n element.classList.contains('prevent-lose-focus') ||\n element.parentElement?.classList.contains('prevent-lose-focus')\n ) {\n event.preventDefault();\n event.stopPropagation();\n }\n }, []);\n\n useEffect(() => {\n handleUpdateText(value);\n }, [handleUpdateText, value]);\n\n useEffect(() => {\n document.body.addEventListener('mousedown', handlePreventLoseFocus);\n\n return () => {\n document.body.removeEventListener('mousedown', handlePreventLoseFocus);\n };\n }, [handlePreventLoseFocus]);\n\n return (\n <StyledEmojiInput isDisabled={isDisabled}>\n <StyledEmojiInputContent isRightElementGiven={!!rightElement}>\n <StyledEmojiInputEditor\n contentEditable={!isDisabled}\n id={inputId}\n onInput={handleInput}\n onKeyDown={onKeyDown}\n onPaste={handlePaste}\n placeholder={placeholder}\n ref={editorRef}\n />\n {!isMobile && (\n <EmojiPickerPopup\n accessToken={accessToken}\n alignment={popupAlignment}\n onSelect={handlePopupSelect}\n onPopupVisibilityChange={onPopupVisibilityChange}\n personId={personId}\n />\n )}\n </StyledEmojiInputContent>\n {rightElement && (\n <StyledEmojiInputRightWrapper>{rightElement}</StyledEmojiInputRightWrapper>\n )}\n </StyledEmojiInput>\n );\n};\n\nEmojiInput.displayName = 'EmojiInput';\n\nexport default EmojiInput;\n"],"mappings":"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"}
1
+ {"version":3,"file":"EmojiInput.js","names":["_react","_interopRequireWildcard","require","_emoji","_environment","_insert","_selection","_text","_EmojiPickerPopup","_interopRequireDefault","_EmojiInput","obj","__esModule","default","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","EmojiInput","_ref","accessToken","inputId","isDisabled","onInput","onKeyDown","onPopupVisibilityChange","personId","placeholder","popupAlignment","rightElement","value","isMobile","useState","getIsMobile","editorRef","useRef","handleUpdateHTML","useCallback","html","current","newInnerHTML","convertEmojisToUnicode","convertBBCodes","innerHTML","saveSelection","restoreSelection","handleInput","event","handlePaste","preventDefault","text","clipboardData","getData","insertTextAtCursorPosition","editorElement","newEvent","Event","bubbles","dispatchEvent","handlePopupSelect","emoji","handlePreventLoseFocus","_element$parentElemen","element","target","classList","contains","parentElement","stopPropagation","useEffect","document","body","addEventListener","removeEventListener","createElement","StyledEmojiInput","StyledEmojiInputContent","isRightElementGiven","StyledEmojiInputEditor","contentEditable","id","onPaste","ref","alignment","onSelect","StyledEmojiInputRightWrapper","displayName","_default","exports"],"sources":["../../../src/components/emoji-input/EmojiInput.tsx"],"sourcesContent":["import React, {\n ChangeEvent,\n ChangeEventHandler,\n ClipboardEvent,\n FC,\n KeyboardEventHandler,\n ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport type { PopupAlignment } from '../../constants/alignment';\nimport { convertEmojisToUnicode } from '../../utils/emoji';\nimport { getIsMobile } from '../../utils/environment';\nimport { insertTextAtCursorPosition } from '../../utils/insert';\nimport { restoreSelection, saveSelection } from '../../utils/selection';\nimport { convertBBCodes } from '../../utils/text';\nimport EmojiPickerPopup from '../emoji-picker-popup/EmojiPickerPopup';\nimport {\n StyledEmojiInput,\n StyledEmojiInputContent,\n StyledEmojiInputEditor,\n StyledEmojiInputRightWrapper,\n} from './EmojiInput.styles';\n\nexport type EmojiInputProps = {\n /**\n * Access token of the logged-in user. Is needed to load and save the history of the emojis.\n */\n accessToken?: string;\n /**\n * HTML id of the input element\n */\n inputId?: string;\n /**\n * Disables the input so that it cannot be changed anymore\n */\n isDisabled?: boolean;\n /**\n * Function that is executed when the text of the input changes\n */\n onInput?: ChangeEventHandler<HTMLDivElement>;\n /**\n * Function that is executed when a key is pressed down.\n */\n onKeyDown?: KeyboardEventHandler<HTMLDivElement>;\n /**\n * Function that is executed when the visibility of the popup changes.\n * @param {boolean} isVisible - Whether the popup is visible or not\n */\n onPopupVisibilityChange?: (isVisible: boolean) => void;\n /**\n * Person id of the logged-in user. Is needed to load and save the history of the emojis.\n */\n personId?: string;\n /**\n * Placeholder for the input field\n */\n placeholder?: string;\n /**\n * Sets the alignment of the popup to a fixed value. If this value is not set, the component\n * calculates the best position on its own. Use the imported 'PopupAlignment' enum to set this\n * value.\n */\n popupAlignment?: PopupAlignment;\n /**\n * Element that is rendered inside the EmojiInput on the right side.\n */\n rightElement?: ReactNode;\n /**\n * Value of the input field\n */\n value: string;\n};\n\nconst EmojiInput: FC<EmojiInputProps> = ({\n accessToken,\n inputId,\n isDisabled,\n onInput,\n onKeyDown,\n onPopupVisibilityChange,\n personId,\n placeholder,\n popupAlignment,\n rightElement,\n value,\n}) => {\n const [isMobile] = useState(getIsMobile());\n\n const editorRef = useRef<HTMLDivElement>(null);\n\n /**\n * This function updates the content of the 'contentEditable' element if the new text is\n * different from the previous content. So this is only true if, for example, a text like \":-)\"\n * has been replaced to the corresponding emoji.\n *\n * When updating the HTML, the current cursor position is saved before replacing the content, so\n * that it can be set again afterward.\n */\n const handleUpdateHTML = useCallback((html: string) => {\n if (!editorRef.current) {\n return;\n }\n\n let newInnerHTML = convertEmojisToUnicode(html);\n\n newInnerHTML = convertBBCodes(newInnerHTML);\n // newInnerHTML = convertQuotes(newInnerHTML);\n\n if (newInnerHTML !== editorRef.current.innerHTML) {\n saveSelection(editorRef.current);\n\n editorRef.current.innerHTML = newInnerHTML;\n\n restoreSelection(editorRef.current);\n }\n }, []);\n\n /**\n * This function handles the 'input' events of the 'contentEditable' element and also passes the\n * respective event up accordingly if the 'onInput' property is a function.\n */\n const handleInput = useCallback(\n (event: ChangeEvent<HTMLDivElement>) => {\n if (!editorRef.current) {\n return;\n }\n\n handleUpdateHTML(editorRef.current.innerHTML);\n\n if (typeof onInput === 'function') {\n onInput(event);\n }\n },\n [handleUpdateHTML, onInput]\n );\n\n /**\n * This function prevents formatting from being adopted when texts are inserted. To do this, the\n * plain text is read from the event after the default behavior has been prevented. The plain\n * text is then inserted at the correct position in the input field using the\n * 'insertTextAtCursorPosition' function.\n */\n const handlePaste = useCallback((event: ClipboardEvent<HTMLDivElement>) => {\n if (editorRef.current) {\n event.preventDefault();\n\n let text = event.clipboardData.getData('text/plain');\n\n text = convertEmojisToUnicode(text);\n\n insertTextAtCursorPosition({ editorElement: editorRef.current, text });\n\n const newEvent = new Event('input', { bubbles: true });\n\n editorRef.current.dispatchEvent(newEvent);\n }\n }, []);\n\n /**\n * This function uses the 'insertTextAtCursorPosition' function to insert the emoji at the\n * correct position in the editor element.\n *\n * At the end an 'input' event is dispatched, so that the function 'handleInput' is triggered,\n * which in turn executes the 'onInput' function from the props. So this serves to ensure that\n * the event is also passed through to the top when inserting via the popup.\n */\n const handlePopupSelect = useCallback((emoji: string) => {\n if (editorRef.current) {\n insertTextAtCursorPosition({ editorElement: editorRef.current, text: emoji });\n\n const event = new Event('input', { bubbles: true });\n\n editorRef.current.dispatchEvent(event);\n }\n }, []);\n\n /**\n * This function ensures that the input field does not lose focus when the popup is opened or an\n * emoji is selected in it. For this purpose the corresponding elements get the class\n * 'prevent-lose-focus'.\n *\n * The class can also be set to any other elements that should also not cause the input field to\n * lose focus.\n */\n const handlePreventLoseFocus = useCallback((event: MouseEvent) => {\n const element = event.target as Element;\n\n if (\n element.classList.contains('prevent-lose-focus') ||\n element.parentElement?.classList.contains('prevent-lose-focus')\n ) {\n event.preventDefault();\n event.stopPropagation();\n }\n }, []);\n\n useEffect(() => {\n handleUpdateHTML(value);\n }, [handleUpdateHTML, value]);\n\n useEffect(() => {\n document.body.addEventListener('mousedown', handlePreventLoseFocus);\n\n return () => {\n document.body.removeEventListener('mousedown', handlePreventLoseFocus);\n };\n }, [handlePreventLoseFocus]);\n\n return (\n <StyledEmojiInput isDisabled={isDisabled}>\n <StyledEmojiInputContent isRightElementGiven={!!rightElement}>\n <StyledEmojiInputEditor\n contentEditable={!isDisabled}\n id={inputId}\n onInput={handleInput}\n onKeyDown={onKeyDown}\n onPaste={handlePaste}\n placeholder={placeholder}\n ref={editorRef}\n />\n {!isMobile && (\n <EmojiPickerPopup\n accessToken={accessToken}\n alignment={popupAlignment}\n onSelect={handlePopupSelect}\n onPopupVisibilityChange={onPopupVisibilityChange}\n personId={personId}\n />\n )}\n </StyledEmojiInputContent>\n {rightElement && (\n <StyledEmojiInputRightWrapper>{rightElement}</StyledEmojiInputRightWrapper>\n )}\n </StyledEmojiInput>\n );\n};\n\nEmojiInput.displayName = 'EmojiInput';\n\nexport default EmojiInput;\n"],"mappings":"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"}
@@ -90,6 +90,10 @@ const StyledEmojiInputEditor = _styledComponents.default.div`
90
90
  pointer-events: none;
91
91
  }
92
92
 
93
+ lc_mention {
94
+ font-weight: bold;
95
+ }
96
+
93
97
  // Styles for custom scrollbar
94
98
  ::-webkit-scrollbar {
95
99
  width: 5px;
@@ -1 +1 @@
1
- {"version":3,"file":"EmojiInput.styles.js","names":["_styledComponents","_interopRequireWildcard","require","_font","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","StyledEmojiInput","styled","div","_ref","theme","_ref2","isDisabled","_ref3","exports","StyledEmojiInputContent","_ref4","isRightElementGiven","css","StyledEmojiInputEditor","_ref5","text","getFontFamily","_ref6","placeholder","_ref7","_ref8","_ref9","StyledEmojiInputRightWrapper"],"sources":["../../../src/components/emoji-input/EmojiInput.styles.ts"],"sourcesContent":["import type { WithTheme } from '@chayns-components/core';\nimport styled, { css } from 'styled-components';\nimport { getFontFamily } from '../../utils/font';\nimport type { EmojiInputProps } from './EmojiInput';\n\ntype StyledEmojiInputProps = WithTheme<Pick<EmojiInputProps, 'isDisabled'>>;\n\nexport const StyledEmojiInput = styled.div<StyledEmojiInputProps>`\n align-items: center;\n background-color: ${({ theme }: StyledEmojiInputProps) => theme['100']};\n border-radius: 3px;\n display: flex;\n min-height: 42px;\n opacity: ${({ isDisabled }) => (isDisabled ? 0.5 : 1)};\n pointer-events: ${({ isDisabled }) => (isDisabled ? 'none' : 'initial')};\n position: relative;\n transition: opacity 0.3s ease;\n`;\n\ntype StyledEmojiInputContentProps = {\n isRightElementGiven: boolean;\n};\n\nexport const StyledEmojiInputContent = styled.div<StyledEmojiInputContentProps>`\n align-items: end;\n border: 1px solid rgba(160, 160, 160, 0.3);\n border-radius: 3px;\n display: flex;\n flex: 1 1 auto;\n gap: 10px;\n padding: 8px 10px;\n\n ${({ isRightElementGiven }) =>\n isRightElementGiven &&\n css`\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n border-right-width: 0;\n `}\n`;\n\ntype StyledEmojiInputEditorProps = WithTheme<Pick<EmojiInputProps, 'placeholder'>>;\n\nexport const StyledEmojiInputEditor = styled.div<StyledEmojiInputEditorProps>`\n color: ${({ theme }: StyledEmojiInputEditorProps) => theme.text};\n flex: 1 1 auto;\n font-family: ${getFontFamily};\n max-height: 210px;\n overflow-y: scroll;\n word-break: break-word;\n\n // This fixes a bug where the field is not editable in certain browsers.\n // This is for example the case on iOS 15 or older.\n -webkit-user-modify: read-write;\n -webkit-user-select: text;\n\n &:empty:not(:focus):before {\n content: '${({ placeholder }) => placeholder}';\n color: ${({ theme }: StyledEmojiInputEditorProps) => theme['006']};\n pointer-events: none;\n }\n\n // Styles for custom scrollbar\n ::-webkit-scrollbar {\n width: 5px;\n }\n\n ::-webkit-scrollbar-track {\n background-color: transparent;\n }\n\n ::-webkit-scrollbar-button {\n background-color: transparent;\n height: 5px;\n }\n\n ::-webkit-scrollbar-thumb {\n background-color: rgba(\n ${({ theme }: StyledEmojiInputEditorProps) => theme['text-rgb']},\n 0.15\n );\n border-radius: 20px;\n }\n\n // Scrollbar styles for Firefox. The above styles are not supported in Firefox, these styles are\n // only supported in Firefox:\n * {\n scrollbar-color: rgba(\n ${({ theme }: StyledEmojiInputEditorProps) => theme['text-rgb']},\n 0.15\n )\n transparent;\n scrollbar-width: thin;\n }\n`;\n\nexport const StyledEmojiInputRightWrapper = styled.div`\n align-self: stretch;\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n flex: 0 0 auto;\n overflow: hidden;\n`;\n"],"mappings":"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"}
1
+ {"version":3,"file":"EmojiInput.styles.js","names":["_styledComponents","_interopRequireWildcard","require","_font","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","StyledEmojiInput","styled","div","_ref","theme","_ref2","isDisabled","_ref3","exports","StyledEmojiInputContent","_ref4","isRightElementGiven","css","StyledEmojiInputEditor","_ref5","text","getFontFamily","_ref6","placeholder","_ref7","_ref8","_ref9","StyledEmojiInputRightWrapper"],"sources":["../../../src/components/emoji-input/EmojiInput.styles.ts"],"sourcesContent":["import type { WithTheme } from '@chayns-components/core';\nimport styled, { css } from 'styled-components';\nimport { getFontFamily } from '../../utils/font';\nimport type { EmojiInputProps } from './EmojiInput';\n\ntype StyledEmojiInputProps = WithTheme<Pick<EmojiInputProps, 'isDisabled'>>;\n\nexport const StyledEmojiInput = styled.div<StyledEmojiInputProps>`\n align-items: center;\n background-color: ${({ theme }: StyledEmojiInputProps) => theme['100']};\n border-radius: 3px;\n display: flex;\n min-height: 42px;\n opacity: ${({ isDisabled }) => (isDisabled ? 0.5 : 1)};\n pointer-events: ${({ isDisabled }) => (isDisabled ? 'none' : 'initial')};\n position: relative;\n transition: opacity 0.3s ease;\n`;\n\ntype StyledEmojiInputContentProps = {\n isRightElementGiven: boolean;\n};\n\nexport const StyledEmojiInputContent = styled.div<StyledEmojiInputContentProps>`\n align-items: end;\n border: 1px solid rgba(160, 160, 160, 0.3);\n border-radius: 3px;\n display: flex;\n flex: 1 1 auto;\n gap: 10px;\n padding: 8px 10px;\n\n ${({ isRightElementGiven }) =>\n isRightElementGiven &&\n css`\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n border-right-width: 0;\n `}\n`;\n\ntype StyledEmojiInputEditorProps = WithTheme<Pick<EmojiInputProps, 'placeholder'>>;\n\nexport const StyledEmojiInputEditor = styled.div<StyledEmojiInputEditorProps>`\n color: ${({ theme }: StyledEmojiInputEditorProps) => theme.text};\n flex: 1 1 auto;\n font-family: ${getFontFamily};\n max-height: 210px;\n overflow-y: scroll;\n word-break: break-word;\n\n // This fixes a bug where the field is not editable in certain browsers.\n // This is for example the case on iOS 15 or older.\n -webkit-user-modify: read-write;\n -webkit-user-select: text;\n\n &:empty:not(:focus):before {\n content: '${({ placeholder }) => placeholder}';\n color: ${({ theme }: StyledEmojiInputEditorProps) => theme['006']};\n pointer-events: none;\n }\n\n lc_mention {\n font-weight: bold;\n }\n\n // Styles for custom scrollbar\n ::-webkit-scrollbar {\n width: 5px;\n }\n\n ::-webkit-scrollbar-track {\n background-color: transparent;\n }\n\n ::-webkit-scrollbar-button {\n background-color: transparent;\n height: 5px;\n }\n\n ::-webkit-scrollbar-thumb {\n background-color: rgba(\n ${({ theme }: StyledEmojiInputEditorProps) => theme['text-rgb']},\n 0.15\n );\n border-radius: 20px;\n }\n\n // Scrollbar styles for Firefox. The above styles are not supported in Firefox, these styles are\n // only supported in Firefox:\n * {\n scrollbar-color: rgba(\n ${({ theme }: StyledEmojiInputEditorProps) => theme['text-rgb']},\n 0.15\n )\n transparent;\n scrollbar-width: thin;\n }\n`;\n\nexport const StyledEmojiInputRightWrapper = styled.div`\n align-self: stretch;\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n flex: 0 0 auto;\n overflow: hidden;\n`;\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const BB_LC_MENTION_REGEX: RegExp;
2
+ export declare const BB_LC_MENTION_ID_REGEX: RegExp;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.BB_LC_MENTION_REGEX = exports.BB_LC_MENTION_ID_REGEX = void 0;
7
+ const BB_LC_MENTION_REGEX = /\[lc_mention(?:|(?: \S+?)*)](.+?)\[\/lc_mention]/g;
8
+ exports.BB_LC_MENTION_REGEX = BB_LC_MENTION_REGEX;
9
+ const BB_LC_MENTION_ID_REGEX = /id="([^"]*)"/;
10
+ exports.BB_LC_MENTION_ID_REGEX = BB_LC_MENTION_ID_REGEX;
11
+ //# sourceMappingURL=regex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regex.js","names":["BB_LC_MENTION_REGEX","exports","BB_LC_MENTION_ID_REGEX"],"sources":["../../src/constants/regex.ts"],"sourcesContent":["export const BB_LC_MENTION_REGEX = /\\[lc_mention(?:|(?: \\S+?)*)](.+?)\\[\\/lc_mention]/g;\nexport const BB_LC_MENTION_ID_REGEX = /id=\"([^\"]*)\"/;\n"],"mappings":";;;;;;AAAO,MAAMA,mBAAmB,GAAG,mDAAmD;AAACC,OAAA,CAAAD,mBAAA,GAAAA,mBAAA;AAChF,MAAME,sBAAsB,GAAG,cAAc;AAACD,OAAA,CAAAC,sBAAA,GAAAA,sBAAA"}
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.insertTextAtCursorPosition = void 0;
7
+ var _selection = require("./selection");
7
8
  /**
8
9
  * This function inserts the passed text at the correct position in the editor element. If the
9
10
  * element has the focus, the new emoji is inserted at the cursor position. If not, the emoji
@@ -23,24 +24,39 @@ const insertTextAtCursorPosition = _ref => {
23
24
  text
24
25
  } = _ref;
25
26
  const selection = window.getSelection();
27
+ (0, _selection.saveSelection)(editorElement);
26
28
  if (selection !== null && selection !== void 0 && selection.anchorNode && editorElement.contains(selection.anchorNode)) {
27
- const range = selection.getRangeAt(0);
28
- const textNodes = text.split(/\r\n|\r|\n/).map(part => document.createTextNode(part));
29
+ let range = selection.getRangeAt(0);
30
+ const parts = text.split(/\r\n|\r|\n/);
31
+ const firstPart = parts.shift();
32
+ const textNodes = parts.map(part => document.createTextNode(part));
29
33
  range.deleteContents();
30
- textNodes.forEach((textNode, index) => {
31
- range.insertNode(textNode);
32
- range.setEndAfter(textNode);
33
- range.setStartAfter(textNode);
34
- if (index !== textNodes.length - 1) {
35
- const brElement = document.createElement('br');
36
- range.insertNode(brElement);
37
- range.setEndAfter(brElement);
38
- range.setStartAfter(brElement);
39
- }
40
- });
41
- range.collapse(false);
42
- selection.removeAllRanges();
43
- selection.addRange(range);
34
+ if (selection.anchorNode.nodeType === Node.TEXT_NODE && firstPart) {
35
+ selection.anchorNode.nodeValue += firstPart;
36
+ (0, _selection.moveSelectionOffset)(firstPart.length);
37
+ }
38
+ (0, _selection.restoreSelection)(editorElement);
39
+ if (textNodes.length > 0) {
40
+ range = selection.getRangeAt(0);
41
+ let brElement = document.createElement('br');
42
+ range.insertNode(brElement);
43
+ range.setEndAfter(brElement);
44
+ range.setStartAfter(brElement);
45
+ textNodes.forEach((textNode, index) => {
46
+ range.insertNode(textNode);
47
+ range.setEndAfter(textNode);
48
+ range.setStartAfter(textNode);
49
+ if (index !== textNodes.length - 1) {
50
+ brElement = document.createElement('br');
51
+ range.insertNode(brElement);
52
+ range.setEndAfter(brElement);
53
+ range.setStartAfter(brElement);
54
+ }
55
+ });
56
+ range.collapse(false);
57
+ selection.removeAllRanges();
58
+ selection.addRange(range);
59
+ }
44
60
  } else {
45
61
  // eslint-disable-next-line no-param-reassign
46
62
  editorElement.innerText += text;
@@ -1 +1 @@
1
- {"version":3,"file":"insert.js","names":["insertTextAtCursorPosition","_ref","editorElement","text","selection","window","getSelection","anchorNode","contains","range","getRangeAt","textNodes","split","map","part","document","createTextNode","deleteContents","forEach","textNode","index","insertNode","setEndAfter","setStartAfter","length","brElement","createElement","collapse","removeAllRanges","addRange","innerText","exports"],"sources":["../../src/utils/insert.ts"],"sourcesContent":["interface InsertTextAtCursorPositionOptions {\n editorElement: HTMLDivElement;\n text: string;\n}\n\n/**\n * This function inserts the passed text at the correct position in the editor element. If the\n * element has the focus, the new emoji is inserted at the cursor position. If not, the emoji\n * will be appended to the back of the input field content.\n *\n * In addition, this function also sets the cursor to the correct position when the input field\n * has the focus. For this purpose, the current position of the cursor or a selection is read to\n * calculate the cursor position after inserting the text.\n *\n * @param {Object} options - Object with element and text to insert\n * @param {HTMLDivElement} options.editorElement - Element to insert text into\n * @param {string} options.text - Text to insert into element\n */\nexport const insertTextAtCursorPosition = ({\n editorElement,\n text,\n}: InsertTextAtCursorPositionOptions) => {\n const selection = window.getSelection();\n\n if (selection?.anchorNode && editorElement.contains(selection.anchorNode)) {\n const range = selection.getRangeAt(0);\n\n const textNodes = text.split(/\\r\\n|\\r|\\n/).map((part) => document.createTextNode(part));\n\n range.deleteContents();\n\n textNodes.forEach((textNode, index) => {\n range.insertNode(textNode);\n range.setEndAfter(textNode);\n range.setStartAfter(textNode);\n\n if (index !== textNodes.length - 1) {\n const brElement = document.createElement('br');\n\n range.insertNode(brElement);\n range.setEndAfter(brElement);\n range.setStartAfter(brElement);\n }\n });\n\n range.collapse(false);\n\n selection.removeAllRanges();\n selection.addRange(range);\n } else {\n // eslint-disable-next-line no-param-reassign\n editorElement.innerText += text;\n }\n};\n"],"mappings":";;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMA,0BAA0B,GAAGC,IAAA,IAGD;EAAA,IAHE;IACvCC,aAAa;IACbC;EAC+B,CAAC,GAAAF,IAAA;EAChC,MAAMG,SAAS,GAAGC,MAAM,CAACC,YAAY,EAAE;EAEvC,IAAIF,SAAS,aAATA,SAAS,eAATA,SAAS,CAAEG,UAAU,IAAIL,aAAa,CAACM,QAAQ,CAACJ,SAAS,CAACG,UAAU,CAAC,EAAE;IACvE,MAAME,KAAK,GAAGL,SAAS,CAACM,UAAU,CAAC,CAAC,CAAC;IAErC,MAAMC,SAAS,GAAGR,IAAI,CAACS,KAAK,CAAC,YAAY,CAAC,CAACC,GAAG,CAAEC,IAAI,IAAKC,QAAQ,CAACC,cAAc,CAACF,IAAI,CAAC,CAAC;IAEvFL,KAAK,CAACQ,cAAc,EAAE;IAEtBN,SAAS,CAACO,OAAO,CAAC,CAACC,QAAQ,EAAEC,KAAK,KAAK;MACnCX,KAAK,CAACY,UAAU,CAACF,QAAQ,CAAC;MAC1BV,KAAK,CAACa,WAAW,CAACH,QAAQ,CAAC;MAC3BV,KAAK,CAACc,aAAa,CAACJ,QAAQ,CAAC;MAE7B,IAAIC,KAAK,KAAKT,SAAS,CAACa,MAAM,GAAG,CAAC,EAAE;QAChC,MAAMC,SAAS,GAAGV,QAAQ,CAACW,aAAa,CAAC,IAAI,CAAC;QAE9CjB,KAAK,CAACY,UAAU,CAACI,SAAS,CAAC;QAC3BhB,KAAK,CAACa,WAAW,CAACG,SAAS,CAAC;QAC5BhB,KAAK,CAACc,aAAa,CAACE,SAAS,CAAC;MAClC;IACJ,CAAC,CAAC;IAEFhB,KAAK,CAACkB,QAAQ,CAAC,KAAK,CAAC;IAErBvB,SAAS,CAACwB,eAAe,EAAE;IAC3BxB,SAAS,CAACyB,QAAQ,CAACpB,KAAK,CAAC;EAC7B,CAAC,MAAM;IACH;IACAP,aAAa,CAAC4B,SAAS,IAAI3B,IAAI;EACnC;AACJ,CAAC;AAAC4B,OAAA,CAAA/B,0BAAA,GAAAA,0BAAA"}
1
+ {"version":3,"file":"insert.js","names":["_selection","require","insertTextAtCursorPosition","_ref","editorElement","text","selection","window","getSelection","saveSelection","anchorNode","contains","range","getRangeAt","parts","split","firstPart","shift","textNodes","map","part","document","createTextNode","deleteContents","nodeType","Node","TEXT_NODE","nodeValue","moveSelectionOffset","length","restoreSelection","brElement","createElement","insertNode","setEndAfter","setStartAfter","forEach","textNode","index","collapse","removeAllRanges","addRange","innerText","exports"],"sources":["../../src/utils/insert.ts"],"sourcesContent":["import { moveSelectionOffset, restoreSelection, saveSelection } from './selection';\n\ninterface InsertTextAtCursorPositionOptions {\n editorElement: HTMLDivElement;\n text: string;\n}\n\n/**\n * This function inserts the passed text at the correct position in the editor element. If the\n * element has the focus, the new emoji is inserted at the cursor position. If not, the emoji\n * will be appended to the back of the input field content.\n *\n * In addition, this function also sets the cursor to the correct position when the input field\n * has the focus. For this purpose, the current position of the cursor or a selection is read to\n * calculate the cursor position after inserting the text.\n *\n * @param {Object} options - Object with element and text to insert\n * @param {HTMLDivElement} options.editorElement - Element to insert text into\n * @param {string} options.text - Text to insert into element\n */\nexport const insertTextAtCursorPosition = ({\n editorElement,\n text,\n}: InsertTextAtCursorPositionOptions) => {\n const selection = window.getSelection();\n\n saveSelection(editorElement);\n\n if (selection?.anchorNode && editorElement.contains(selection.anchorNode)) {\n let range = selection.getRangeAt(0);\n\n const parts = text.split(/\\r\\n|\\r|\\n/);\n\n const firstPart = parts.shift();\n\n const textNodes = parts.map((part) => document.createTextNode(part));\n\n range.deleteContents();\n\n if (selection.anchorNode.nodeType === Node.TEXT_NODE && firstPart) {\n selection.anchorNode.nodeValue += firstPart;\n\n moveSelectionOffset(firstPart.length);\n }\n\n restoreSelection(editorElement);\n\n if (textNodes.length > 0) {\n range = selection.getRangeAt(0);\n\n let brElement = document.createElement('br');\n\n range.insertNode(brElement);\n range.setEndAfter(brElement);\n range.setStartAfter(brElement);\n\n textNodes.forEach((textNode, index) => {\n range.insertNode(textNode);\n range.setEndAfter(textNode);\n range.setStartAfter(textNode);\n\n if (index !== textNodes.length - 1) {\n brElement = document.createElement('br');\n\n range.insertNode(brElement);\n range.setEndAfter(brElement);\n range.setStartAfter(brElement);\n }\n });\n\n range.collapse(false);\n\n selection.removeAllRanges();\n selection.addRange(range);\n }\n } else {\n // eslint-disable-next-line no-param-reassign\n editorElement.innerText += text;\n }\n};\n"],"mappings":";;;;;;AAAA,IAAAA,UAAA,GAAAC,OAAA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,0BAA0B,GAAGC,IAAA,IAGD;EAAA,IAHE;IACvCC,aAAa;IACbC;EAC+B,CAAC,GAAAF,IAAA;EAChC,MAAMG,SAAS,GAAGC,MAAM,CAACC,YAAY,EAAE;EAEvC,IAAAC,wBAAa,EAACL,aAAa,CAAC;EAE5B,IAAIE,SAAS,aAATA,SAAS,eAATA,SAAS,CAAEI,UAAU,IAAIN,aAAa,CAACO,QAAQ,CAACL,SAAS,CAACI,UAAU,CAAC,EAAE;IACvE,IAAIE,KAAK,GAAGN,SAAS,CAACO,UAAU,CAAC,CAAC,CAAC;IAEnC,MAAMC,KAAK,GAAGT,IAAI,CAACU,KAAK,CAAC,YAAY,CAAC;IAEtC,MAAMC,SAAS,GAAGF,KAAK,CAACG,KAAK,EAAE;IAE/B,MAAMC,SAAS,GAAGJ,KAAK,CAACK,GAAG,CAAEC,IAAI,IAAKC,QAAQ,CAACC,cAAc,CAACF,IAAI,CAAC,CAAC;IAEpER,KAAK,CAACW,cAAc,EAAE;IAEtB,IAAIjB,SAAS,CAACI,UAAU,CAACc,QAAQ,KAAKC,IAAI,CAACC,SAAS,IAAIV,SAAS,EAAE;MAC/DV,SAAS,CAACI,UAAU,CAACiB,SAAS,IAAIX,SAAS;MAE3C,IAAAY,8BAAmB,EAACZ,SAAS,CAACa,MAAM,CAAC;IACzC;IAEA,IAAAC,2BAAgB,EAAC1B,aAAa,CAAC;IAE/B,IAAIc,SAAS,CAACW,MAAM,GAAG,CAAC,EAAE;MACtBjB,KAAK,GAAGN,SAAS,CAACO,UAAU,CAAC,CAAC,CAAC;MAE/B,IAAIkB,SAAS,GAAGV,QAAQ,CAACW,aAAa,CAAC,IAAI,CAAC;MAE5CpB,KAAK,CAACqB,UAAU,CAACF,SAAS,CAAC;MAC3BnB,KAAK,CAACsB,WAAW,CAACH,SAAS,CAAC;MAC5BnB,KAAK,CAACuB,aAAa,CAACJ,SAAS,CAAC;MAE9Bb,SAAS,CAACkB,OAAO,CAAC,CAACC,QAAQ,EAAEC,KAAK,KAAK;QACnC1B,KAAK,CAACqB,UAAU,CAACI,QAAQ,CAAC;QAC1BzB,KAAK,CAACsB,WAAW,CAACG,QAAQ,CAAC;QAC3BzB,KAAK,CAACuB,aAAa,CAACE,QAAQ,CAAC;QAE7B,IAAIC,KAAK,KAAKpB,SAAS,CAACW,MAAM,GAAG,CAAC,EAAE;UAChCE,SAAS,GAAGV,QAAQ,CAACW,aAAa,CAAC,IAAI,CAAC;UAExCpB,KAAK,CAACqB,UAAU,CAACF,SAAS,CAAC;UAC3BnB,KAAK,CAACsB,WAAW,CAACH,SAAS,CAAC;UAC5BnB,KAAK,CAACuB,aAAa,CAACJ,SAAS,CAAC;QAClC;MACJ,CAAC,CAAC;MAEFnB,KAAK,CAAC2B,QAAQ,CAAC,KAAK,CAAC;MAErBjC,SAAS,CAACkC,eAAe,EAAE;MAC3BlC,SAAS,CAACmC,QAAQ,CAAC7B,KAAK,CAAC;IAC7B;EACJ,CAAC,MAAM;IACH;IACAR,aAAa,CAACsC,SAAS,IAAIrC,IAAI;EACnC;AACJ,CAAC;AAACsC,OAAA,CAAAzC,0BAAA,GAAAA,0BAAA"}
@@ -1,2 +1,3 @@
1
1
  export declare const saveSelection: (element: HTMLDivElement) => void;
2
2
  export declare const restoreSelection: (element: HTMLDivElement) => void;
3
+ export declare const moveSelectionOffset: (distance: number) => void;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.saveSelection = exports.restoreSelection = void 0;
6
+ exports.saveSelection = exports.restoreSelection = exports.moveSelectionOffset = void 0;
7
7
  let childIndex = -1;
8
8
  let endOffset = -1;
9
9
  let startOffset = -1;
@@ -17,46 +17,37 @@ const saveSelection = element => {
17
17
  return;
18
18
  }
19
19
  const range = selection.getRangeAt(0);
20
- console.debug('saveSelection 0', {
21
- childNodes: Array.from(element.childNodes),
22
- node
23
- });
24
20
  childIndex = Array.from(element.childNodes).indexOf(node);
25
21
  endOffset = range.endOffset;
26
22
  startOffset = range.startOffset;
27
- console.log('saveSelection 1', {
28
- childIndex,
29
- endOffset,
30
- startOffset
31
- });
32
23
  };
33
24
  exports.saveSelection = saveSelection;
34
25
  const restoreSelection = element => {
35
- const childNode = element.childNodes[childIndex];
26
+ let childNode = element.childNodes[childIndex];
36
27
  const selection = window.getSelection();
37
- console.log('restoreSelection 0', {
38
- childNode,
39
- childNodes: element.childNodes,
40
- childIndex
41
- });
42
28
  if (!childNode || !element || !selection) {
43
29
  return;
44
30
  }
45
31
  const range = document.createRange();
46
- console.log('restoreSelection 1', {
47
- childIndex,
48
- endOffset,
49
- startOffset
50
- });
51
- if (childNode.nodeValue) {
52
- endOffset = Math.min(endOffset, childNode.nodeValue.length);
53
- startOffset = Math.min(startOffset, childNode.nodeValue.length);
32
+ if (childNode.nodeValue && endOffset > childNode.nodeValue.length) {
33
+ if (childNode.nextSibling) {
34
+ childNode = childNode.nextSibling;
35
+ if (childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue) {
36
+ endOffset = childNode.nodeValue.length;
37
+ startOffset = childNode.nodeValue.length;
38
+ } else {
39
+ var _childNode$parentNode;
40
+ const textNode = document.createTextNode('');
41
+ (_childNode$parentNode = childNode.parentNode) === null || _childNode$parentNode === void 0 ? void 0 : _childNode$parentNode.insertBefore(textNode, childNode.nextSibling);
42
+ childNode = textNode;
43
+ endOffset = 0;
44
+ startOffset = 0;
45
+ }
46
+ } else {
47
+ endOffset = childNode.nodeValue.length;
48
+ startOffset = childNode.nodeValue.length;
49
+ }
54
50
  }
55
- console.log('restoreSelection 2', {
56
- childIndex,
57
- endOffset,
58
- startOffset
59
- });
60
51
  range.setStart(childNode, startOffset);
61
52
  range.setEnd(childNode, endOffset);
62
53
  selection.removeAllRanges();
@@ -64,4 +55,9 @@ const restoreSelection = element => {
64
55
  range.collapse(true);
65
56
  };
66
57
  exports.restoreSelection = restoreSelection;
58
+ const moveSelectionOffset = distance => {
59
+ endOffset += distance;
60
+ startOffset += distance;
61
+ };
62
+ exports.moveSelectionOffset = moveSelectionOffset;
67
63
  //# sourceMappingURL=selection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"selection.js","names":["childIndex","endOffset","startOffset","saveSelection","element","selection","window","getSelection","node","anchorNode","range","getRangeAt","console","debug","childNodes","Array","from","indexOf","log","exports","restoreSelection","childNode","document","createRange","nodeValue","Math","min","length","setStart","setEnd","removeAllRanges","addRange","collapse"],"sources":["../../src/utils/selection.ts"],"sourcesContent":["let childIndex = -1;\nlet endOffset = -1;\nlet startOffset = -1;\n\nexport const saveSelection = (element: HTMLDivElement) => {\n const selection = window.getSelection();\n\n if (!selection) {\n return;\n }\n\n const node = selection.anchorNode;\n\n if (!node) {\n return;\n }\n\n const range = selection.getRangeAt(0);\n\n console.debug('saveSelection 0', { childNodes: Array.from(element.childNodes), node });\n\n childIndex = Array.from(element.childNodes).indexOf(node as ChildNode);\n\n endOffset = range.endOffset;\n startOffset = range.startOffset;\n\n console.log('saveSelection 1', { childIndex, endOffset, startOffset });\n};\n\nexport const restoreSelection = (element: HTMLDivElement) => {\n const childNode = element.childNodes[childIndex];\n const selection = window.getSelection();\n\n console.log('restoreSelection 0', { childNode, childNodes: element.childNodes, childIndex });\n\n if (!childNode || !element || !selection) {\n return;\n }\n\n const range = document.createRange();\n\n console.log('restoreSelection 1', { childIndex, endOffset, startOffset });\n\n if (childNode.nodeValue) {\n endOffset = Math.min(endOffset, childNode.nodeValue.length);\n startOffset = Math.min(startOffset, childNode.nodeValue.length);\n }\n\n console.log('restoreSelection 2', { childIndex, endOffset, startOffset });\n\n range.setStart(childNode, startOffset);\n range.setEnd(childNode, endOffset);\n\n selection.removeAllRanges();\n selection.addRange(range);\n\n range.collapse(true);\n};\n"],"mappings":";;;;;;AAAA,IAAIA,UAAU,GAAG,CAAC,CAAC;AACnB,IAAIC,SAAS,GAAG,CAAC,CAAC;AAClB,IAAIC,WAAW,GAAG,CAAC,CAAC;AAEb,MAAMC,aAAa,GAAIC,OAAuB,IAAK;EACtD,MAAMC,SAAS,GAAGC,MAAM,CAACC,YAAY,EAAE;EAEvC,IAAI,CAACF,SAAS,EAAE;IACZ;EACJ;EAEA,MAAMG,IAAI,GAAGH,SAAS,CAACI,UAAU;EAEjC,IAAI,CAACD,IAAI,EAAE;IACP;EACJ;EAEA,MAAME,KAAK,GAAGL,SAAS,CAACM,UAAU,CAAC,CAAC,CAAC;EAErCC,OAAO,CAACC,KAAK,CAAC,iBAAiB,EAAE;IAAEC,UAAU,EAAEC,KAAK,CAACC,IAAI,CAACZ,OAAO,CAACU,UAAU,CAAC;IAAEN;EAAK,CAAC,CAAC;EAEtFR,UAAU,GAAGe,KAAK,CAACC,IAAI,CAACZ,OAAO,CAACU,UAAU,CAAC,CAACG,OAAO,CAACT,IAAI,CAAc;EAEtEP,SAAS,GAAGS,KAAK,CAACT,SAAS;EAC3BC,WAAW,GAAGQ,KAAK,CAACR,WAAW;EAE/BU,OAAO,CAACM,GAAG,CAAC,iBAAiB,EAAE;IAAElB,UAAU;IAAEC,SAAS;IAAEC;EAAY,CAAC,CAAC;AAC1E,CAAC;AAACiB,OAAA,CAAAhB,aAAA,GAAAA,aAAA;AAEK,MAAMiB,gBAAgB,GAAIhB,OAAuB,IAAK;EACzD,MAAMiB,SAAS,GAAGjB,OAAO,CAACU,UAAU,CAACd,UAAU,CAAC;EAChD,MAAMK,SAAS,GAAGC,MAAM,CAACC,YAAY,EAAE;EAEvCK,OAAO,CAACM,GAAG,CAAC,oBAAoB,EAAE;IAAEG,SAAS;IAAEP,UAAU,EAAEV,OAAO,CAACU,UAAU;IAAEd;EAAW,CAAC,CAAC;EAE5F,IAAI,CAACqB,SAAS,IAAI,CAACjB,OAAO,IAAI,CAACC,SAAS,EAAE;IACtC;EACJ;EAEA,MAAMK,KAAK,GAAGY,QAAQ,CAACC,WAAW,EAAE;EAEpCX,OAAO,CAACM,GAAG,CAAC,oBAAoB,EAAE;IAAElB,UAAU;IAAEC,SAAS;IAAEC;EAAY,CAAC,CAAC;EAEzE,IAAImB,SAAS,CAACG,SAAS,EAAE;IACrBvB,SAAS,GAAGwB,IAAI,CAACC,GAAG,CAACzB,SAAS,EAAEoB,SAAS,CAACG,SAAS,CAACG,MAAM,CAAC;IAC3DzB,WAAW,GAAGuB,IAAI,CAACC,GAAG,CAACxB,WAAW,EAAEmB,SAAS,CAACG,SAAS,CAACG,MAAM,CAAC;EACnE;EAEAf,OAAO,CAACM,GAAG,CAAC,oBAAoB,EAAE;IAAElB,UAAU;IAAEC,SAAS;IAAEC;EAAY,CAAC,CAAC;EAEzEQ,KAAK,CAACkB,QAAQ,CAACP,SAAS,EAAEnB,WAAW,CAAC;EACtCQ,KAAK,CAACmB,MAAM,CAACR,SAAS,EAAEpB,SAAS,CAAC;EAElCI,SAAS,CAACyB,eAAe,EAAE;EAC3BzB,SAAS,CAAC0B,QAAQ,CAACrB,KAAK,CAAC;EAEzBA,KAAK,CAACsB,QAAQ,CAAC,IAAI,CAAC;AACxB,CAAC;AAACb,OAAA,CAAAC,gBAAA,GAAAA,gBAAA"}
1
+ {"version":3,"file":"selection.js","names":["childIndex","endOffset","startOffset","saveSelection","element","selection","window","getSelection","node","anchorNode","range","getRangeAt","Array","from","childNodes","indexOf","exports","restoreSelection","childNode","document","createRange","nodeValue","length","nextSibling","nodeType","Node","TEXT_NODE","_childNode$parentNode","textNode","createTextNode","parentNode","insertBefore","setStart","setEnd","removeAllRanges","addRange","collapse","moveSelectionOffset","distance"],"sources":["../../src/utils/selection.ts"],"sourcesContent":["let childIndex = -1;\nlet endOffset = -1;\nlet startOffset = -1;\n\nexport const saveSelection = (element: HTMLDivElement) => {\n const selection = window.getSelection();\n\n if (!selection) {\n return;\n }\n\n const node = selection.anchorNode;\n\n if (!node) {\n return;\n }\n\n const range = selection.getRangeAt(0);\n\n childIndex = Array.from(element.childNodes).indexOf(node as ChildNode);\n\n endOffset = range.endOffset;\n startOffset = range.startOffset;\n};\n\nexport const restoreSelection = (element: HTMLDivElement) => {\n let childNode = element.childNodes[childIndex];\n\n const selection = window.getSelection();\n\n if (!childNode || !element || !selection) {\n return;\n }\n\n const range = document.createRange();\n\n if (childNode.nodeValue && endOffset > childNode.nodeValue.length) {\n if (childNode.nextSibling) {\n childNode = childNode.nextSibling;\n\n if (childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue) {\n endOffset = childNode.nodeValue.length;\n startOffset = childNode.nodeValue.length;\n } else {\n const textNode = document.createTextNode('');\n\n childNode.parentNode?.insertBefore(textNode, childNode.nextSibling);\n\n childNode = textNode;\n\n endOffset = 0;\n startOffset = 0;\n }\n } else {\n endOffset = childNode.nodeValue.length;\n startOffset = childNode.nodeValue.length;\n }\n }\n\n range.setStart(childNode, startOffset);\n range.setEnd(childNode, endOffset);\n\n selection.removeAllRanges();\n selection.addRange(range);\n\n range.collapse(true);\n};\n\nexport const moveSelectionOffset = (distance: number) => {\n endOffset += distance;\n startOffset += distance;\n};\n"],"mappings":";;;;;;AAAA,IAAIA,UAAU,GAAG,CAAC,CAAC;AACnB,IAAIC,SAAS,GAAG,CAAC,CAAC;AAClB,IAAIC,WAAW,GAAG,CAAC,CAAC;AAEb,MAAMC,aAAa,GAAIC,OAAuB,IAAK;EACtD,MAAMC,SAAS,GAAGC,MAAM,CAACC,YAAY,EAAE;EAEvC,IAAI,CAACF,SAAS,EAAE;IACZ;EACJ;EAEA,MAAMG,IAAI,GAAGH,SAAS,CAACI,UAAU;EAEjC,IAAI,CAACD,IAAI,EAAE;IACP;EACJ;EAEA,MAAME,KAAK,GAAGL,SAAS,CAACM,UAAU,CAAC,CAAC,CAAC;EAErCX,UAAU,GAAGY,KAAK,CAACC,IAAI,CAACT,OAAO,CAACU,UAAU,CAAC,CAACC,OAAO,CAACP,IAAI,CAAc;EAEtEP,SAAS,GAAGS,KAAK,CAACT,SAAS;EAC3BC,WAAW,GAAGQ,KAAK,CAACR,WAAW;AACnC,CAAC;AAACc,OAAA,CAAAb,aAAA,GAAAA,aAAA;AAEK,MAAMc,gBAAgB,GAAIb,OAAuB,IAAK;EACzD,IAAIc,SAAS,GAAGd,OAAO,CAACU,UAAU,CAACd,UAAU,CAAC;EAE9C,MAAMK,SAAS,GAAGC,MAAM,CAACC,YAAY,EAAE;EAEvC,IAAI,CAACW,SAAS,IAAI,CAACd,OAAO,IAAI,CAACC,SAAS,EAAE;IACtC;EACJ;EAEA,MAAMK,KAAK,GAAGS,QAAQ,CAACC,WAAW,EAAE;EAEpC,IAAIF,SAAS,CAACG,SAAS,IAAIpB,SAAS,GAAGiB,SAAS,CAACG,SAAS,CAACC,MAAM,EAAE;IAC/D,IAAIJ,SAAS,CAACK,WAAW,EAAE;MACvBL,SAAS,GAAGA,SAAS,CAACK,WAAW;MAEjC,IAAIL,SAAS,CAACM,QAAQ,KAAKC,IAAI,CAACC,SAAS,IAAIR,SAAS,CAACG,SAAS,EAAE;QAC9DpB,SAAS,GAAGiB,SAAS,CAACG,SAAS,CAACC,MAAM;QACtCpB,WAAW,GAAGgB,SAAS,CAACG,SAAS,CAACC,MAAM;MAC5C,CAAC,MAAM;QAAA,IAAAK,qBAAA;QACH,MAAMC,QAAQ,GAAGT,QAAQ,CAACU,cAAc,CAAC,EAAE,CAAC;QAE5C,CAAAF,qBAAA,GAAAT,SAAS,CAACY,UAAU,cAAAH,qBAAA,uBAApBA,qBAAA,CAAsBI,YAAY,CAACH,QAAQ,EAAEV,SAAS,CAACK,WAAW,CAAC;QAEnEL,SAAS,GAAGU,QAAQ;QAEpB3B,SAAS,GAAG,CAAC;QACbC,WAAW,GAAG,CAAC;MACnB;IACJ,CAAC,MAAM;MACHD,SAAS,GAAGiB,SAAS,CAACG,SAAS,CAACC,MAAM;MACtCpB,WAAW,GAAGgB,SAAS,CAACG,SAAS,CAACC,MAAM;IAC5C;EACJ;EAEAZ,KAAK,CAACsB,QAAQ,CAACd,SAAS,EAAEhB,WAAW,CAAC;EACtCQ,KAAK,CAACuB,MAAM,CAACf,SAAS,EAAEjB,SAAS,CAAC;EAElCI,SAAS,CAAC6B,eAAe,EAAE;EAC3B7B,SAAS,CAAC8B,QAAQ,CAACzB,KAAK,CAAC;EAEzBA,KAAK,CAAC0B,QAAQ,CAAC,IAAI,CAAC;AACxB,CAAC;AAACpB,OAAA,CAAAC,gBAAA,GAAAA,gBAAA;AAEK,MAAMoB,mBAAmB,GAAIC,QAAgB,IAAK;EACrDrC,SAAS,IAAIqC,QAAQ;EACrBpC,WAAW,IAAIoC,QAAQ;AAC3B,CAAC;AAACtB,OAAA,CAAAqB,mBAAA,GAAAA,mBAAA"}
@@ -1 +1,2 @@
1
+ export declare const convertBBCodes: (text: string) => string;
1
2
  export declare const convertQuotes: (text: string) => string;
package/lib/utils/text.js CHANGED
@@ -3,9 +3,25 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.convertQuotes = void 0;
6
+ exports.convertQuotes = exports.convertBBCodes = void 0;
7
+ var _regex = require("../constants/regex");
8
+ const replaceLcMention = (lcMention, text) => {
9
+ let attributes = '';
10
+ const idMatches = lcMention.match(_regex.BB_LC_MENTION_ID_REGEX);
11
+ const match = idMatches === null || idMatches === void 0 ? void 0 : idMatches[1];
12
+ if (match) {
13
+ attributes += `id="${match}"`;
14
+ }
15
+ return `<lc_mention contenteditable="false" ${attributes}>${text}</lc_mention>`;
16
+ };
17
+ const convertBBCodes = text => {
18
+ let result = text;
19
+ result = result.replace(_regex.BB_LC_MENTION_REGEX, replaceLcMention);
20
+ return result;
21
+ };
22
+ exports.convertBBCodes = convertBBCodes;
7
23
  const convertQuotes = text => {
8
- const regexForQuotes = /(?:\s|^|[\u{1F000}-\u{1F9FF}])"(?=\w)|(?<=\w)"(?=\s|$|[\u{1F000}-\u{1F9FF}])|(?<=\w)"(?=\w)|(?<=[^\w\s\u{1F000}-\u{1F9FF}])"(?=\w)|(?<=[^\w\s\u{1F000}-\u{1F9FF}])"(?=\^)|(?<=[^\w\s\u{1F000}-\u{1F9FF}])"(?<=[^\w\s\u{1F000}-\u{1F9FF}])|(?<=\w)"(?<=[^\w\s\u{1F000}-\u{1F9FF}])/gu;
24
+ const regexForQuotes = /(?<=[\s<>]|^)("(?=\w)|(?<=\w)")(?=[\s<>]|$)|(?<=[^\w\s\u{1F000}-\u{1F9FF}])(?![^<]*>)("(?![^<]*>[^<]*<\/lc_mention>)(?=\w)|(?<=[^\w\s\u{1F000}-\u{1F9FF}])(?![^<]*>)("(?![^<]*>[^<]*<\/lc_mention>)(?=\^)|(?<=[^\w\s\u{1F000}-\u{1F9FF}])(?![^<]*>)("(?![^<]*>[^<]*<\/lc_mention>)(?<=[^\w\s\u{1F000}-\u{1F9FF}]))))/gu;
9
25
  const regexForQuoteStart = /„(\s|$)/g;
10
26
  const formattedQuotes = text.replace(regexForQuotes, match => {
11
27
  if (match.startsWith(' ') || text.startsWith(match)) {
@@ -1 +1 @@
1
- {"version":3,"file":"text.js","names":["convertQuotes","text","regexForQuotes","regexForQuoteStart","formattedQuotes","replace","match","startsWith","String","fromCharCode","exports"],"sources":["../../src/utils/text.ts"],"sourcesContent":["export const convertQuotes = (text: string) => {\n const regexForQuotes =\n /(?:\\s|^|[\\u{1F000}-\\u{1F9FF}])\"(?=\\w)|(?<=\\w)\"(?=\\s|$|[\\u{1F000}-\\u{1F9FF}])|(?<=\\w)\"(?=\\w)|(?<=[^\\w\\s\\u{1F000}-\\u{1F9FF}])\"(?=\\w)|(?<=[^\\w\\s\\u{1F000}-\\u{1F9FF}])\"(?=\\^)|(?<=[^\\w\\s\\u{1F000}-\\u{1F9FF}])\"(?<=[^\\w\\s\\u{1F000}-\\u{1F9FF}])|(?<=\\w)\"(?<=[^\\w\\s\\u{1F000}-\\u{1F9FF}])/gu;\n\n const regexForQuoteStart = /„(\\s|$)/g;\n\n const formattedQuotes = text.replace(regexForQuotes, (match) => {\n if (match.startsWith(' ') || text.startsWith(match)) {\n return match.startsWith(' ')\n ? ` ${String.fromCharCode(8222)}`\n : String.fromCharCode(8222);\n }\n return String.fromCharCode(8220);\n });\n\n return formattedQuotes.replace(regexForQuoteStart, '\"');\n};\n"],"mappings":";;;;;;AAAO,MAAMA,aAAa,GAAIC,IAAY,IAAK;EAC3C,MAAMC,cAAc,GAChB,qRAAqR;EAEzR,MAAMC,kBAAkB,GAAG,UAAU;EAErC,MAAMC,eAAe,GAAGH,IAAI,CAACI,OAAO,CAACH,cAAc,EAAGI,KAAK,IAAK;IAC5D,IAAIA,KAAK,CAACC,UAAU,CAAC,GAAG,CAAC,IAAIN,IAAI,CAACM,UAAU,CAACD,KAAK,CAAC,EAAE;MACjD,OAAOA,KAAK,CAACC,UAAU,CAAC,GAAG,CAAC,GACrB,IAAGC,MAAM,CAACC,YAAY,CAAC,IAAI,CAAE,EAAC,GAC/BD,MAAM,CAACC,YAAY,CAAC,IAAI,CAAC;IACnC;IACA,OAAOD,MAAM,CAACC,YAAY,CAAC,IAAI,CAAC;EACpC,CAAC,CAAC;EAEF,OAAOL,eAAe,CAACC,OAAO,CAACF,kBAAkB,EAAE,GAAG,CAAC;AAC3D,CAAC;AAACO,OAAA,CAAAV,aAAA,GAAAA,aAAA"}
1
+ {"version":3,"file":"text.js","names":["_regex","require","replaceLcMention","lcMention","text","attributes","idMatches","match","BB_LC_MENTION_ID_REGEX","convertBBCodes","result","replace","BB_LC_MENTION_REGEX","exports","convertQuotes","regexForQuotes","regexForQuoteStart","formattedQuotes","startsWith","String","fromCharCode"],"sources":["../../src/utils/text.ts"],"sourcesContent":["import { BB_LC_MENTION_ID_REGEX, BB_LC_MENTION_REGEX } from '../constants/regex';\n\nconst replaceLcMention = (lcMention: string, text: string) => {\n let attributes = '';\n\n const idMatches = lcMention.match(BB_LC_MENTION_ID_REGEX);\n\n const match = idMatches?.[1];\n\n if (match) {\n attributes += `id=\"${match}\"`;\n }\n\n return `<lc_mention contenteditable=\"false\" ${attributes}>${text}</lc_mention>`;\n};\n\nexport const convertBBCodes = (text: string) => {\n let result = text;\n\n result = result.replace(BB_LC_MENTION_REGEX, replaceLcMention);\n\n return result;\n};\n\nexport const convertQuotes = (text: string) => {\n const regexForQuotes =\n /(?<=[\\s<>]|^)(\"(?=\\w)|(?<=\\w)\")(?=[\\s<>]|$)|(?<=[^\\w\\s\\u{1F000}-\\u{1F9FF}])(?![^<]*>)(\"(?![^<]*>[^<]*<\\/lc_mention>)(?=\\w)|(?<=[^\\w\\s\\u{1F000}-\\u{1F9FF}])(?![^<]*>)(\"(?![^<]*>[^<]*<\\/lc_mention>)(?=\\^)|(?<=[^\\w\\s\\u{1F000}-\\u{1F9FF}])(?![^<]*>)(\"(?![^<]*>[^<]*<\\/lc_mention>)(?<=[^\\w\\s\\u{1F000}-\\u{1F9FF}]))))/gu;\n\n const regexForQuoteStart = /„(\\s|$)/g;\n\n const formattedQuotes = text.replace(regexForQuotes, (match) => {\n if (match.startsWith(' ') || text.startsWith(match)) {\n return match.startsWith(' ')\n ? ` ${String.fromCharCode(8222)}`\n : String.fromCharCode(8222);\n }\n return String.fromCharCode(8220);\n });\n\n return formattedQuotes.replace(regexForQuoteStart, '\"');\n};\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,MAAMC,gBAAgB,GAAGA,CAACC,SAAiB,EAAEC,IAAY,KAAK;EAC1D,IAAIC,UAAU,GAAG,EAAE;EAEnB,MAAMC,SAAS,GAAGH,SAAS,CAACI,KAAK,CAACC,6BAAsB,CAAC;EAEzD,MAAMD,KAAK,GAAGD,SAAS,aAATA,SAAS,uBAATA,SAAS,CAAG,CAAC,CAAC;EAE5B,IAAIC,KAAK,EAAE;IACPF,UAAU,IAAK,OAAME,KAAM,GAAE;EACjC;EAEA,OAAQ,uCAAsCF,UAAW,IAAGD,IAAK,eAAc;AACnF,CAAC;AAEM,MAAMK,cAAc,GAAIL,IAAY,IAAK;EAC5C,IAAIM,MAAM,GAAGN,IAAI;EAEjBM,MAAM,GAAGA,MAAM,CAACC,OAAO,CAACC,0BAAmB,EAAEV,gBAAgB,CAAC;EAE9D,OAAOQ,MAAM;AACjB,CAAC;AAACG,OAAA,CAAAJ,cAAA,GAAAA,cAAA;AAEK,MAAMK,aAAa,GAAIV,IAAY,IAAK;EAC3C,MAAMW,cAAc,GAChB,wTAAwT;EAE5T,MAAMC,kBAAkB,GAAG,UAAU;EAErC,MAAMC,eAAe,GAAGb,IAAI,CAACO,OAAO,CAACI,cAAc,EAAGR,KAAK,IAAK;IAC5D,IAAIA,KAAK,CAACW,UAAU,CAAC,GAAG,CAAC,IAAId,IAAI,CAACc,UAAU,CAACX,KAAK,CAAC,EAAE;MACjD,OAAOA,KAAK,CAACW,UAAU,CAAC,GAAG,CAAC,GACrB,IAAGC,MAAM,CAACC,YAAY,CAAC,IAAI,CAAE,EAAC,GAC/BD,MAAM,CAACC,YAAY,CAAC,IAAI,CAAC;IACnC;IACA,OAAOD,MAAM,CAACC,YAAY,CAAC,IAAI,CAAC;EACpC,CAAC,CAAC;EAEF,OAAOH,eAAe,CAACN,OAAO,CAACK,kBAAkB,EAAE,GAAG,CAAC;AAC3D,CAAC;AAACH,OAAA,CAAAC,aAAA,GAAAA,aAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chayns-components/emoji-input",
3
- "version": "5.0.0-beta.122",
3
+ "version": "5.0.0-beta.124",
4
4
  "description": "Input field that supports HTML elements and emojis",
5
5
  "keywords": [
6
6
  "chayns",
@@ -68,5 +68,5 @@
68
68
  "publishConfig": {
69
69
  "access": "public"
70
70
  },
71
- "gitHead": "dd9b34a871b42b67d23245103f605d6feea64dab"
71
+ "gitHead": "22bdaf4bb22c8ee9e00efa75372a30eb8613c311"
72
72
  }