stream-chat-react 12.14.0 → 12.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/components/Channel/Channel.d.ts +8 -2
  2. package/dist/components/Chat/hooks/useChat.js +1 -1
  3. package/dist/components/MessageInput/MessageInput.js +3 -0
  4. package/dist/components/MessageInput/MessageInputFlat.js +28 -48
  5. package/dist/components/MessageInput/WithDragAndDropUpload.d.ts +37 -0
  6. package/dist/components/MessageInput/WithDragAndDropUpload.js +85 -0
  7. package/dist/components/MessageInput/index.d.ts +1 -0
  8. package/dist/components/MessageInput/index.js +1 -0
  9. package/dist/context/MessageInputContext.js +3 -2
  10. package/dist/css/v2/index.css +1 -1
  11. package/dist/css/v2/index.layout.css +1 -1
  12. package/dist/index.browser.cjs +442 -400
  13. package/dist/index.browser.cjs.map +4 -4
  14. package/dist/index.node.cjs +467 -424
  15. package/dist/index.node.cjs.map +4 -4
  16. package/dist/plugins/Emojis/index.browser.cjs +0 -3
  17. package/dist/plugins/Emojis/index.browser.cjs.map +2 -2
  18. package/dist/plugins/Emojis/index.node.cjs +0 -3
  19. package/dist/plugins/Emojis/index.node.cjs.map +2 -2
  20. package/dist/scss/v2/DropzoneContainer/DropzoneContainer-layout.scss +14 -0
  21. package/dist/scss/v2/DropzoneContainer/DropzoneContainer-theme.scss +17 -0
  22. package/dist/scss/v2/MessageInput/MessageInput-layout.scss +0 -13
  23. package/dist/scss/v2/MessageInput/MessageInput-theme.scss +8 -19
  24. package/dist/scss/v2/index.layout.scss +2 -1
  25. package/dist/scss/v2/index.scss +1 -0
  26. package/package.json +2 -2
  27. /package/dist/scss/v2/DragAndDropContainer/{DragAmdDropContainer-layout.scss → DragAndDropContainer-layout.scss} +0 -0
@@ -76,9 +76,6 @@ var MessageInputContext = (0, import_react2.createContext)(void 0);
76
76
  var useMessageInputContext = (componentName) => {
77
77
  const contextValue = (0, import_react2.useContext)(MessageInputContext);
78
78
  if (!contextValue) {
79
- console.warn(
80
- `The useMessageInputContext hook was called outside of the MessageInputContext provider. Make sure this hook is called within the MessageInput's UI component. The errored call is located in the ${componentName} component.`
81
- );
82
79
  return {};
83
80
  }
84
81
  return contextValue;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/plugins/Emojis/index.ts", "../../../src/plugins/Emojis/EmojiPicker.tsx", "../../../src/context/TranslationContext.tsx", "../../../src/i18n/utils.ts", "../../../src/context/MessageInputContext.tsx", "../../../src/plugins/Emojis/icons.tsx"],
4
- "sourcesContent": ["export * from './EmojiPicker';\nexport { EmojiPickerIcon } from './icons';\n", "import React, { useEffect, useState } from 'react';\nimport { usePopper } from 'react-popper';\nimport Picker from '@emoji-mart/react';\n\nimport type { Options } from '@popperjs/core';\n\nimport { useMessageInputContext, useTranslationContext } from '../../context';\nimport { EmojiPickerIcon } from './icons';\n\nconst isShadowRoot = (node: Node): node is ShadowRoot => !!(node as ShadowRoot).host;\n\nexport type EmojiPickerProps = {\n ButtonIconComponent?: React.ComponentType;\n buttonClassName?: string;\n pickerContainerClassName?: string;\n wrapperClassName?: string;\n closeOnEmojiSelect?: boolean;\n /**\n * Untyped [properties](https://github.com/missive/emoji-mart/tree/v5.5.2#options--props) to be\n * passed down to the [emoji-mart `Picker`](https://github.com/missive/emoji-mart/tree/v5.5.2#-picker) component\n */\n pickerProps?: Partial<{ theme: 'auto' | 'light' | 'dark' } & Record<string, unknown>>;\n /**\n * [React Popper options](https://popper.js.org/docs/v2/constructors/#options) to be\n * passed down to the [react-popper `usePopper`](https://popper.js.org/react-popper/v2/hook/) hook\n */\n popperOptions?: Partial<Options>;\n};\n\nconst classNames: EmojiPickerProps = {\n buttonClassName: 'str-chat__emoji-picker-button',\n pickerContainerClassName: 'str-chat__message-textarea-emoji-picker-container',\n wrapperClassName: 'str-chat__message-textarea-emoji-picker',\n};\n\nexport const EmojiPicker = (props: EmojiPickerProps) => {\n const { t } = useTranslationContext('EmojiPicker');\n const { insertText, textareaRef } = useMessageInputContext('EmojiPicker');\n const [displayPicker, setDisplayPicker] = useState(false);\n const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(\n null,\n );\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n const { attributes, styles } = usePopper(referenceElement, popperElement, {\n placement: 'top-end',\n ...props.popperOptions,\n });\n\n const { buttonClassName, pickerContainerClassName, wrapperClassName } = classNames;\n\n const { ButtonIconComponent = EmojiPickerIcon } = props;\n\n useEffect(() => {\n if (!popperElement || !referenceElement) return;\n\n const handlePointerDown = (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n\n const rootNode = target.getRootNode();\n\n if (\n popperElement.contains(isShadowRoot(rootNode) ? rootNode.host : target) ||\n referenceElement.contains(target)\n ) {\n return;\n }\n\n setDisplayPicker(false);\n };\n\n window.addEventListener('pointerdown', handlePointerDown);\n return () => window.removeEventListener('pointerdown', handlePointerDown);\n }, [referenceElement, popperElement]);\n\n return (\n <div className={props.wrapperClassName ?? wrapperClassName}>\n {displayPicker && (\n <div\n className={props.pickerContainerClassName ?? pickerContainerClassName}\n style={styles.popper}\n {...attributes.popper}\n ref={setPopperElement}\n >\n <Picker\n data={async () => (await import('@emoji-mart/data')).default}\n onEmojiSelect={(e: { native: string }) => {\n insertText(e.native);\n textareaRef.current?.focus();\n if (props.closeOnEmojiSelect) {\n setDisplayPicker(false);\n }\n }}\n {...props.pickerProps}\n />\n </div>\n )}\n <button\n aria-expanded={displayPicker}\n aria-label={t('aria/Emoji picker')}\n className={props.buttonClassName ?? buttonClassName}\n onClick={() => setDisplayPicker((cv) => !cv)}\n ref={setReferenceElement}\n type='button'\n >\n {ButtonIconComponent && <ButtonIconComponent />}\n </button>\n </div>\n );\n};\n", "import React, { PropsWithChildren, useContext } from 'react';\nimport Dayjs from 'dayjs';\nimport calendar from 'dayjs/plugin/calendar';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\n\nimport { getDisplayName } from './utils/getDisplayName';\nimport { defaultDateTimeParser, defaultTranslatorFunction } from '../i18n/utils';\n\nimport type { TFunction } from 'i18next';\nimport type { TranslationLanguages } from 'stream-chat';\n\nimport type { UnknownType } from '../types/types';\nimport type { TDateTimeParser } from '../i18n/types';\n\nDayjs.extend(calendar);\nDayjs.extend(localizedFormat);\n\nexport type TranslationContextValue = {\n t: TFunction;\n tDateTimeParser: TDateTimeParser;\n userLanguage: TranslationLanguages;\n};\n\nexport const TranslationContext = React.createContext<TranslationContextValue>({\n t: defaultTranslatorFunction,\n tDateTimeParser: defaultDateTimeParser,\n userLanguage: 'en',\n});\n\nexport const TranslationProvider = ({\n children,\n value,\n}: PropsWithChildren<{ value: TranslationContextValue }>) => (\n <TranslationContext.Provider value={value}>{children}</TranslationContext.Provider>\n);\n\nexport const useTranslationContext = (componentName?: string) => {\n const contextValue = useContext(TranslationContext);\n\n if (!contextValue) {\n console.warn(\n `The useTranslationContext hook was called outside of the TranslationContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as TranslationContextValue;\n }\n\n return contextValue;\n};\n\nexport const withTranslationContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithTranslationContextComponent = (\n props: Omit<P, keyof TranslationContextValue>,\n ) => {\n const translationContext = useTranslationContext();\n\n return <Component {...(props as P)} {...translationContext} />;\n };\n\n WithTranslationContextComponent.displayName = `WithTranslationContext${getDisplayName(\n Component,\n )}`;\n\n return WithTranslationContextComponent;\n};\n", "import Dayjs from 'dayjs';\n\nimport type { TFunction } from 'i18next';\nimport type { Moment } from 'moment-timezone';\nimport type {\n DateFormatterOptions,\n PredefinedFormatters,\n SupportedTranslations,\n TDateTimeParserInput,\n TDateTimeParserOutput,\n TimestampFormatterOptions,\n} from './types';\n\nexport const notValidDateWarning =\n 'MessageTimestamp was called without a message, or message has invalid created_at date.';\nexport const noParsingFunctionWarning =\n 'MessageTimestamp was called but there is no datetime parsing function available';\n\nexport const isNumberOrString = (\n output: TDateTimeParserOutput,\n): output is number | string => typeof output === 'string' || typeof output === 'number';\n\nexport const isDayOrMoment = (\n output: TDateTimeParserOutput,\n): output is Dayjs.Dayjs | Moment => !!(output as Dayjs.Dayjs | Moment)?.isSame;\n\nexport const isDate = (output: TDateTimeParserOutput): output is Date =>\n !!(output as Date)?.getMonth;\n\nexport function getDateString({\n calendar,\n calendarFormats,\n format,\n formatDate,\n messageCreatedAt,\n t,\n tDateTimeParser,\n timestampTranslationKey,\n}: DateFormatterOptions): string | number | null {\n if (\n !messageCreatedAt ||\n (typeof messageCreatedAt === 'string' && !Date.parse(messageCreatedAt))\n ) {\n console.warn(notValidDateWarning);\n return null;\n }\n\n if (typeof formatDate === 'function') {\n return formatDate(new Date(messageCreatedAt));\n }\n\n if (t && timestampTranslationKey) {\n const options: TimestampFormatterOptions = {};\n if (typeof calendar !== 'undefined' && calendar !== null) options.calendar = calendar;\n if (typeof calendarFormats !== 'undefined' && calendarFormats !== null)\n options.calendarFormats = calendarFormats;\n if (typeof format !== 'undefined' && format !== null) options.format = format;\n\n const translatedTimestamp = t(timestampTranslationKey, {\n ...options,\n timestamp: new Date(messageCreatedAt),\n });\n const translationKeyFound = timestampTranslationKey !== translatedTimestamp;\n if (translationKeyFound) return translatedTimestamp;\n }\n\n if (!tDateTimeParser) {\n console.warn(noParsingFunctionWarning);\n return null;\n }\n\n const parsedTime = tDateTimeParser(messageCreatedAt);\n\n if (isDayOrMoment(parsedTime)) {\n /**\n * parsedTime.calendar is guaranteed on the type but is only\n * available when a user calls dayjs.extend(calendar)\n */\n return calendar && parsedTime.calendar\n ? parsedTime.calendar(undefined, calendarFormats || undefined)\n : parsedTime.format(format || undefined);\n }\n\n if (isDate(parsedTime)) {\n return parsedTime.toDateString();\n }\n\n if (isNumberOrString(parsedTime)) {\n return parsedTime;\n }\n\n return null;\n}\n\nexport const predefinedFormatters: PredefinedFormatters = {\n timestampFormatter:\n (streamI18n) =>\n (\n value,\n _,\n {\n calendarFormats,\n ...options\n }: Pick<TimestampFormatterOptions, 'calendar' | 'format'> & {\n calendarFormats?: Record<string, string> | string;\n },\n ) => {\n let parsedCalendarFormats;\n try {\n if (!options.calendar) {\n parsedCalendarFormats = {};\n } else if (typeof calendarFormats === 'string') {\n parsedCalendarFormats = JSON.parse(calendarFormats);\n } else if (typeof calendarFormats === 'object') {\n parsedCalendarFormats = calendarFormats;\n }\n } catch (e) {\n console.error('[TIMESTAMP FORMATTER]', e);\n }\n\n const result = getDateString({\n ...options,\n calendarFormats: parsedCalendarFormats,\n messageCreatedAt: value,\n tDateTimeParser: streamI18n.tDateTimeParser,\n });\n if (!result || typeof result === 'number') {\n return JSON.stringify(value);\n }\n return result;\n },\n};\n\nexport const defaultTranslatorFunction: TFunction = <tResult = string>(key: tResult) =>\n key;\n\nexport const defaultDateTimeParser = (input?: TDateTimeParserInput) => Dayjs(input);\n\nexport const isLanguageSupported = (\n language: string,\n): language is SupportedTranslations => {\n const translations = [\n 'de',\n 'en',\n 'es',\n 'fr',\n 'hi',\n 'it',\n 'ja',\n 'ko',\n 'nl',\n 'pt',\n 'ru',\n 'tr',\n ];\n return translations.some((translation) => language === translation);\n};\n", "import React, { createContext, PropsWithChildren, useContext } from 'react';\n\nimport type { TriggerSettings } from '../components/MessageInput/DefaultTriggerProvider';\nimport type { CooldownTimerState, MessageInputProps } from '../components/MessageInput';\nimport type {\n CommandsListState,\n MentionsListState,\n MessageInputHookProps,\n MessageInputState,\n} from '../components/MessageInput/hooks/useMessageInputState';\n\nimport type { CustomTrigger, DefaultStreamChatGenerics } from '../types/types';\n\nexport type MessageInputContextValue<\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n V extends CustomTrigger = CustomTrigger,\n> = MessageInputState<StreamChatGenerics> &\n MessageInputHookProps<StreamChatGenerics> &\n Omit<MessageInputProps<StreamChatGenerics, V>, 'Input'> &\n CooldownTimerState & {\n autocompleteTriggers?: TriggerSettings<StreamChatGenerics, V>;\n } & CommandsListState &\n MentionsListState;\n\nexport const MessageInputContext = createContext<\n (MessageInputState & MessageInputHookProps) | undefined\n>(undefined);\n\nexport const MessageInputContextProvider = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n V extends CustomTrigger = CustomTrigger,\n>({\n children,\n value,\n}: PropsWithChildren<{\n value: MessageInputContextValue<StreamChatGenerics, V>;\n}>) => (\n <MessageInputContext.Provider value={value as MessageInputContextValue}>\n {children}\n </MessageInputContext.Provider>\n);\n\nexport const useMessageInputContext = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n V extends CustomTrigger = CustomTrigger,\n>(\n componentName?: string,\n) => {\n const contextValue = useContext(MessageInputContext);\n\n if (!contextValue) {\n console.warn(\n `The useMessageInputContext hook was called outside of the MessageInputContext provider. Make sure this hook is called within the MessageInput's UI component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as MessageInputContextValue<StreamChatGenerics, V>;\n }\n\n return contextValue as MessageInputContextValue<StreamChatGenerics, V>;\n};\n", "import React from 'react';\n\nexport const EmojiPickerIcon = () => (\n <svg\n preserveAspectRatio='xMinYMin'\n viewBox='0 0 28 28'\n width='100%'\n xmlns='http://www.w3.org/2000/svg'\n >\n <g clipRule='evenodd' fillRule='evenodd'>\n <path d='M14 4.4C8.6 4.4 4.4 8.6 4.4 14c0 5.4 4.2 9.6 9.6 9.6c5.4 0 9.6-4.2 9.6-9.6c0-5.4-4.2-9.6-9.6-9.6zM2 14c0-6.6 5.4-12 12-12s12 5.4 12 12s-5.4 12-12 12s-12-5.4-12-12zM12.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM18.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM8.6 15.4c.6-.4 1.2-.2 1.6.2c.6.8 1.6 1.8 3 2c1.2.4 2.8.2 4.8-2c.4-.4 1.2-.6 1.6 0c.4.4.6 1.2 0 1.6c-2.2 2.6-4.8 3.4-7 3c-2-.4-3.6-1.8-4.4-3c-.4-.6-.2-1.2.4-1.8z'></path>\n </g>\n </svg>\n);\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["export * from './EmojiPicker';\nexport { EmojiPickerIcon } from './icons';\n", "import React, { useEffect, useState } from 'react';\nimport { usePopper } from 'react-popper';\nimport Picker from '@emoji-mart/react';\n\nimport type { Options } from '@popperjs/core';\n\nimport { useMessageInputContext, useTranslationContext } from '../../context';\nimport { EmojiPickerIcon } from './icons';\n\nconst isShadowRoot = (node: Node): node is ShadowRoot => !!(node as ShadowRoot).host;\n\nexport type EmojiPickerProps = {\n ButtonIconComponent?: React.ComponentType;\n buttonClassName?: string;\n pickerContainerClassName?: string;\n wrapperClassName?: string;\n closeOnEmojiSelect?: boolean;\n /**\n * Untyped [properties](https://github.com/missive/emoji-mart/tree/v5.5.2#options--props) to be\n * passed down to the [emoji-mart `Picker`](https://github.com/missive/emoji-mart/tree/v5.5.2#-picker) component\n */\n pickerProps?: Partial<{ theme: 'auto' | 'light' | 'dark' } & Record<string, unknown>>;\n /**\n * [React Popper options](https://popper.js.org/docs/v2/constructors/#options) to be\n * passed down to the [react-popper `usePopper`](https://popper.js.org/react-popper/v2/hook/) hook\n */\n popperOptions?: Partial<Options>;\n};\n\nconst classNames: EmojiPickerProps = {\n buttonClassName: 'str-chat__emoji-picker-button',\n pickerContainerClassName: 'str-chat__message-textarea-emoji-picker-container',\n wrapperClassName: 'str-chat__message-textarea-emoji-picker',\n};\n\nexport const EmojiPicker = (props: EmojiPickerProps) => {\n const { t } = useTranslationContext('EmojiPicker');\n const { insertText, textareaRef } = useMessageInputContext('EmojiPicker');\n const [displayPicker, setDisplayPicker] = useState(false);\n const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(\n null,\n );\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n const { attributes, styles } = usePopper(referenceElement, popperElement, {\n placement: 'top-end',\n ...props.popperOptions,\n });\n\n const { buttonClassName, pickerContainerClassName, wrapperClassName } = classNames;\n\n const { ButtonIconComponent = EmojiPickerIcon } = props;\n\n useEffect(() => {\n if (!popperElement || !referenceElement) return;\n\n const handlePointerDown = (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n\n const rootNode = target.getRootNode();\n\n if (\n popperElement.contains(isShadowRoot(rootNode) ? rootNode.host : target) ||\n referenceElement.contains(target)\n ) {\n return;\n }\n\n setDisplayPicker(false);\n };\n\n window.addEventListener('pointerdown', handlePointerDown);\n return () => window.removeEventListener('pointerdown', handlePointerDown);\n }, [referenceElement, popperElement]);\n\n return (\n <div className={props.wrapperClassName ?? wrapperClassName}>\n {displayPicker && (\n <div\n className={props.pickerContainerClassName ?? pickerContainerClassName}\n style={styles.popper}\n {...attributes.popper}\n ref={setPopperElement}\n >\n <Picker\n data={async () => (await import('@emoji-mart/data')).default}\n onEmojiSelect={(e: { native: string }) => {\n insertText(e.native);\n textareaRef.current?.focus();\n if (props.closeOnEmojiSelect) {\n setDisplayPicker(false);\n }\n }}\n {...props.pickerProps}\n />\n </div>\n )}\n <button\n aria-expanded={displayPicker}\n aria-label={t('aria/Emoji picker')}\n className={props.buttonClassName ?? buttonClassName}\n onClick={() => setDisplayPicker((cv) => !cv)}\n ref={setReferenceElement}\n type='button'\n >\n {ButtonIconComponent && <ButtonIconComponent />}\n </button>\n </div>\n );\n};\n", "import React, { PropsWithChildren, useContext } from 'react';\nimport Dayjs from 'dayjs';\nimport calendar from 'dayjs/plugin/calendar';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\n\nimport { getDisplayName } from './utils/getDisplayName';\nimport { defaultDateTimeParser, defaultTranslatorFunction } from '../i18n/utils';\n\nimport type { TFunction } from 'i18next';\nimport type { TranslationLanguages } from 'stream-chat';\n\nimport type { UnknownType } from '../types/types';\nimport type { TDateTimeParser } from '../i18n/types';\n\nDayjs.extend(calendar);\nDayjs.extend(localizedFormat);\n\nexport type TranslationContextValue = {\n t: TFunction;\n tDateTimeParser: TDateTimeParser;\n userLanguage: TranslationLanguages;\n};\n\nexport const TranslationContext = React.createContext<TranslationContextValue>({\n t: defaultTranslatorFunction,\n tDateTimeParser: defaultDateTimeParser,\n userLanguage: 'en',\n});\n\nexport const TranslationProvider = ({\n children,\n value,\n}: PropsWithChildren<{ value: TranslationContextValue }>) => (\n <TranslationContext.Provider value={value}>{children}</TranslationContext.Provider>\n);\n\nexport const useTranslationContext = (componentName?: string) => {\n const contextValue = useContext(TranslationContext);\n\n if (!contextValue) {\n console.warn(\n `The useTranslationContext hook was called outside of the TranslationContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as TranslationContextValue;\n }\n\n return contextValue;\n};\n\nexport const withTranslationContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithTranslationContextComponent = (\n props: Omit<P, keyof TranslationContextValue>,\n ) => {\n const translationContext = useTranslationContext();\n\n return <Component {...(props as P)} {...translationContext} />;\n };\n\n WithTranslationContextComponent.displayName = `WithTranslationContext${getDisplayName(\n Component,\n )}`;\n\n return WithTranslationContextComponent;\n};\n", "import Dayjs from 'dayjs';\n\nimport type { TFunction } from 'i18next';\nimport type { Moment } from 'moment-timezone';\nimport type {\n DateFormatterOptions,\n PredefinedFormatters,\n SupportedTranslations,\n TDateTimeParserInput,\n TDateTimeParserOutput,\n TimestampFormatterOptions,\n} from './types';\n\nexport const notValidDateWarning =\n 'MessageTimestamp was called without a message, or message has invalid created_at date.';\nexport const noParsingFunctionWarning =\n 'MessageTimestamp was called but there is no datetime parsing function available';\n\nexport const isNumberOrString = (\n output: TDateTimeParserOutput,\n): output is number | string => typeof output === 'string' || typeof output === 'number';\n\nexport const isDayOrMoment = (\n output: TDateTimeParserOutput,\n): output is Dayjs.Dayjs | Moment => !!(output as Dayjs.Dayjs | Moment)?.isSame;\n\nexport const isDate = (output: TDateTimeParserOutput): output is Date =>\n !!(output as Date)?.getMonth;\n\nexport function getDateString({\n calendar,\n calendarFormats,\n format,\n formatDate,\n messageCreatedAt,\n t,\n tDateTimeParser,\n timestampTranslationKey,\n}: DateFormatterOptions): string | number | null {\n if (\n !messageCreatedAt ||\n (typeof messageCreatedAt === 'string' && !Date.parse(messageCreatedAt))\n ) {\n console.warn(notValidDateWarning);\n return null;\n }\n\n if (typeof formatDate === 'function') {\n return formatDate(new Date(messageCreatedAt));\n }\n\n if (t && timestampTranslationKey) {\n const options: TimestampFormatterOptions = {};\n if (typeof calendar !== 'undefined' && calendar !== null) options.calendar = calendar;\n if (typeof calendarFormats !== 'undefined' && calendarFormats !== null)\n options.calendarFormats = calendarFormats;\n if (typeof format !== 'undefined' && format !== null) options.format = format;\n\n const translatedTimestamp = t(timestampTranslationKey, {\n ...options,\n timestamp: new Date(messageCreatedAt),\n });\n const translationKeyFound = timestampTranslationKey !== translatedTimestamp;\n if (translationKeyFound) return translatedTimestamp;\n }\n\n if (!tDateTimeParser) {\n console.warn(noParsingFunctionWarning);\n return null;\n }\n\n const parsedTime = tDateTimeParser(messageCreatedAt);\n\n if (isDayOrMoment(parsedTime)) {\n /**\n * parsedTime.calendar is guaranteed on the type but is only\n * available when a user calls dayjs.extend(calendar)\n */\n return calendar && parsedTime.calendar\n ? parsedTime.calendar(undefined, calendarFormats || undefined)\n : parsedTime.format(format || undefined);\n }\n\n if (isDate(parsedTime)) {\n return parsedTime.toDateString();\n }\n\n if (isNumberOrString(parsedTime)) {\n return parsedTime;\n }\n\n return null;\n}\n\nexport const predefinedFormatters: PredefinedFormatters = {\n timestampFormatter:\n (streamI18n) =>\n (\n value,\n _,\n {\n calendarFormats,\n ...options\n }: Pick<TimestampFormatterOptions, 'calendar' | 'format'> & {\n calendarFormats?: Record<string, string> | string;\n },\n ) => {\n let parsedCalendarFormats;\n try {\n if (!options.calendar) {\n parsedCalendarFormats = {};\n } else if (typeof calendarFormats === 'string') {\n parsedCalendarFormats = JSON.parse(calendarFormats);\n } else if (typeof calendarFormats === 'object') {\n parsedCalendarFormats = calendarFormats;\n }\n } catch (e) {\n console.error('[TIMESTAMP FORMATTER]', e);\n }\n\n const result = getDateString({\n ...options,\n calendarFormats: parsedCalendarFormats,\n messageCreatedAt: value,\n tDateTimeParser: streamI18n.tDateTimeParser,\n });\n if (!result || typeof result === 'number') {\n return JSON.stringify(value);\n }\n return result;\n },\n};\n\nexport const defaultTranslatorFunction: TFunction = <tResult = string>(key: tResult) =>\n key;\n\nexport const defaultDateTimeParser = (input?: TDateTimeParserInput) => Dayjs(input);\n\nexport const isLanguageSupported = (\n language: string,\n): language is SupportedTranslations => {\n const translations = [\n 'de',\n 'en',\n 'es',\n 'fr',\n 'hi',\n 'it',\n 'ja',\n 'ko',\n 'nl',\n 'pt',\n 'ru',\n 'tr',\n ];\n return translations.some((translation) => language === translation);\n};\n", "import React, { createContext, PropsWithChildren, useContext } from 'react';\n\nimport type { TriggerSettings } from '../components/MessageInput/DefaultTriggerProvider';\nimport type { CooldownTimerState, MessageInputProps } from '../components/MessageInput';\nimport type {\n CommandsListState,\n MentionsListState,\n MessageInputHookProps,\n MessageInputState,\n} from '../components/MessageInput/hooks/useMessageInputState';\n\nimport type { CustomTrigger, DefaultStreamChatGenerics } from '../types/types';\n\nexport type MessageInputContextValue<\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n V extends CustomTrigger = CustomTrigger,\n> = MessageInputState<StreamChatGenerics> &\n MessageInputHookProps<StreamChatGenerics> &\n Omit<MessageInputProps<StreamChatGenerics, V>, 'Input'> &\n CooldownTimerState & {\n autocompleteTriggers?: TriggerSettings<StreamChatGenerics, V>;\n } & CommandsListState &\n MentionsListState;\n\nexport const MessageInputContext = createContext<\n (MessageInputState & MessageInputHookProps) | undefined\n>(undefined);\n\nexport const MessageInputContextProvider = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n V extends CustomTrigger = CustomTrigger,\n>({\n children,\n value,\n}: PropsWithChildren<{\n value: MessageInputContextValue<StreamChatGenerics, V>;\n}>) => (\n <MessageInputContext.Provider value={value as MessageInputContextValue}>\n {children}\n </MessageInputContext.Provider>\n);\n\nexport const useMessageInputContext = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n V extends CustomTrigger = CustomTrigger,\n>(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n componentName?: string,\n) => {\n const contextValue = useContext(MessageInputContext);\n\n if (!contextValue) {\n return {} as MessageInputContextValue<StreamChatGenerics, V>;\n }\n\n return contextValue as MessageInputContextValue<StreamChatGenerics, V>;\n};\n", "import React from 'react';\n\nexport const EmojiPickerIcon = () => (\n <svg\n preserveAspectRatio='xMinYMin'\n viewBox='0 0 28 28'\n width='100%'\n xmlns='http://www.w3.org/2000/svg'\n >\n <g clipRule='evenodd' fillRule='evenodd'>\n <path d='M14 4.4C8.6 4.4 4.4 8.6 4.4 14c0 5.4 4.2 9.6 9.6 9.6c5.4 0 9.6-4.2 9.6-9.6c0-5.4-4.2-9.6-9.6-9.6zM2 14c0-6.6 5.4-12 12-12s12 5.4 12 12s-5.4 12-12 12s-12-5.4-12-12zM12.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM18.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM8.6 15.4c.6-.4 1.2-.2 1.6.2c.6.8 1.6 1.8 3 2c1.2.4 2.8.2 4.8-2c.4-.4 1.2-.6 1.6 0c.4.4.6 1.2 0 1.6c-2.2 2.6-4.8 3.4-7 3c-2-.4-3.6-1.8-4.4-3c-.4-.6-.2-1.2.4-1.8z'></path>\n </g>\n </svg>\n);\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_react", "import_dayjs", "Dayjs", "Dayjs", "calendar", "localizedFormat", "React", "import_react", "import_react", "React", "React", "Picker"]
7
7
  }
@@ -76,9 +76,6 @@ var MessageInputContext = (0, import_react2.createContext)(void 0);
76
76
  var useMessageInputContext = (componentName) => {
77
77
  const contextValue = (0, import_react2.useContext)(MessageInputContext);
78
78
  if (!contextValue) {
79
- console.warn(
80
- `The useMessageInputContext hook was called outside of the MessageInputContext provider. Make sure this hook is called within the MessageInput's UI component. The errored call is located in the ${componentName} component.`
81
- );
82
79
  return {};
83
80
  }
84
81
  return contextValue;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/plugins/Emojis/index.ts", "../../../src/plugins/Emojis/EmojiPicker.tsx", "../../../src/context/TranslationContext.tsx", "../../../src/i18n/utils.ts", "../../../src/context/MessageInputContext.tsx", "../../../src/plugins/Emojis/icons.tsx"],
4
- "sourcesContent": ["export * from './EmojiPicker';\nexport { EmojiPickerIcon } from './icons';\n", "import React, { useEffect, useState } from 'react';\nimport { usePopper } from 'react-popper';\nimport Picker from '@emoji-mart/react';\n\nimport type { Options } from '@popperjs/core';\n\nimport { useMessageInputContext, useTranslationContext } from '../../context';\nimport { EmojiPickerIcon } from './icons';\n\nconst isShadowRoot = (node: Node): node is ShadowRoot => !!(node as ShadowRoot).host;\n\nexport type EmojiPickerProps = {\n ButtonIconComponent?: React.ComponentType;\n buttonClassName?: string;\n pickerContainerClassName?: string;\n wrapperClassName?: string;\n closeOnEmojiSelect?: boolean;\n /**\n * Untyped [properties](https://github.com/missive/emoji-mart/tree/v5.5.2#options--props) to be\n * passed down to the [emoji-mart `Picker`](https://github.com/missive/emoji-mart/tree/v5.5.2#-picker) component\n */\n pickerProps?: Partial<{ theme: 'auto' | 'light' | 'dark' } & Record<string, unknown>>;\n /**\n * [React Popper options](https://popper.js.org/docs/v2/constructors/#options) to be\n * passed down to the [react-popper `usePopper`](https://popper.js.org/react-popper/v2/hook/) hook\n */\n popperOptions?: Partial<Options>;\n};\n\nconst classNames: EmojiPickerProps = {\n buttonClassName: 'str-chat__emoji-picker-button',\n pickerContainerClassName: 'str-chat__message-textarea-emoji-picker-container',\n wrapperClassName: 'str-chat__message-textarea-emoji-picker',\n};\n\nexport const EmojiPicker = (props: EmojiPickerProps) => {\n const { t } = useTranslationContext('EmojiPicker');\n const { insertText, textareaRef } = useMessageInputContext('EmojiPicker');\n const [displayPicker, setDisplayPicker] = useState(false);\n const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(\n null,\n );\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n const { attributes, styles } = usePopper(referenceElement, popperElement, {\n placement: 'top-end',\n ...props.popperOptions,\n });\n\n const { buttonClassName, pickerContainerClassName, wrapperClassName } = classNames;\n\n const { ButtonIconComponent = EmojiPickerIcon } = props;\n\n useEffect(() => {\n if (!popperElement || !referenceElement) return;\n\n const handlePointerDown = (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n\n const rootNode = target.getRootNode();\n\n if (\n popperElement.contains(isShadowRoot(rootNode) ? rootNode.host : target) ||\n referenceElement.contains(target)\n ) {\n return;\n }\n\n setDisplayPicker(false);\n };\n\n window.addEventListener('pointerdown', handlePointerDown);\n return () => window.removeEventListener('pointerdown', handlePointerDown);\n }, [referenceElement, popperElement]);\n\n return (\n <div className={props.wrapperClassName ?? wrapperClassName}>\n {displayPicker && (\n <div\n className={props.pickerContainerClassName ?? pickerContainerClassName}\n style={styles.popper}\n {...attributes.popper}\n ref={setPopperElement}\n >\n <Picker\n data={async () => (await import('@emoji-mart/data')).default}\n onEmojiSelect={(e: { native: string }) => {\n insertText(e.native);\n textareaRef.current?.focus();\n if (props.closeOnEmojiSelect) {\n setDisplayPicker(false);\n }\n }}\n {...props.pickerProps}\n />\n </div>\n )}\n <button\n aria-expanded={displayPicker}\n aria-label={t('aria/Emoji picker')}\n className={props.buttonClassName ?? buttonClassName}\n onClick={() => setDisplayPicker((cv) => !cv)}\n ref={setReferenceElement}\n type='button'\n >\n {ButtonIconComponent && <ButtonIconComponent />}\n </button>\n </div>\n );\n};\n", "import React, { PropsWithChildren, useContext } from 'react';\nimport Dayjs from 'dayjs';\nimport calendar from 'dayjs/plugin/calendar';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\n\nimport { getDisplayName } from './utils/getDisplayName';\nimport { defaultDateTimeParser, defaultTranslatorFunction } from '../i18n/utils';\n\nimport type { TFunction } from 'i18next';\nimport type { TranslationLanguages } from 'stream-chat';\n\nimport type { UnknownType } from '../types/types';\nimport type { TDateTimeParser } from '../i18n/types';\n\nDayjs.extend(calendar);\nDayjs.extend(localizedFormat);\n\nexport type TranslationContextValue = {\n t: TFunction;\n tDateTimeParser: TDateTimeParser;\n userLanguage: TranslationLanguages;\n};\n\nexport const TranslationContext = React.createContext<TranslationContextValue>({\n t: defaultTranslatorFunction,\n tDateTimeParser: defaultDateTimeParser,\n userLanguage: 'en',\n});\n\nexport const TranslationProvider = ({\n children,\n value,\n}: PropsWithChildren<{ value: TranslationContextValue }>) => (\n <TranslationContext.Provider value={value}>{children}</TranslationContext.Provider>\n);\n\nexport const useTranslationContext = (componentName?: string) => {\n const contextValue = useContext(TranslationContext);\n\n if (!contextValue) {\n console.warn(\n `The useTranslationContext hook was called outside of the TranslationContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as TranslationContextValue;\n }\n\n return contextValue;\n};\n\nexport const withTranslationContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithTranslationContextComponent = (\n props: Omit<P, keyof TranslationContextValue>,\n ) => {\n const translationContext = useTranslationContext();\n\n return <Component {...(props as P)} {...translationContext} />;\n };\n\n WithTranslationContextComponent.displayName = `WithTranslationContext${getDisplayName(\n Component,\n )}`;\n\n return WithTranslationContextComponent;\n};\n", "import Dayjs from 'dayjs';\n\nimport type { TFunction } from 'i18next';\nimport type { Moment } from 'moment-timezone';\nimport type {\n DateFormatterOptions,\n PredefinedFormatters,\n SupportedTranslations,\n TDateTimeParserInput,\n TDateTimeParserOutput,\n TimestampFormatterOptions,\n} from './types';\n\nexport const notValidDateWarning =\n 'MessageTimestamp was called without a message, or message has invalid created_at date.';\nexport const noParsingFunctionWarning =\n 'MessageTimestamp was called but there is no datetime parsing function available';\n\nexport const isNumberOrString = (\n output: TDateTimeParserOutput,\n): output is number | string => typeof output === 'string' || typeof output === 'number';\n\nexport const isDayOrMoment = (\n output: TDateTimeParserOutput,\n): output is Dayjs.Dayjs | Moment => !!(output as Dayjs.Dayjs | Moment)?.isSame;\n\nexport const isDate = (output: TDateTimeParserOutput): output is Date =>\n !!(output as Date)?.getMonth;\n\nexport function getDateString({\n calendar,\n calendarFormats,\n format,\n formatDate,\n messageCreatedAt,\n t,\n tDateTimeParser,\n timestampTranslationKey,\n}: DateFormatterOptions): string | number | null {\n if (\n !messageCreatedAt ||\n (typeof messageCreatedAt === 'string' && !Date.parse(messageCreatedAt))\n ) {\n console.warn(notValidDateWarning);\n return null;\n }\n\n if (typeof formatDate === 'function') {\n return formatDate(new Date(messageCreatedAt));\n }\n\n if (t && timestampTranslationKey) {\n const options: TimestampFormatterOptions = {};\n if (typeof calendar !== 'undefined' && calendar !== null) options.calendar = calendar;\n if (typeof calendarFormats !== 'undefined' && calendarFormats !== null)\n options.calendarFormats = calendarFormats;\n if (typeof format !== 'undefined' && format !== null) options.format = format;\n\n const translatedTimestamp = t(timestampTranslationKey, {\n ...options,\n timestamp: new Date(messageCreatedAt),\n });\n const translationKeyFound = timestampTranslationKey !== translatedTimestamp;\n if (translationKeyFound) return translatedTimestamp;\n }\n\n if (!tDateTimeParser) {\n console.warn(noParsingFunctionWarning);\n return null;\n }\n\n const parsedTime = tDateTimeParser(messageCreatedAt);\n\n if (isDayOrMoment(parsedTime)) {\n /**\n * parsedTime.calendar is guaranteed on the type but is only\n * available when a user calls dayjs.extend(calendar)\n */\n return calendar && parsedTime.calendar\n ? parsedTime.calendar(undefined, calendarFormats || undefined)\n : parsedTime.format(format || undefined);\n }\n\n if (isDate(parsedTime)) {\n return parsedTime.toDateString();\n }\n\n if (isNumberOrString(parsedTime)) {\n return parsedTime;\n }\n\n return null;\n}\n\nexport const predefinedFormatters: PredefinedFormatters = {\n timestampFormatter:\n (streamI18n) =>\n (\n value,\n _,\n {\n calendarFormats,\n ...options\n }: Pick<TimestampFormatterOptions, 'calendar' | 'format'> & {\n calendarFormats?: Record<string, string> | string;\n },\n ) => {\n let parsedCalendarFormats;\n try {\n if (!options.calendar) {\n parsedCalendarFormats = {};\n } else if (typeof calendarFormats === 'string') {\n parsedCalendarFormats = JSON.parse(calendarFormats);\n } else if (typeof calendarFormats === 'object') {\n parsedCalendarFormats = calendarFormats;\n }\n } catch (e) {\n console.error('[TIMESTAMP FORMATTER]', e);\n }\n\n const result = getDateString({\n ...options,\n calendarFormats: parsedCalendarFormats,\n messageCreatedAt: value,\n tDateTimeParser: streamI18n.tDateTimeParser,\n });\n if (!result || typeof result === 'number') {\n return JSON.stringify(value);\n }\n return result;\n },\n};\n\nexport const defaultTranslatorFunction: TFunction = <tResult = string>(key: tResult) =>\n key;\n\nexport const defaultDateTimeParser = (input?: TDateTimeParserInput) => Dayjs(input);\n\nexport const isLanguageSupported = (\n language: string,\n): language is SupportedTranslations => {\n const translations = [\n 'de',\n 'en',\n 'es',\n 'fr',\n 'hi',\n 'it',\n 'ja',\n 'ko',\n 'nl',\n 'pt',\n 'ru',\n 'tr',\n ];\n return translations.some((translation) => language === translation);\n};\n", "import React, { createContext, PropsWithChildren, useContext } from 'react';\n\nimport type { TriggerSettings } from '../components/MessageInput/DefaultTriggerProvider';\nimport type { CooldownTimerState, MessageInputProps } from '../components/MessageInput';\nimport type {\n CommandsListState,\n MentionsListState,\n MessageInputHookProps,\n MessageInputState,\n} from '../components/MessageInput/hooks/useMessageInputState';\n\nimport type { CustomTrigger, DefaultStreamChatGenerics } from '../types/types';\n\nexport type MessageInputContextValue<\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n V extends CustomTrigger = CustomTrigger,\n> = MessageInputState<StreamChatGenerics> &\n MessageInputHookProps<StreamChatGenerics> &\n Omit<MessageInputProps<StreamChatGenerics, V>, 'Input'> &\n CooldownTimerState & {\n autocompleteTriggers?: TriggerSettings<StreamChatGenerics, V>;\n } & CommandsListState &\n MentionsListState;\n\nexport const MessageInputContext = createContext<\n (MessageInputState & MessageInputHookProps) | undefined\n>(undefined);\n\nexport const MessageInputContextProvider = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n V extends CustomTrigger = CustomTrigger,\n>({\n children,\n value,\n}: PropsWithChildren<{\n value: MessageInputContextValue<StreamChatGenerics, V>;\n}>) => (\n <MessageInputContext.Provider value={value as MessageInputContextValue}>\n {children}\n </MessageInputContext.Provider>\n);\n\nexport const useMessageInputContext = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n V extends CustomTrigger = CustomTrigger,\n>(\n componentName?: string,\n) => {\n const contextValue = useContext(MessageInputContext);\n\n if (!contextValue) {\n console.warn(\n `The useMessageInputContext hook was called outside of the MessageInputContext provider. Make sure this hook is called within the MessageInput's UI component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as MessageInputContextValue<StreamChatGenerics, V>;\n }\n\n return contextValue as MessageInputContextValue<StreamChatGenerics, V>;\n};\n", "import React from 'react';\n\nexport const EmojiPickerIcon = () => (\n <svg\n preserveAspectRatio='xMinYMin'\n viewBox='0 0 28 28'\n width='100%'\n xmlns='http://www.w3.org/2000/svg'\n >\n <g clipRule='evenodd' fillRule='evenodd'>\n <path d='M14 4.4C8.6 4.4 4.4 8.6 4.4 14c0 5.4 4.2 9.6 9.6 9.6c5.4 0 9.6-4.2 9.6-9.6c0-5.4-4.2-9.6-9.6-9.6zM2 14c0-6.6 5.4-12 12-12s12 5.4 12 12s-5.4 12-12 12s-12-5.4-12-12zM12.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM18.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM8.6 15.4c.6-.4 1.2-.2 1.6.2c.6.8 1.6 1.8 3 2c1.2.4 2.8.2 4.8-2c.4-.4 1.2-.6 1.6 0c.4.4.6 1.2 0 1.6c-2.2 2.6-4.8 3.4-7 3c-2-.4-3.6-1.8-4.4-3c-.4-.6-.2-1.2.4-1.8z'></path>\n </g>\n </svg>\n);\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["export * from './EmojiPicker';\nexport { EmojiPickerIcon } from './icons';\n", "import React, { useEffect, useState } from 'react';\nimport { usePopper } from 'react-popper';\nimport Picker from '@emoji-mart/react';\n\nimport type { Options } from '@popperjs/core';\n\nimport { useMessageInputContext, useTranslationContext } from '../../context';\nimport { EmojiPickerIcon } from './icons';\n\nconst isShadowRoot = (node: Node): node is ShadowRoot => !!(node as ShadowRoot).host;\n\nexport type EmojiPickerProps = {\n ButtonIconComponent?: React.ComponentType;\n buttonClassName?: string;\n pickerContainerClassName?: string;\n wrapperClassName?: string;\n closeOnEmojiSelect?: boolean;\n /**\n * Untyped [properties](https://github.com/missive/emoji-mart/tree/v5.5.2#options--props) to be\n * passed down to the [emoji-mart `Picker`](https://github.com/missive/emoji-mart/tree/v5.5.2#-picker) component\n */\n pickerProps?: Partial<{ theme: 'auto' | 'light' | 'dark' } & Record<string, unknown>>;\n /**\n * [React Popper options](https://popper.js.org/docs/v2/constructors/#options) to be\n * passed down to the [react-popper `usePopper`](https://popper.js.org/react-popper/v2/hook/) hook\n */\n popperOptions?: Partial<Options>;\n};\n\nconst classNames: EmojiPickerProps = {\n buttonClassName: 'str-chat__emoji-picker-button',\n pickerContainerClassName: 'str-chat__message-textarea-emoji-picker-container',\n wrapperClassName: 'str-chat__message-textarea-emoji-picker',\n};\n\nexport const EmojiPicker = (props: EmojiPickerProps) => {\n const { t } = useTranslationContext('EmojiPicker');\n const { insertText, textareaRef } = useMessageInputContext('EmojiPicker');\n const [displayPicker, setDisplayPicker] = useState(false);\n const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(\n null,\n );\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n const { attributes, styles } = usePopper(referenceElement, popperElement, {\n placement: 'top-end',\n ...props.popperOptions,\n });\n\n const { buttonClassName, pickerContainerClassName, wrapperClassName } = classNames;\n\n const { ButtonIconComponent = EmojiPickerIcon } = props;\n\n useEffect(() => {\n if (!popperElement || !referenceElement) return;\n\n const handlePointerDown = (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n\n const rootNode = target.getRootNode();\n\n if (\n popperElement.contains(isShadowRoot(rootNode) ? rootNode.host : target) ||\n referenceElement.contains(target)\n ) {\n return;\n }\n\n setDisplayPicker(false);\n };\n\n window.addEventListener('pointerdown', handlePointerDown);\n return () => window.removeEventListener('pointerdown', handlePointerDown);\n }, [referenceElement, popperElement]);\n\n return (\n <div className={props.wrapperClassName ?? wrapperClassName}>\n {displayPicker && (\n <div\n className={props.pickerContainerClassName ?? pickerContainerClassName}\n style={styles.popper}\n {...attributes.popper}\n ref={setPopperElement}\n >\n <Picker\n data={async () => (await import('@emoji-mart/data')).default}\n onEmojiSelect={(e: { native: string }) => {\n insertText(e.native);\n textareaRef.current?.focus();\n if (props.closeOnEmojiSelect) {\n setDisplayPicker(false);\n }\n }}\n {...props.pickerProps}\n />\n </div>\n )}\n <button\n aria-expanded={displayPicker}\n aria-label={t('aria/Emoji picker')}\n className={props.buttonClassName ?? buttonClassName}\n onClick={() => setDisplayPicker((cv) => !cv)}\n ref={setReferenceElement}\n type='button'\n >\n {ButtonIconComponent && <ButtonIconComponent />}\n </button>\n </div>\n );\n};\n", "import React, { PropsWithChildren, useContext } from 'react';\nimport Dayjs from 'dayjs';\nimport calendar from 'dayjs/plugin/calendar';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\n\nimport { getDisplayName } from './utils/getDisplayName';\nimport { defaultDateTimeParser, defaultTranslatorFunction } from '../i18n/utils';\n\nimport type { TFunction } from 'i18next';\nimport type { TranslationLanguages } from 'stream-chat';\n\nimport type { UnknownType } from '../types/types';\nimport type { TDateTimeParser } from '../i18n/types';\n\nDayjs.extend(calendar);\nDayjs.extend(localizedFormat);\n\nexport type TranslationContextValue = {\n t: TFunction;\n tDateTimeParser: TDateTimeParser;\n userLanguage: TranslationLanguages;\n};\n\nexport const TranslationContext = React.createContext<TranslationContextValue>({\n t: defaultTranslatorFunction,\n tDateTimeParser: defaultDateTimeParser,\n userLanguage: 'en',\n});\n\nexport const TranslationProvider = ({\n children,\n value,\n}: PropsWithChildren<{ value: TranslationContextValue }>) => (\n <TranslationContext.Provider value={value}>{children}</TranslationContext.Provider>\n);\n\nexport const useTranslationContext = (componentName?: string) => {\n const contextValue = useContext(TranslationContext);\n\n if (!contextValue) {\n console.warn(\n `The useTranslationContext hook was called outside of the TranslationContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as TranslationContextValue;\n }\n\n return contextValue;\n};\n\nexport const withTranslationContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithTranslationContextComponent = (\n props: Omit<P, keyof TranslationContextValue>,\n ) => {\n const translationContext = useTranslationContext();\n\n return <Component {...(props as P)} {...translationContext} />;\n };\n\n WithTranslationContextComponent.displayName = `WithTranslationContext${getDisplayName(\n Component,\n )}`;\n\n return WithTranslationContextComponent;\n};\n", "import Dayjs from 'dayjs';\n\nimport type { TFunction } from 'i18next';\nimport type { Moment } from 'moment-timezone';\nimport type {\n DateFormatterOptions,\n PredefinedFormatters,\n SupportedTranslations,\n TDateTimeParserInput,\n TDateTimeParserOutput,\n TimestampFormatterOptions,\n} from './types';\n\nexport const notValidDateWarning =\n 'MessageTimestamp was called without a message, or message has invalid created_at date.';\nexport const noParsingFunctionWarning =\n 'MessageTimestamp was called but there is no datetime parsing function available';\n\nexport const isNumberOrString = (\n output: TDateTimeParserOutput,\n): output is number | string => typeof output === 'string' || typeof output === 'number';\n\nexport const isDayOrMoment = (\n output: TDateTimeParserOutput,\n): output is Dayjs.Dayjs | Moment => !!(output as Dayjs.Dayjs | Moment)?.isSame;\n\nexport const isDate = (output: TDateTimeParserOutput): output is Date =>\n !!(output as Date)?.getMonth;\n\nexport function getDateString({\n calendar,\n calendarFormats,\n format,\n formatDate,\n messageCreatedAt,\n t,\n tDateTimeParser,\n timestampTranslationKey,\n}: DateFormatterOptions): string | number | null {\n if (\n !messageCreatedAt ||\n (typeof messageCreatedAt === 'string' && !Date.parse(messageCreatedAt))\n ) {\n console.warn(notValidDateWarning);\n return null;\n }\n\n if (typeof formatDate === 'function') {\n return formatDate(new Date(messageCreatedAt));\n }\n\n if (t && timestampTranslationKey) {\n const options: TimestampFormatterOptions = {};\n if (typeof calendar !== 'undefined' && calendar !== null) options.calendar = calendar;\n if (typeof calendarFormats !== 'undefined' && calendarFormats !== null)\n options.calendarFormats = calendarFormats;\n if (typeof format !== 'undefined' && format !== null) options.format = format;\n\n const translatedTimestamp = t(timestampTranslationKey, {\n ...options,\n timestamp: new Date(messageCreatedAt),\n });\n const translationKeyFound = timestampTranslationKey !== translatedTimestamp;\n if (translationKeyFound) return translatedTimestamp;\n }\n\n if (!tDateTimeParser) {\n console.warn(noParsingFunctionWarning);\n return null;\n }\n\n const parsedTime = tDateTimeParser(messageCreatedAt);\n\n if (isDayOrMoment(parsedTime)) {\n /**\n * parsedTime.calendar is guaranteed on the type but is only\n * available when a user calls dayjs.extend(calendar)\n */\n return calendar && parsedTime.calendar\n ? parsedTime.calendar(undefined, calendarFormats || undefined)\n : parsedTime.format(format || undefined);\n }\n\n if (isDate(parsedTime)) {\n return parsedTime.toDateString();\n }\n\n if (isNumberOrString(parsedTime)) {\n return parsedTime;\n }\n\n return null;\n}\n\nexport const predefinedFormatters: PredefinedFormatters = {\n timestampFormatter:\n (streamI18n) =>\n (\n value,\n _,\n {\n calendarFormats,\n ...options\n }: Pick<TimestampFormatterOptions, 'calendar' | 'format'> & {\n calendarFormats?: Record<string, string> | string;\n },\n ) => {\n let parsedCalendarFormats;\n try {\n if (!options.calendar) {\n parsedCalendarFormats = {};\n } else if (typeof calendarFormats === 'string') {\n parsedCalendarFormats = JSON.parse(calendarFormats);\n } else if (typeof calendarFormats === 'object') {\n parsedCalendarFormats = calendarFormats;\n }\n } catch (e) {\n console.error('[TIMESTAMP FORMATTER]', e);\n }\n\n const result = getDateString({\n ...options,\n calendarFormats: parsedCalendarFormats,\n messageCreatedAt: value,\n tDateTimeParser: streamI18n.tDateTimeParser,\n });\n if (!result || typeof result === 'number') {\n return JSON.stringify(value);\n }\n return result;\n },\n};\n\nexport const defaultTranslatorFunction: TFunction = <tResult = string>(key: tResult) =>\n key;\n\nexport const defaultDateTimeParser = (input?: TDateTimeParserInput) => Dayjs(input);\n\nexport const isLanguageSupported = (\n language: string,\n): language is SupportedTranslations => {\n const translations = [\n 'de',\n 'en',\n 'es',\n 'fr',\n 'hi',\n 'it',\n 'ja',\n 'ko',\n 'nl',\n 'pt',\n 'ru',\n 'tr',\n ];\n return translations.some((translation) => language === translation);\n};\n", "import React, { createContext, PropsWithChildren, useContext } from 'react';\n\nimport type { TriggerSettings } from '../components/MessageInput/DefaultTriggerProvider';\nimport type { CooldownTimerState, MessageInputProps } from '../components/MessageInput';\nimport type {\n CommandsListState,\n MentionsListState,\n MessageInputHookProps,\n MessageInputState,\n} from '../components/MessageInput/hooks/useMessageInputState';\n\nimport type { CustomTrigger, DefaultStreamChatGenerics } from '../types/types';\n\nexport type MessageInputContextValue<\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n V extends CustomTrigger = CustomTrigger,\n> = MessageInputState<StreamChatGenerics> &\n MessageInputHookProps<StreamChatGenerics> &\n Omit<MessageInputProps<StreamChatGenerics, V>, 'Input'> &\n CooldownTimerState & {\n autocompleteTriggers?: TriggerSettings<StreamChatGenerics, V>;\n } & CommandsListState &\n MentionsListState;\n\nexport const MessageInputContext = createContext<\n (MessageInputState & MessageInputHookProps) | undefined\n>(undefined);\n\nexport const MessageInputContextProvider = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n V extends CustomTrigger = CustomTrigger,\n>({\n children,\n value,\n}: PropsWithChildren<{\n value: MessageInputContextValue<StreamChatGenerics, V>;\n}>) => (\n <MessageInputContext.Provider value={value as MessageInputContextValue}>\n {children}\n </MessageInputContext.Provider>\n);\n\nexport const useMessageInputContext = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n V extends CustomTrigger = CustomTrigger,\n>(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n componentName?: string,\n) => {\n const contextValue = useContext(MessageInputContext);\n\n if (!contextValue) {\n return {} as MessageInputContextValue<StreamChatGenerics, V>;\n }\n\n return contextValue as MessageInputContextValue<StreamChatGenerics, V>;\n};\n", "import React from 'react';\n\nexport const EmojiPickerIcon = () => (\n <svg\n preserveAspectRatio='xMinYMin'\n viewBox='0 0 28 28'\n width='100%'\n xmlns='http://www.w3.org/2000/svg'\n >\n <g clipRule='evenodd' fillRule='evenodd'>\n <path d='M14 4.4C8.6 4.4 4.4 8.6 4.4 14c0 5.4 4.2 9.6 9.6 9.6c5.4 0 9.6-4.2 9.6-9.6c0-5.4-4.2-9.6-9.6-9.6zM2 14c0-6.6 5.4-12 12-12s12 5.4 12 12s-5.4 12-12 12s-12-5.4-12-12zM12.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM18.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM8.6 15.4c.6-.4 1.2-.2 1.6.2c.6.8 1.6 1.8 3 2c1.2.4 2.8.2 4.8-2c.4-.4 1.2-.6 1.6 0c.4.4.6 1.2 0 1.6c-2.2 2.6-4.8 3.4-7 3c-2-.4-3.6-1.8-4.4-3c-.4-.6-.2-1.2.4-1.8z'></path>\n </g>\n </svg>\n);\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_react", "import_dayjs", "Dayjs", "Dayjs", "calendar", "localizedFormat", "React", "import_react", "import_react", "React", "React", "Picker"]
7
7
  }
@@ -0,0 +1,14 @@
1
+ @use '../utils';
2
+
3
+ .str-chat__dropzone-container {
4
+ @include utils.flex-row-center;
5
+
6
+ position: absolute;
7
+ height: 100%;
8
+ width: 100%;
9
+ z-index: 5;
10
+
11
+ p {
12
+ margin: unset;
13
+ }
14
+ }
@@ -0,0 +1,17 @@
1
+ .str-chat {
2
+ /* The text/icon color of the dropzone container */
3
+ --str-chat__dropzone-container-color: var(--str-chat__on-primary-color);
4
+
5
+ /* The background color of the dropzone container */
6
+ --str-chat__dropzone-container-background-color: var(--str-chat__primary-overlay-color);
7
+
8
+ /* The backdrop filter applied to the dropzone container */
9
+ --str-chat__dropzone-container-backdrop-filter: blur(3px);
10
+ }
11
+
12
+ .str-chat__dropzone-container {
13
+ background-color: var(--str-chat__dropzone-container-background-color);
14
+ color: var(--str-chat__dropzone-container-color);
15
+ backdrop-filter: var(--str-chat__dropzone-container-backdrop-filter);
16
+ font: var(--str-chat__subtitle-text);
17
+ }
@@ -26,19 +26,6 @@
26
26
  }
27
27
  }
28
28
 
29
- .str-chat__dropzone-container {
30
- @include utils.flex-row-center;
31
-
32
- position: absolute;
33
- height: 100%;
34
- width: 100%;
35
- z-index: 5;
36
-
37
- p {
38
- margin: unset;
39
- }
40
- }
41
-
42
29
  .str-chat__message-input-inner {
43
30
  flex-grow: 1;
44
31
  width: 100%;
@@ -25,15 +25,6 @@
25
25
  /* Box shadow applied to the component */
26
26
  --str-chat__message-input-box-shadow: none;
27
27
 
28
- /* The text/icon color of the dropzone container */
29
- --str-chat__dropzone-container-color: var(--str-chat__on-primary-color);
30
-
31
- /* The background color of the dropzone container */
32
- --str-chat__dropzone-container-background-color: var(--str-chat__primary-overlay-color);
33
-
34
- /* The backdrop filter applied to the dropzone container */
35
- --str-chat__dropzone-container-backdrop-filter: blur(3px);
36
-
37
28
  /* The border radius used for the borders of the textarea */
38
29
  --str-chat__message-textarea-border-radius: var(--str-chat__border-radius-md);
39
30
 
@@ -179,19 +170,14 @@
179
170
  --str-chat__attachment-selector-actions-menu-button-icon-color: var(--str-chat__primary-color);
180
171
 
181
172
  /* Color applied to an attachment selector menu item icon when hovered over or focused */
182
- --str-chat__attachment-selector-actions-menu-button-icon-color-active: var(--str-chat__primary-color);
173
+ --str-chat__attachment-selector-actions-menu-button-icon-color-active: var(
174
+ --str-chat__primary-color
175
+ );
183
176
  }
184
177
 
185
178
  .str-chat__message-input {
186
179
  @include utils.component-layer-overrides('message-input');
187
180
 
188
- .str-chat__dropzone-container {
189
- background-color: var(--str-chat__dropzone-container-background-color);
190
- color: var(--str-chat__dropzone-container-color);
191
- backdrop-filter: var(--str-chat__dropzone-container-backdrop-filter);
192
- font: var(--str-chat__subtitle-text);
193
- }
194
-
195
181
  .str-chat__file-input-container {
196
182
  --str-chat-icon-color: var(--str-chat__message-input-tools-color);
197
183
  @include utils.component-layer-overrides('message-input-tools');
@@ -326,11 +312,14 @@
326
312
  background-color: var(--str-chat__attachment-selector-actions-menu-button-icon-color);
327
313
  }
328
314
 
329
- &:hover, &:focus {
315
+ &:hover,
316
+ &:focus {
330
317
  color: var(--str-chat__text-color);
331
318
 
332
319
  .str-chat__dialog-menu__button-icon {
333
- background-color: var(--str-chat__attachment-selector-actions-menu-button-icon-color-active);
320
+ background-color: var(
321
+ --str-chat__attachment-selector-actions-menu-button-icon-color-active
322
+ );
334
323
  }
335
324
  }
336
325
  }
@@ -16,7 +16,8 @@
16
16
  @use 'common/CTAButton/CTAButton-layout';
17
17
  @use 'common/CircleFAButton/CircleFAButton-layout';
18
18
  @use 'Dialog/Dialog-layout';
19
- @use 'DragAndDropContainer/DragAmdDropContainer-layout';
19
+ @use 'DragAndDropContainer/DragAndDropContainer-layout';
20
+ @use 'DropzoneContainer/DropzoneContainer-layout';
20
21
  @use 'EditMessageForm/EditMessageForm-layout';
21
22
  @use 'Form/Form-layout';
22
23
  @use 'ImageCarousel/ImageCarousel-layout';
@@ -19,6 +19,7 @@
19
19
  @use 'ChannelSearch/ChannelSearch-theme';
20
20
  @use 'Dialog/Dialog-theme';
21
21
  @use 'DragAndDropContainer/DragAndDropContainer-theme';
22
+ @use 'DropzoneContainer/DropzoneContainer-theme';
22
23
  @use 'EditMessageForm/EditMessageForm-theme';
23
24
  @use 'Form/Form-theme';
24
25
  @use 'Icon/Icon-theme';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stream-chat-react",
3
- "version": "12.14.0",
3
+ "version": "12.15.0",
4
4
  "description": "React components to create chat conversations or livestream style chat",
5
5
  "author": "GetStream",
6
6
  "homepage": "https://getstream.io/chat/",
@@ -186,7 +186,7 @@
186
186
  "@playwright/test": "^1.42.1",
187
187
  "@semantic-release/changelog": "^6.0.3",
188
188
  "@semantic-release/git": "^10.0.1",
189
- "@stream-io/stream-chat-css": "^5.8.0",
189
+ "@stream-io/stream-chat-css": "^5.8.1",
190
190
  "@testing-library/dom": "^10.4.0",
191
191
  "@testing-library/jest-dom": "^6.6.3",
192
192
  "@testing-library/react": "^16.2.0",