@azure/communication-react 1.12.1-alpha-202401240013 → 1.12.1-alpha-202401250013

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 (69) hide show
  1. package/dist/communication-react.d.ts +10 -5
  2. package/dist/dist-cjs/communication-react/index.js +330 -254
  3. package/dist/dist-cjs/communication-react/index.js.map +1 -1
  4. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
  5. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
  6. package/dist/dist-esm/communication-react/src/index.d.ts +1 -1
  7. package/dist/dist-esm/communication-react/src/index.js.map +1 -1
  8. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsEditBox.js +2 -1
  9. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsEditBox.js.map +1 -1
  10. package/dist/dist-esm/react-components/src/components/Dialpad/Dialpad.d.ts +9 -5
  11. package/dist/dist-esm/react-components/src/components/Dialpad/Dialpad.js +5 -9
  12. package/dist/dist-esm/react-components/src/components/Dialpad/Dialpad.js.map +1 -1
  13. package/dist/dist-esm/react-components/src/components/FileUploadCards.d.ts +32 -1
  14. package/dist/dist-esm/react-components/src/components/FileUploadCards.js.map +1 -1
  15. package/dist/dist-esm/react-components/src/components/InputBoxButton.d.ts +19 -0
  16. package/dist/dist-esm/react-components/src/components/InputBoxButton.js +32 -0
  17. package/dist/dist-esm/react-components/src/components/InputBoxButton.js.map +1 -0
  18. package/dist/dist-esm/react-components/src/components/InputBoxComponent.d.ts +0 -17
  19. package/dist/dist-esm/react-components/src/components/InputBoxComponent.js +3 -29
  20. package/dist/dist-esm/react-components/src/components/InputBoxComponent.js.map +1 -1
  21. package/dist/dist-esm/react-components/src/components/RTE/RTEInputBoxComponent.d.ts +19 -0
  22. package/dist/dist-esm/react-components/src/components/RTE/RTEInputBoxComponent.js +13 -0
  23. package/dist/dist-esm/react-components/src/components/RTE/RTEInputBoxComponent.js.map +1 -0
  24. package/dist/dist-esm/react-components/src/components/RTE/RTESendBox.d.ts +34 -1
  25. package/dist/dist-esm/react-components/src/components/RTE/RTESendBox.js +45 -3
  26. package/dist/dist-esm/react-components/src/components/RTE/RTESendBox.js.map +1 -1
  27. package/dist/dist-esm/react-components/src/components/RTE/RTESendBoxErrors.d.ts +15 -0
  28. package/dist/dist-esm/react-components/src/components/RTE/RTESendBoxErrors.js +18 -0
  29. package/dist/dist-esm/react-components/src/components/RTE/RTESendBoxErrors.js.map +1 -0
  30. package/dist/dist-esm/react-components/src/components/RTE/RichTextEditor.d.ts +18 -0
  31. package/dist/dist-esm/react-components/src/components/RTE/RichTextEditor.js +40 -0
  32. package/dist/dist-esm/react-components/src/components/RTE/RichTextEditor.js.map +1 -0
  33. package/dist/dist-esm/react-components/src/components/SendBox.d.ts +1 -32
  34. package/dist/dist-esm/react-components/src/components/SendBox.js +33 -30
  35. package/dist/dist-esm/react-components/src/components/SendBox.js.map +1 -1
  36. package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.d.ts +0 -17
  37. package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js +1 -28
  38. package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js.map +1 -1
  39. package/dist/dist-esm/react-components/src/components/index.d.ts +2 -1
  40. package/dist/dist-esm/react-components/src/components/index.js.map +1 -1
  41. package/dist/dist-esm/react-components/src/components/styles/InputBoxButton.style.d.ts +13 -0
  42. package/dist/dist-esm/react-components/src/components/styles/InputBoxButton.style.js +30 -0
  43. package/dist/dist-esm/react-components/src/components/styles/InputBoxButton.style.js.map +1 -0
  44. package/dist/dist-esm/react-components/src/components/styles/InputBoxComponent.style.d.ts +0 -16
  45. package/dist/dist-esm/react-components/src/components/styles/InputBoxComponent.style.js +0 -32
  46. package/dist/dist-esm/react-components/src/components/styles/InputBoxComponent.style.js.map +1 -1
  47. package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.d.ts +5 -0
  48. package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js +16 -0
  49. package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js.map +1 -0
  50. package/dist/dist-esm/react-components/src/components/styles/SendBox.styles.d.ts +8 -2
  51. package/dist/dist-esm/react-components/src/components/styles/SendBox.styles.js +13 -7
  52. package/dist/dist-esm/react-components/src/components/styles/SendBox.styles.js.map +1 -1
  53. package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.d.ts +10 -0
  54. package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js +18 -0
  55. package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js.map +1 -0
  56. package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/CallPage.js +30 -3
  57. package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/CallPage.js.map +1 -1
  58. package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/DtmfDialpadPage.js +11 -4
  59. package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/DtmfDialpadPage.js.map +1 -1
  60. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/baseSelectors.d.ts +5 -0
  61. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/baseSelectors.js +4 -0
  62. package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/baseSelectors.js.map +1 -1
  63. package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/MediaGalleryUtils.d.ts +7 -0
  64. package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/MediaGalleryUtils.js +13 -0
  65. package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/MediaGalleryUtils.js.map +1 -1
  66. package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DesktopMoreButton.js +11 -16
  67. package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DesktopMoreButton.js.map +1 -1
  68. package/dist/tsdoc-metadata.json +1 -1
  69. package/package.json +5 -1
@@ -1 +1 @@
1
- {"version":3,"file":"InputBoxComponent.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/InputBoxComponent.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useState, ReactNode, FormEvent, useCallback } from 'react';\n\nimport {\n Stack,\n TextField,\n mergeStyles,\n IStyle,\n ITextField,\n concatStyleSets,\n IconButton,\n TooltipHost,\n ICalloutContentStyles,\n ITextFieldProps\n} from '@fluentui/react';\nimport { BaseCustomStyles } from '../types';\nimport { isEnterKeyEventFromCompositionSession } from './utils';\n\nimport {\n inputBoxStyle,\n inputBoxWrapperStyle,\n inputButtonStyle,\n textFieldStyle,\n textContainerStyle,\n inputButtonTooltipStyle,\n iconWrapperStyle\n} from './styles/InputBoxComponent.style';\n\nimport { isDarkThemed } from '../theming/themeUtils';\nimport { useTheme } from '../theming';\n/* @conditional-compile-remove(mention) */\nimport { MentionLookupOptions } from './MentionPopover';\n/* @conditional-compile-remove(mention) */\nimport { TextFieldWithMention, TextFieldWithMentionProps } from './TextFieldWithMention/TextFieldWithMention';\n\n/**\n * @private\n */\nexport interface InputBoxStylesProps extends BaseCustomStyles {\n /** Styles for the text field. */\n textField?: IStyle;\n\n /** Styles for the system message; These styles will be ignored when a custom system message component is provided. */\n systemMessage?: IStyle;\n\n /** Styles for customizing the container of the text field */\n textFieldContainer?: IStyle;\n}\n\ntype InputBoxComponentProps = {\n children?: ReactNode;\n 'data-ui-id'?: string;\n id?: string;\n textValue: string; // This could be plain text or HTML.\n onChange: (event?: FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => void;\n textFieldRef?: React.RefObject<ITextField>;\n inputClassName?: string;\n placeholderText?: string;\n supportNewline?: boolean;\n maxLength: number;\n onKeyDown?: (ev: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n onEnterKeyDown?: () => void;\n errorMessage?: string | React.ReactElement;\n disabled?: boolean;\n styles?: InputBoxStylesProps;\n autoFocus?: 'sendBoxTextField';\n /* @conditional-compile-remove(mention) */\n mentionLookupOptions?: MentionLookupOptions;\n};\n\n/**\n * @private\n */\nexport const InputBoxComponent = (props: InputBoxComponentProps): JSX.Element => {\n const {\n styles,\n id,\n 'data-ui-id': dataUiId,\n textValue,\n onChange,\n textFieldRef,\n placeholderText,\n onKeyDown,\n onEnterKeyDown,\n supportNewline,\n inputClassName,\n errorMessage,\n disabled,\n children\n } = props;\n const mergedRootStyle = mergeStyles(inputBoxWrapperStyle, styles?.root);\n const mergedInputFieldStyle = mergeStyles(inputBoxStyle, inputClassName);\n\n const mergedTextContainerStyle = mergeStyles(textContainerStyle, styles?.textFieldContainer);\n const mergedTextFieldStyle = concatStyleSets(textFieldStyle, {\n fieldGroup: styles?.textField,\n errorMessage: styles?.systemMessage,\n suffix: {\n backgroundColor: 'transparent',\n padding: '0 0'\n }\n });\n\n const onTextFieldKeyDown = useCallback(\n (ev: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n if (isEnterKeyEventFromCompositionSession(ev)) {\n return;\n }\n if (ev.key === 'Enter' && (ev.shiftKey === false || !supportNewline)) {\n ev.preventDefault();\n onEnterKeyDown && onEnterKeyDown();\n }\n onKeyDown && onKeyDown(ev);\n },\n [onEnterKeyDown, onKeyDown, supportNewline]\n );\n\n const onRenderChildren = (): JSX.Element => {\n return <>{children}</>;\n };\n\n const renderTextField = (): JSX.Element => {\n const textFieldProps: ITextFieldProps = {\n autoFocus: props.autoFocus === 'sendBoxTextField',\n multiline: true,\n autoAdjustHeight: true,\n multiple: false,\n resizable: false,\n componentRef: textFieldRef,\n id,\n inputClassName: mergedInputFieldStyle,\n placeholder: placeholderText,\n autoComplete: 'off',\n styles: mergedTextFieldStyle,\n disabled,\n errorMessage,\n onRenderSuffix: props.children ? onRenderChildren : undefined\n };\n\n /* @conditional-compile-remove(mention) */\n const textFieldWithMentionProps: TextFieldWithMentionProps = {\n textFieldProps: textFieldProps,\n dataUiId: dataUiId,\n textValue: textValue,\n onChange: onChange,\n onKeyDown: onKeyDown,\n onEnterKeyDown: onEnterKeyDown,\n textFieldRef: textFieldRef,\n supportNewline: supportNewline,\n mentionLookupOptions: props.mentionLookupOptions\n };\n /* @conditional-compile-remove(mention) */\n if (props.mentionLookupOptions) {\n return <TextFieldWithMention {...textFieldWithMentionProps} />;\n }\n return (\n <div style={textFieldProps.errorMessage ? { padding: '0 0 5px 5px' } : undefined}>\n <TextField\n {...textFieldProps}\n data-ui-id={dataUiId}\n value={textValue}\n onChange={onChange}\n onKeyDown={onTextFieldKeyDown}\n onFocus={(e) => {\n // Fix for setting the cursor to the correct position when multiline is true\n // This approach should be reviewed during migration to FluentUI v9\n e.currentTarget.value = '';\n e.currentTarget.value = textValue;\n }}\n />\n </div>\n );\n };\n\n return (\n <Stack className={mergedRootStyle}>\n <div className={mergedTextContainerStyle}>{renderTextField()}</div>\n </Stack>\n );\n};\n\n/**\n * Props for displaying a send button besides the text input area.\n *\n * @private\n */\nexport type InputBoxButtonProps = {\n onRenderIcon: (isHover: boolean) => JSX.Element;\n onClick: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;\n className?: string;\n id?: string;\n ariaLabel?: string;\n tooltipContent?: string;\n};\n\n/**\n * @private\n */\nexport const InputBoxButton = (props: InputBoxButtonProps): JSX.Element => {\n const { onRenderIcon, onClick, ariaLabel, className, id, tooltipContent } = props;\n const [isHover, setIsHover] = useState(false);\n const mergedButtonStyle = mergeStyles(inputButtonStyle, className);\n\n const theme = useTheme();\n const calloutStyle: Partial<ICalloutContentStyles> = { root: { padding: 0 }, calloutMain: { padding: '0.5rem' } };\n\n // Place callout with no gap between it and the button.\n const calloutProps = {\n gapSpace: 0,\n styles: calloutStyle,\n backgroundColor: isDarkThemed(theme) ? theme.palette.neutralLighter : ''\n };\n return (\n <TooltipHost hostClassName={inputButtonTooltipStyle} content={tooltipContent} calloutProps={{ ...calloutProps }}>\n <IconButton\n className={mergedButtonStyle}\n ariaLabel={ariaLabel}\n onClick={onClick}\n id={id}\n onMouseEnter={() => {\n setIsHover(true);\n }}\n onMouseLeave={() => {\n setIsHover(false);\n }}\n // VoiceOver fix: Avoid icon from stealing focus when IconButton is double-tapped to send message by wrapping with Stack with pointerEvents style to none\n onRenderIcon={() => <Stack className={iconWrapperStyle}>{onRenderIcon(isHover)}</Stack>}\n />\n </TooltipHost>\n );\n};\n"]}
1
+ {"version":3,"file":"InputBoxComponent.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/InputBoxComponent.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,KAAK,EAAE,EAAwB,WAAW,EAAE,MAAM,OAAO,CAAC;AAEjE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAsB,eAAe,EAAmB,MAAM,iBAAiB,CAAC;AAEtH,OAAO,EAAE,qCAAqC,EAAE,MAAM,SAAS,CAAC;AAEhE,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EACnB,MAAM,kCAAkC,CAAC;AAI1C,0CAA0C;AAC1C,OAAO,EAAE,oBAAoB,EAA6B,MAAM,6CAA6C,CAAC;AAqC9G;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAA6B,EAAe,EAAE;IAC9E,MAAM,EACJ,MAAM,EACN,EAAE,EACF,YAAY,EAAE,QAAQ,EACtB,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,SAAS,EACT,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,QAAQ,EACT,GAAG,KAAK,CAAC;IACV,MAAM,eAAe,GAAG,WAAW,CAAC,oBAAoB,EAAE,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,CAAC;IACxE,MAAM,qBAAqB,GAAG,WAAW,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;IAEzE,MAAM,wBAAwB,GAAG,WAAW,CAAC,kBAAkB,EAAE,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,kBAAkB,CAAC,CAAC;IAC7F,MAAM,oBAAoB,GAAG,eAAe,CAAC,cAAc,EAAE;QAC3D,UAAU,EAAE,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,SAAS;QAC7B,YAAY,EAAE,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,aAAa;QACnC,MAAM,EAAE;YACN,eAAe,EAAE,aAAa;YAC9B,OAAO,EAAE,KAAK;SACf;KACF,CAAC,CAAC;IAEH,MAAM,kBAAkB,GAAG,WAAW,CACpC,CAAC,EAA+D,EAAE,EAAE;QAClE,IAAI,qCAAqC,CAAC,EAAE,CAAC,EAAE,CAAC;YAC9C,OAAO;QACT,CAAC;QACD,IAAI,EAAE,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,EAAE,CAAC,QAAQ,KAAK,KAAK,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;YACrE,EAAE,CAAC,cAAc,EAAE,CAAC;YACpB,cAAc,IAAI,cAAc,EAAE,CAAC;QACrC,CAAC;QACD,SAAS,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,EACD,CAAC,cAAc,EAAE,SAAS,EAAE,cAAc,CAAC,CAC5C,CAAC;IAEF,MAAM,gBAAgB,GAAG,GAAgB,EAAE;QACzC,OAAO,0CAAG,QAAQ,CAAI,CAAC;IACzB,CAAC,CAAC;IAEF,MAAM,eAAe,GAAG,GAAgB,EAAE;QACxC,MAAM,cAAc,GAAoB;YACtC,SAAS,EAAE,KAAK,CAAC,SAAS,KAAK,kBAAkB;YACjD,SAAS,EAAE,IAAI;YACf,gBAAgB,EAAE,IAAI;YACtB,QAAQ,EAAE,KAAK;YACf,SAAS,EAAE,KAAK;YAChB,YAAY,EAAE,YAAY;YAC1B,EAAE;YACF,cAAc,EAAE,qBAAqB;YACrC,WAAW,EAAE,eAAe;YAC5B,YAAY,EAAE,KAAK;YACnB,MAAM,EAAE,oBAAoB;YAC5B,QAAQ;YACR,YAAY;YACZ,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS;SAC9D,CAAC;QAEF,0CAA0C;QAC1C,MAAM,yBAAyB,GAA8B;YAC3D,cAAc,EAAE,cAAc;YAC9B,QAAQ,EAAE,QAAQ;YAClB,SAAS,EAAE,SAAS;YACpB,QAAQ,EAAE,QAAQ;YAClB,SAAS,EAAE,SAAS;YACpB,cAAc,EAAE,cAAc;YAC9B,YAAY,EAAE,YAAY;YAC1B,cAAc,EAAE,cAAc;YAC9B,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;SACjD,CAAC;QACF,0CAA0C;QAC1C,IAAI,KAAK,CAAC,oBAAoB,EAAE,CAAC;YAC/B,OAAO,oBAAC,oBAAoB,oBAAK,yBAAyB,EAAI,CAAC;QACjE,CAAC;QACD,OAAO,CACL,6BAAK,KAAK,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,SAAS;YAC9E,oBAAC,SAAS,oBACJ,cAAc,kBACN,QAAQ,EACpB,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,kBAAkB,EAC7B,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;oBACb,4EAA4E;oBAC5E,mEAAmE;oBACnE,CAAC,CAAC,aAAa,CAAC,KAAK,GAAG,EAAE,CAAC;oBAC3B,CAAC,CAAC,aAAa,CAAC,KAAK,GAAG,SAAS,CAAC;gBACpC,CAAC,IACD,CACE,CACP,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,CACL,oBAAC,KAAK,IAAC,SAAS,EAAE,eAAe;QAC/B,6BAAK,SAAS,EAAE,wBAAwB,IAAG,eAAe,EAAE,CAAO,CAC7D,CACT,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { ReactNode, FormEvent, useCallback } from 'react';\n\nimport { Stack, TextField, mergeStyles, IStyle, ITextField, concatStyleSets, ITextFieldProps } from '@fluentui/react';\nimport { BaseCustomStyles } from '../types';\nimport { isEnterKeyEventFromCompositionSession } from './utils';\n\nimport {\n inputBoxStyle,\n inputBoxWrapperStyle,\n textFieldStyle,\n textContainerStyle\n} from './styles/InputBoxComponent.style';\n\n/* @conditional-compile-remove(mention) */\nimport { MentionLookupOptions } from './MentionPopover';\n/* @conditional-compile-remove(mention) */\nimport { TextFieldWithMention, TextFieldWithMentionProps } from './TextFieldWithMention/TextFieldWithMention';\n\n/**\n * @private\n */\nexport interface InputBoxStylesProps extends BaseCustomStyles {\n /** Styles for the text field. */\n textField?: IStyle;\n\n /** Styles for the system message; These styles will be ignored when a custom system message component is provided. */\n systemMessage?: IStyle;\n\n /** Styles for customizing the container of the text field */\n textFieldContainer?: IStyle;\n}\n\ntype InputBoxComponentProps = {\n children?: ReactNode;\n 'data-ui-id'?: string;\n id?: string;\n textValue: string; // This could be plain text or HTML.\n onChange: (event?: FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => void;\n textFieldRef?: React.RefObject<ITextField>;\n inputClassName?: string;\n placeholderText?: string;\n supportNewline?: boolean;\n maxLength: number;\n onKeyDown?: (ev: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n onEnterKeyDown?: () => void;\n errorMessage?: string | React.ReactElement;\n disabled?: boolean;\n styles?: InputBoxStylesProps;\n autoFocus?: 'sendBoxTextField';\n /* @conditional-compile-remove(mention) */\n mentionLookupOptions?: MentionLookupOptions;\n};\n\n/**\n * @private\n */\nexport const InputBoxComponent = (props: InputBoxComponentProps): JSX.Element => {\n const {\n styles,\n id,\n 'data-ui-id': dataUiId,\n textValue,\n onChange,\n textFieldRef,\n placeholderText,\n onKeyDown,\n onEnterKeyDown,\n supportNewline,\n inputClassName,\n errorMessage,\n disabled,\n children\n } = props;\n const mergedRootStyle = mergeStyles(inputBoxWrapperStyle, styles?.root);\n const mergedInputFieldStyle = mergeStyles(inputBoxStyle, inputClassName);\n\n const mergedTextContainerStyle = mergeStyles(textContainerStyle, styles?.textFieldContainer);\n const mergedTextFieldStyle = concatStyleSets(textFieldStyle, {\n fieldGroup: styles?.textField,\n errorMessage: styles?.systemMessage,\n suffix: {\n backgroundColor: 'transparent',\n padding: '0 0'\n }\n });\n\n const onTextFieldKeyDown = useCallback(\n (ev: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n if (isEnterKeyEventFromCompositionSession(ev)) {\n return;\n }\n if (ev.key === 'Enter' && (ev.shiftKey === false || !supportNewline)) {\n ev.preventDefault();\n onEnterKeyDown && onEnterKeyDown();\n }\n onKeyDown && onKeyDown(ev);\n },\n [onEnterKeyDown, onKeyDown, supportNewline]\n );\n\n const onRenderChildren = (): JSX.Element => {\n return <>{children}</>;\n };\n\n const renderTextField = (): JSX.Element => {\n const textFieldProps: ITextFieldProps = {\n autoFocus: props.autoFocus === 'sendBoxTextField',\n multiline: true,\n autoAdjustHeight: true,\n multiple: false,\n resizable: false,\n componentRef: textFieldRef,\n id,\n inputClassName: mergedInputFieldStyle,\n placeholder: placeholderText,\n autoComplete: 'off',\n styles: mergedTextFieldStyle,\n disabled,\n errorMessage,\n onRenderSuffix: props.children ? onRenderChildren : undefined\n };\n\n /* @conditional-compile-remove(mention) */\n const textFieldWithMentionProps: TextFieldWithMentionProps = {\n textFieldProps: textFieldProps,\n dataUiId: dataUiId,\n textValue: textValue,\n onChange: onChange,\n onKeyDown: onKeyDown,\n onEnterKeyDown: onEnterKeyDown,\n textFieldRef: textFieldRef,\n supportNewline: supportNewline,\n mentionLookupOptions: props.mentionLookupOptions\n };\n /* @conditional-compile-remove(mention) */\n if (props.mentionLookupOptions) {\n return <TextFieldWithMention {...textFieldWithMentionProps} />;\n }\n return (\n <div style={textFieldProps.errorMessage ? { padding: '0 0 5px 5px' } : undefined}>\n <TextField\n {...textFieldProps}\n data-ui-id={dataUiId}\n value={textValue}\n onChange={onChange}\n onKeyDown={onTextFieldKeyDown}\n onFocus={(e) => {\n // Fix for setting the cursor to the correct position when multiline is true\n // This approach should be reviewed during migration to FluentUI v9\n e.currentTarget.value = '';\n e.currentTarget.value = textValue;\n }}\n />\n </div>\n );\n };\n\n return (\n <Stack className={mergedRootStyle}>\n <div className={mergedTextContainerStyle}>{renderTextField()}</div>\n </Stack>\n );\n};\n"]}
@@ -0,0 +1,19 @@
1
+ /// <reference types="react" />
2
+ import { BaseCustomStyles } from '../../types';
3
+ /**
4
+ * @private
5
+ */
6
+ export interface RTEInputBoxComponentStylesProps extends BaseCustomStyles {
7
+ }
8
+ /**
9
+ * @private
10
+ */
11
+ export interface RTEInputBoxComponentProps {
12
+ placeholderText?: string;
13
+ content: string;
14
+ }
15
+ /**
16
+ * @private
17
+ */
18
+ export declare const RTEInputBoxComponent: (props: RTEInputBoxComponentProps) => JSX.Element;
19
+ //# sourceMappingURL=RTEInputBoxComponent.d.ts.map
@@ -0,0 +1,13 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import React from 'react';
4
+ import { RichTextEditor } from './RichTextEditor';
5
+ /**
6
+ * @private
7
+ */
8
+ export const RTEInputBoxComponent = (props) => {
9
+ const { placeholderText, content } = props;
10
+ return (React.createElement("div", null,
11
+ React.createElement(RichTextEditor, { content: content, placeholderText: placeholderText, onChange: () => { } })));
12
+ };
13
+ //# sourceMappingURL=RTEInputBoxComponent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RTEInputBoxComponent.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RTE/RTEInputBoxComponent.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAelD;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAgC,EAAe,EAAE;IACpF,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAE3C,OAAO,CACL;QACE,oBAAC,cAAc,IAAC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,GAAI,CACtF,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React from 'react';\nimport { BaseCustomStyles } from '../../types';\nimport { RichTextEditor } from './RichTextEditor';\n\n/**\n * @private\n */\nexport interface RTEInputBoxComponentStylesProps extends BaseCustomStyles {}\n\n/**\n * @private\n */\nexport interface RTEInputBoxComponentProps {\n placeholderText?: string;\n content: string;\n}\n\n/**\n * @private\n */\nexport const RTEInputBoxComponent = (props: RTEInputBoxComponentProps): JSX.Element => {\n const { placeholderText, content } = props;\n\n return (\n <div>\n <RichTextEditor content={content} placeholderText={placeholderText} onChange={() => {}} />\n </div>\n );\n};\n"]}
@@ -1,11 +1,44 @@
1
1
  /// <reference types="react" />
2
+ import { SendBoxStrings } from '../SendBox';
3
+ import { ActiveFileUpload } from '../FileUploadCards';
2
4
  /**
3
5
  * Props for {@link RTESendBox}.
4
6
  *
5
7
  * @beta
6
8
  */
7
9
  export interface RTESendBoxProps {
8
- valueToDisplay?: string;
10
+ /**
11
+ * Optional boolean to disable text box
12
+ * @defaultValue false
13
+ */
14
+ disabled?: boolean;
15
+ /**
16
+ * Optional strings to override in component
17
+ */
18
+ strings?: Partial<SendBoxStrings>;
19
+ /**
20
+ * Optional text for system message below text box
21
+ */
22
+ systemMessage?: string;
23
+ /**
24
+ * Optional callback to render uploaded files in the SendBox. The sendBox will expand
25
+ * vertically to accommodate the uploaded files. File uploads will
26
+ * be rendered below the text area in sendBox.
27
+ * @beta
28
+ */
29
+ onRenderFileUploads?: () => JSX.Element;
30
+ /**
31
+ * Optional array of active file uploads where each object has attributes
32
+ * of a file upload like name, progress, errorMessage etc.
33
+ * @beta
34
+ */
35
+ activeFileUploads?: ActiveFileUpload[];
36
+ /**
37
+ * Optional callback to remove the file upload before sending by clicking on
38
+ * cancel icon.
39
+ * @beta
40
+ */
41
+ onCancelFileUpload?: (fileId: string) => void;
9
42
  }
10
43
  /**
11
44
  * A component to render SendBox with Rich Text Editor support.
@@ -1,13 +1,55 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
- import React from 'react';
3
+ import React, { useCallback, useMemo, useState } from 'react';
4
+ import { RTEInputBoxComponent } from './RTEInputBoxComponent';
5
+ import { Icon, Stack, useTheme } from '@fluentui/react';
6
+ import { useLocale } from '../../localization';
7
+ import { borderAndBoxShadowStyle, sendButtonStyle, sendIconStyle } from '../styles/SendBox.styles';
8
+ import { InputBoxButton } from '../InputBoxButton';
9
+ import { RTESendBoxErrors } from './RTESendBoxErrors';
4
10
  /**
5
11
  * A component to render SendBox with Rich Text Editor support.
6
12
  *
7
13
  * @beta
8
14
  */
9
15
  export const RTESendBox = (props) => {
10
- const { valueToDisplay = 'Hello World!' } = props;
11
- return React.createElement("div", null, valueToDisplay);
16
+ const { disabled, systemMessage } = props;
17
+ const theme = useTheme();
18
+ const localeStrings = useLocale().strings.sendBox;
19
+ const strings = Object.assign(Object.assign({}, localeStrings), props.strings);
20
+ const [contentValue] = useState('');
21
+ const [contentValueOverflow] = useState(false);
22
+ const contentTooLongMessage = contentValueOverflow ? strings.textTooLong : undefined;
23
+ const errorMessage = systemMessage !== null && systemMessage !== void 0 ? systemMessage : contentTooLongMessage;
24
+ const sendMessageOnClick = () => {
25
+ if (disabled || contentValueOverflow) {
26
+ return;
27
+ }
28
+ };
29
+ const onRenderSendIcon = useCallback((isHover) => (React.createElement(Icon, { iconName: isHover && contentValue ? 'SendBoxSendHovered' : 'SendBoxSend', className: sendIconStyle({
30
+ theme,
31
+ hasText: !!contentValue,
32
+ /* @conditional-compile-remove(file-sharing) */ hasFile: false,
33
+ hasErrorMessage: !!errorMessage
34
+ }) })), [contentValue, errorMessage, theme]);
35
+ const sendBoxErrorsProps = useMemo(() => {
36
+ return {
37
+ fileUploadsPendingError: undefined,
38
+ fileUploadError: undefined,
39
+ systemError: systemMessage ? { message: systemMessage, timestamp: Date.now() } : undefined,
40
+ messageTooLongError: contentValueOverflow ? { message: strings.textTooLong, timestamp: Date.now() } : undefined
41
+ };
42
+ }, [contentValueOverflow, strings.textTooLong, systemMessage]);
43
+ return (React.createElement(Stack, { className: borderAndBoxShadowStyle({
44
+ theme: theme,
45
+ hasErrorMessage: !!errorMessage,
46
+ disabled: !!disabled
47
+ }) },
48
+ React.createElement(RTESendBoxErrors, Object.assign({}, sendBoxErrorsProps)),
49
+ React.createElement(RTEInputBoxComponent, { placeholderText: strings.placeholderText, content: contentValue }),
50
+ React.createElement(InputBoxButton, { onRenderIcon: onRenderSendIcon, onClick: (e) => {
51
+ sendMessageOnClick();
52
+ e.stopPropagation(); // Prevents the click from bubbling up and triggering a focus event on the chat.
53
+ }, className: sendButtonStyle, ariaLabel: localeStrings.sendButtonAriaLabel, tooltipContent: localeStrings.sendButtonAriaLabel })));
12
54
  };
13
55
  //# sourceMappingURL=RTESendBox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RTESendBox.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RTE/RTESendBox.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,KAAK,MAAM,OAAO,CAAC;AAY1B;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAsB,EAAe,EAAE;IAChE,MAAM,EAAE,cAAc,GAAG,cAAc,EAAE,GAAG,KAAK,CAAC;IAClD,OAAO,iCAAM,cAAc,CAAO,CAAC;AACrC,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React from 'react';\n\n/**\n * Props for {@link RTESendBox}.\n *\n * @beta\n */\nexport interface RTESendBoxProps {\n // just a value to be displayed for now but it should be deleted when the component development starts\n valueToDisplay?: string;\n}\n\n/**\n * A component to render SendBox with Rich Text Editor support.\n *\n * @beta\n */\nexport const RTESendBox = (props: RTESendBoxProps): JSX.Element => {\n const { valueToDisplay = 'Hello World!' } = props;\n return <div>{valueToDisplay}</div>;\n};\n"]}
1
+ {"version":3,"file":"RTESendBox.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RTE/RTESendBox.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useCallback, useMemo, useState } from 'react';\nimport { RTEInputBoxComponent } from './RTEInputBoxComponent';\nimport { Icon, Stack, useTheme } from '@fluentui/react';\nimport { useLocale } from '../../localization';\nimport { SendBoxStrings } from '../SendBox';\nimport { borderAndBoxShadowStyle, sendButtonStyle, sendIconStyle } from '../styles/SendBox.styles';\nimport { InputBoxButton } from '../InputBoxButton';\nimport { RTESendBoxErrors, RTESendBoxErrorsProps } from './RTESendBoxErrors';\n/* @conditional-compile-remove(file-sharing) */\nimport { ActiveFileUpload } from '../FileUploadCards';\n\n/**\n * Props for {@link RTESendBox}.\n *\n * @beta\n */\nexport interface RTESendBoxProps {\n /**\n * Optional boolean to disable text box\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * Optional strings to override in component\n */\n strings?: Partial<SendBoxStrings>;\n /**\n * Optional text for system message below text box\n */\n systemMessage?: string;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Optional callback to render uploaded files in the SendBox. The sendBox will expand\n * vertically to accommodate the uploaded files. File uploads will\n * be rendered below the text area in sendBox.\n * @beta\n */\n onRenderFileUploads?: () => JSX.Element;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Optional array of active file uploads where each object has attributes\n * of a file upload like name, progress, errorMessage etc.\n * @beta\n */\n activeFileUploads?: ActiveFileUpload[];\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Optional callback to remove the file upload before sending by clicking on\n * cancel icon.\n * @beta\n */\n onCancelFileUpload?: (fileId: string) => void;\n}\n\n/**\n * A component to render SendBox with Rich Text Editor support.\n *\n * @beta\n */\nexport const RTESendBox = (props: RTESendBoxProps): JSX.Element => {\n const { disabled, systemMessage } = props;\n\n const theme = useTheme();\n const localeStrings = useLocale().strings.sendBox;\n const strings = { ...localeStrings, ...props.strings };\n\n const [contentValue] = useState('');\n const [contentValueOverflow] = useState(false);\n\n const contentTooLongMessage = contentValueOverflow ? strings.textTooLong : undefined;\n const errorMessage = systemMessage ?? contentTooLongMessage;\n\n const sendMessageOnClick = (): void => {\n if (disabled || contentValueOverflow) {\n return;\n }\n };\n\n const onRenderSendIcon = useCallback(\n (isHover: boolean) => (\n <Icon\n iconName={isHover && contentValue ? 'SendBoxSendHovered' : 'SendBoxSend'}\n className={sendIconStyle({\n theme,\n hasText: !!contentValue,\n /* @conditional-compile-remove(file-sharing) */ hasFile: false,\n hasErrorMessage: !!errorMessage\n })}\n />\n ),\n [contentValue, errorMessage, theme]\n );\n\n const sendBoxErrorsProps = useMemo<RTESendBoxErrorsProps>(() => {\n return {\n fileUploadsPendingError: undefined,\n fileUploadError: undefined,\n systemError: systemMessage ? { message: systemMessage, timestamp: Date.now() } : undefined,\n messageTooLongError: contentValueOverflow ? { message: strings.textTooLong, timestamp: Date.now() } : undefined\n };\n }, [contentValueOverflow, strings.textTooLong, systemMessage]);\n\n return (\n <Stack\n className={borderAndBoxShadowStyle({\n theme: theme,\n hasErrorMessage: !!errorMessage,\n disabled: !!disabled\n })}\n >\n <RTESendBoxErrors {...sendBoxErrorsProps} />\n <RTEInputBoxComponent placeholderText={strings.placeholderText} content={contentValue} />\n <InputBoxButton\n onRenderIcon={onRenderSendIcon}\n onClick={(e) => {\n sendMessageOnClick();\n e.stopPropagation(); // Prevents the click from bubbling up and triggering a focus event on the chat.\n }}\n className={sendButtonStyle}\n ariaLabel={localeStrings.sendButtonAriaLabel}\n tooltipContent={localeStrings.sendButtonAriaLabel}\n />\n {/* File Upload */}\n </Stack>\n );\n};\n"]}
@@ -0,0 +1,15 @@
1
+ /// <reference types="react" />
2
+ import { SendBoxErrorBarError } from '../SendBoxErrorBar';
3
+ /**
4
+ * @private
5
+ */
6
+ export interface RTESendBoxErrorsProps {
7
+ fileUploadsPendingError?: SendBoxErrorBarError;
8
+ fileUploadError?: SendBoxErrorBarError;
9
+ systemError?: SendBoxErrorBarError;
10
+ }
11
+ /**
12
+ * @private
13
+ */
14
+ export declare const RTESendBoxErrors: (props: RTESendBoxErrorsProps) => JSX.Element;
15
+ //# sourceMappingURL=RTESendBoxErrors.d.ts.map
@@ -0,0 +1,18 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import React from 'react';
4
+ import { SendBoxErrorBar } from '../SendBoxErrorBar';
5
+ /**
6
+ * @private
7
+ */
8
+ export const RTESendBoxErrors = (props) => {
9
+ const { fileUploadError, fileUploadsPendingError } = props;
10
+ const errorToDisplay = React.useMemo(() => {
11
+ if (fileUploadError && fileUploadsPendingError) {
12
+ return fileUploadError.timestamp > fileUploadsPendingError.timestamp ? fileUploadError : fileUploadsPendingError;
13
+ }
14
+ return fileUploadError || fileUploadsPendingError;
15
+ }, [fileUploadError, fileUploadsPendingError]);
16
+ return React.createElement(SendBoxErrorBar, { error: errorToDisplay, dismissAfterMs: 10 * 1000 });
17
+ };
18
+ //# sourceMappingURL=RTESendBoxErrors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RTESendBoxErrors.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RTE/RTESendBoxErrors.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAwB,MAAM,oBAAoB,CAAC;AAW3E;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAA4B,EAAe,EAAE;IAC5E,MAAM,EAAE,eAAe,EAAE,uBAAuB,EAAE,GAAG,KAAK,CAAC;IAE3D,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACxC,IAAI,eAAe,IAAI,uBAAuB,EAAE,CAAC;YAC/C,OAAO,eAAe,CAAC,SAAS,GAAG,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,uBAAuB,CAAC;QACnH,CAAC;QACD,OAAO,eAAe,IAAI,uBAAuB,CAAC;IACpD,CAAC,EAAE,CAAC,eAAe,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAE/C,OAAO,oBAAC,eAAe,IAAC,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,EAAE,GAAG,IAAI,GAAI,CAAC;AAC/E,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React from 'react';\nimport { SendBoxErrorBar, SendBoxErrorBarError } from '../SendBoxErrorBar';\n\n/**\n * @private\n */\nexport interface RTESendBoxErrorsProps {\n fileUploadsPendingError?: SendBoxErrorBarError;\n fileUploadError?: SendBoxErrorBarError;\n systemError?: SendBoxErrorBarError;\n}\n\n/**\n * @private\n */\nexport const RTESendBoxErrors = (props: RTESendBoxErrorsProps): JSX.Element => {\n const { fileUploadError, fileUploadsPendingError } = props;\n\n const errorToDisplay = React.useMemo(() => {\n if (fileUploadError && fileUploadsPendingError) {\n return fileUploadError.timestamp > fileUploadsPendingError.timestamp ? fileUploadError : fileUploadsPendingError;\n }\n return fileUploadError || fileUploadsPendingError;\n }, [fileUploadError, fileUploadsPendingError]);\n\n return <SendBoxErrorBar error={errorToDisplay} dismissAfterMs={10 * 1000} />;\n};\n"]}
@@ -0,0 +1,18 @@
1
+ /// <reference types="react" />
2
+ /**
3
+ * Props for {@link RichTextEditor}.
4
+ *
5
+ * @beta
6
+ */
7
+ export interface RichTextEditorProps {
8
+ content?: string;
9
+ onChange: (newValue?: string) => void;
10
+ placeholderText?: string;
11
+ }
12
+ /**
13
+ * A component to wrap RoosterJS Rich Text Editor.
14
+ *
15
+ * @beta
16
+ */
17
+ export declare const RichTextEditor: (props: RichTextEditorProps) => JSX.Element;
18
+ //# sourceMappingURL=RichTextEditor.d.ts.map
@@ -0,0 +1,40 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import React, { useEffect, useMemo, useRef } from 'react';
4
+ import { ContentEdit, Watermark } from 'roosterjs-editor-plugins';
5
+ import { Editor } from 'roosterjs-editor-core';
6
+ import { Rooster, createUpdateContentPlugin, UpdateMode } from 'roosterjs-react';
7
+ import { richTextEditorStyle } from '../styles/RichTextEditor.styles';
8
+ /**
9
+ * A component to wrap RoosterJS Rich Text Editor.
10
+ *
11
+ * @beta
12
+ */
13
+ export const RichTextEditor = (props) => {
14
+ const { content, onChange, placeholderText } = props;
15
+ const editor = useRef(null);
16
+ useEffect(() => {
17
+ var _a, _b;
18
+ if (content !== ((_a = editor.current) === null || _a === void 0 ? void 0 : _a.getContent())) {
19
+ (_b = editor.current) === null || _b === void 0 ? void 0 : _b.setContent(content || '');
20
+ }
21
+ }, [content]);
22
+ const editorCreator = useMemo(() => {
23
+ return (div) => {
24
+ const contentEdit = new ContentEdit();
25
+ const placeholderPlugin = new Watermark(placeholderText || '');
26
+ const updateContentPlugin = createUpdateContentPlugin(UpdateMode.OnContentChangedEvent | UpdateMode.OnUserInput, (content) => {
27
+ onChange && onChange(content);
28
+ });
29
+ const options = {
30
+ plugins: [placeholderPlugin, contentEdit, updateContentPlugin],
31
+ imageSelectionBorderColor: 'blue'
32
+ };
33
+ editor.current = new Editor(div, options);
34
+ return editor.current;
35
+ };
36
+ }, [onChange, placeholderText]);
37
+ return (React.createElement("div", null,
38
+ React.createElement(Rooster, { className: richTextEditorStyle, editorCreator: editorCreator })));
39
+ };
40
+ //# sourceMappingURL=RichTextEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RichTextEditor.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RTE/RichTextEditor.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAYtE;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAA0B,EAAe,EAAE;IACxE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAE5C,SAAS,CAAC,GAAG,EAAE;;QACb,IAAI,OAAO,MAAK,MAAA,MAAM,CAAC,OAAO,0CAAE,UAAU,EAAE,CAAA,EAAE,CAAC;YAC7C,MAAA,MAAM,CAAC,OAAO,0CAAE,UAAU,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE;QACjC,OAAO,CAAC,GAAmB,EAAE,EAAE;YAC7B,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;YACtC,MAAM,iBAAiB,GAAG,IAAI,SAAS,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;YAC/D,MAAM,mBAAmB,GAAG,yBAAyB,CACnD,UAAU,CAAC,qBAAqB,GAAG,UAAU,CAAC,WAAW,EACzD,CAAC,OAAe,EAAE,EAAE;gBAClB,QAAQ,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;YAChC,CAAC,CACF,CAAC;YAEF,MAAM,OAAO,GAAkB;gBAC7B,OAAO,EAAE,CAAC,iBAAiB,EAAE,WAAW,EAAE,mBAAmB,CAAC;gBAC9D,yBAAyB,EAAE,MAAM;aAClC,CAAC;YAEF,MAAM,CAAC,OAAO,GAAG,IAAI,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC1C,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;IAEhC,OAAO,CACL;QACE,oBAAC,OAAO,IAAC,SAAS,EAAE,mBAAmB,EAAE,aAAa,EAAE,aAAa,GAAI,CACrE,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport React, { useEffect, useMemo, useRef } from 'react';\nimport { ContentEdit, Watermark } from 'roosterjs-editor-plugins';\nimport { Editor } from 'roosterjs-editor-core';\nimport { EditorOptions, IEditor } from 'roosterjs-editor-types';\nimport { Rooster, createUpdateContentPlugin, UpdateMode } from 'roosterjs-react';\nimport { richTextEditorStyle } from '../styles/RichTextEditor.styles';\n/**\n * Props for {@link RichTextEditor}.\n *\n * @beta\n */\nexport interface RichTextEditorProps {\n content?: string;\n onChange: (newValue?: string) => void;\n placeholderText?: string;\n}\n\n/**\n * A component to wrap RoosterJS Rich Text Editor.\n *\n * @beta\n */\nexport const RichTextEditor = (props: RichTextEditorProps): JSX.Element => {\n const { content, onChange, placeholderText } = props;\n const editor = useRef<IEditor | null>(null);\n\n useEffect(() => {\n if (content !== editor.current?.getContent()) {\n editor.current?.setContent(content || '');\n }\n }, [content]);\n\n const editorCreator = useMemo(() => {\n return (div: HTMLDivElement) => {\n const contentEdit = new ContentEdit();\n const placeholderPlugin = new Watermark(placeholderText || '');\n const updateContentPlugin = createUpdateContentPlugin(\n UpdateMode.OnContentChangedEvent | UpdateMode.OnUserInput,\n (content: string) => {\n onChange && onChange(content);\n }\n );\n\n const options: EditorOptions = {\n plugins: [placeholderPlugin, contentEdit, updateContentPlugin],\n imageSelectionBorderColor: 'blue'\n };\n\n editor.current = new Editor(div, options);\n return editor.current;\n };\n }, [onChange, placeholderText]);\n\n return (\n <div>\n <Rooster className={richTextEditorStyle} editorCreator={editorCreator} />\n </div>\n );\n};\n"]}
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { IStyle } from '@fluentui/react';
3
3
  import { BaseCustomStyles } from '../types';
4
- import { SendBoxErrorBarError } from './SendBoxErrorBar';
4
+ import { ActiveFileUpload } from './FileUploadCards';
5
5
  import { MentionLookupOptions } from './MentionPopover';
6
6
  /**
7
7
  * Fluent styles for {@link Sendbox}.
@@ -20,37 +20,6 @@ export interface SendBoxStylesProps extends BaseCustomStyles {
20
20
  /** Styles for the system message; These styles will be ignored when a custom system message component is provided. */
21
21
  systemMessage?: IStyle;
22
22
  }
23
- /**
24
- * Attributes required for SendBox to show file uploads like name, progress etc.
25
- * @beta
26
- */
27
- export interface ActiveFileUpload {
28
- /**
29
- * Unique identifier for the file upload.
30
- */
31
- id: string;
32
- /**
33
- * File name to be rendered for uploaded file.
34
- */
35
- filename: string;
36
- /**
37
- * A number between 0 and 1 indicating the progress of the upload.
38
- * This is unrelated to the `uploadComplete` property.
39
- * It is only used to show the progress of the upload.
40
- * Progress of 1 doesn't mark the upload as complete, set the `uploadComplete`
41
- * property to true to mark the upload as complete.
42
- */
43
- progress: number;
44
- /**
45
- * Error to be displayed to the user if the upload fails.
46
- */
47
- error?: SendBoxErrorBarError;
48
- /**
49
- * `true` means that the upload is completed.
50
- * This is independent of the upload `progress`.
51
- */
52
- uploadComplete?: boolean;
53
- }
54
23
  /**
55
24
  * Strings of {@link SendBox} that can be overridden.
56
25
  *
@@ -6,14 +6,18 @@ import { sendButtonStyle, sendIconStyle, sendBoxWrapperStyles, borderAndBoxShado
6
6
  import { useTheme } from '../theming';
7
7
  import { useLocale } from '../localization';
8
8
  import { useIdentifiers } from '../identifiers';
9
- import { InputBoxButton, InputBoxComponent } from './InputBoxComponent';
9
+ import { InputBoxComponent } from './InputBoxComponent';
10
+ import { InputBoxButton } from './InputBoxButton';
11
+ /* @conditional-compile-remove(file-sharing) */
10
12
  import { SendBoxErrors } from './SendBoxErrors';
11
13
  /* @conditional-compile-remove(file-sharing) */
12
14
  import { _FileUploadCards } from './FileUploadCards';
13
15
  /* @conditional-compile-remove(file-sharing) */
14
16
  import { fileUploadCardsStyles } from './styles/SendBox.styles';
15
- const EMPTY_MESSAGE_REGEX = /^\s*$/;
17
+ /* @conditional-compile-remove(file-sharing) */
18
+ import { hasCompletedFileUploads, hasIncompleteFileUploads } from './utils/SendBoxUtils';
16
19
  const MAXIMUM_LENGTH_OF_MESSAGE = 8000;
20
+ const EMPTY_MESSAGE_REGEX = /^\s*$/;
17
21
  /**
18
22
  * Component for typing and sending messages.
19
23
  *
@@ -25,15 +29,17 @@ const MAXIMUM_LENGTH_OF_MESSAGE = 8000;
25
29
  export const SendBox = (props) => {
26
30
  const { disabled, systemMessage, supportNewline, onSendMessage, onTyping, onRenderIcon, onRenderSystemMessage, styles, autoFocus,
27
31
  /* @conditional-compile-remove(mention) */
28
- mentionLookupOptions } = props;
32
+ mentionLookupOptions,
33
+ /* @conditional-compile-remove(file-sharing) */
34
+ activeFileUploads } = props;
29
35
  const theme = useTheme();
30
36
  const localeStrings = useLocale().strings.sendBox;
31
37
  const strings = Object.assign(Object.assign({}, localeStrings), props.strings);
32
38
  const ids = useIdentifiers();
33
- const activeFileUploads = activeFileUploadsTrampoline(props);
34
39
  const [textValue, setTextValue] = useState('');
35
40
  const [textValueOverflow, setTextValueOverflow] = useState(false);
36
41
  const sendTextFieldRef = React.useRef(null);
42
+ /* @conditional-compile-remove(file-sharing) */
37
43
  const [fileUploadsPendingError, setFileUploadsPendingError] = useState(undefined);
38
44
  const sendMessageOnClick = () => {
39
45
  var _a;
@@ -42,16 +48,18 @@ export const SendBox = (props) => {
42
48
  return;
43
49
  }
44
50
  // Don't send message until all files have been uploaded successfully
51
+ /* @conditional-compile-remove(file-sharing) */
45
52
  setFileUploadsPendingError(undefined);
46
- if (hasIncompleteFileUploads(props)) {
47
- /* @conditional-compile-remove(file-sharing) */
53
+ /* @conditional-compile-remove(file-sharing) */
54
+ if (hasIncompleteFileUploads(activeFileUploads)) {
48
55
  setFileUploadsPendingError({ message: strings.fileUploadsPendingError, timestamp: Date.now() });
49
56
  return;
50
57
  }
51
58
  const message = textValue;
52
59
  // we don't want to send empty messages including spaces, newlines, tabs
53
60
  // Message can be empty if there is a valid file upload
54
- if (!EMPTY_MESSAGE_REGEX.test(message) || hasFile(props)) {
61
+ if (!EMPTY_MESSAGE_REGEX.test(message) ||
62
+ /* @conditional-compile-remove(file-sharing) */ hasCompletedFileUploads(activeFileUploads)) {
55
63
  onSendMessage && onSendMessage(sanitizeText(message));
56
64
  setTextValue('');
57
65
  }
@@ -73,18 +81,28 @@ export const SendBox = (props) => {
73
81
  const errorMessage = systemMessage !== null && systemMessage !== void 0 ? systemMessage : textTooLongMessage;
74
82
  const mergedSendButtonStyle = useMemo(() => mergeStyles(sendButtonStyle, styles === null || styles === void 0 ? void 0 : styles.sendMessageIconContainer), [styles === null || styles === void 0 ? void 0 : styles.sendMessageIconContainer]);
75
83
  const mergedStyles = useMemo(() => concatStyleSets(styles), [styles]);
76
- const hasText = !!textValue;
77
- const hasTextOrFile = hasText || hasFile(props);
78
- const mergedSendIconStyle = useMemo(() => mergeStyles(sendIconStyle, {
79
- color: !!errorMessage || !hasTextOrFile ? theme.palette.neutralTertiary : theme.palette.themePrimary
80
- }, styles === null || styles === void 0 ? void 0 : styles.sendMessageIcon), [errorMessage, hasTextOrFile, theme, styles === null || styles === void 0 ? void 0 : styles.sendMessageIcon]);
84
+ const mergedSendIconStyle = useMemo(() => sendIconStyle({
85
+ theme,
86
+ hasText: !!textValue,
87
+ /* @conditional-compile-remove(file-sharing) */ hasFile: hasCompletedFileUploads(activeFileUploads),
88
+ hasErrorMessage: !!errorMessage,
89
+ customSendIconStyle: styles === null || styles === void 0 ? void 0 : styles.sendMessageIcon
90
+ }), [
91
+ theme,
92
+ textValue,
93
+ /* @conditional-compile-remove(file-sharing) */ activeFileUploads,
94
+ errorMessage,
95
+ styles === null || styles === void 0 ? void 0 : styles.sendMessageIcon
96
+ ]);
81
97
  const onRenderSendIcon = useCallback((isHover) => onRenderIcon ? (onRenderIcon(isHover)) : (React.createElement(Icon, { iconName: isHover && textValue ? 'SendBoxSendHovered' : 'SendBoxSend', className: mergedSendIconStyle })), [mergedSendIconStyle, onRenderIcon, textValue]);
82
98
  // Ensure that errors are cleared when there are no files in sendBox
99
+ /* @conditional-compile-remove(file-sharing) */
83
100
  React.useEffect(() => {
84
101
  if (!(activeFileUploads === null || activeFileUploads === void 0 ? void 0 : activeFileUploads.filter((upload) => !upload.error).length)) {
85
102
  setFileUploadsPendingError(undefined);
86
103
  }
87
104
  }, [activeFileUploads]);
105
+ /* @conditional-compile-remove(file-sharing) */
88
106
  const sendBoxErrorsProps = useMemo(() => {
89
107
  var _a;
90
108
  return {
@@ -106,13 +124,13 @@ export const SendBox = (props) => {
106
124
  } })));
107
125
  }, [activeFileUploads, props, localeStrings]);
108
126
  return (React.createElement(Stack, { className: mergeStyles(sendBoxWrapperStyles, { overflow: 'visible' } // This is needed for the mention popup to be visible
109
- ) },
127
+ ) }, /* @conditional-compile-remove(file-sharing) */
110
128
  React.createElement(SendBoxErrors, Object.assign({}, sendBoxErrorsProps)),
111
- React.createElement(Stack, { className: mergeStyles(borderAndBoxShadowStyle({
129
+ React.createElement(Stack, { className: borderAndBoxShadowStyle({
112
130
  theme,
113
131
  hasErrorMessage: !!errorMessage,
114
132
  disabled: !!disabled
115
- })) },
133
+ }) },
116
134
  React.createElement(InputBoxComponent, { autoFocus: autoFocus, "data-ui-id": ids.sendboxTextField, disabled: disabled, errorMessage: onRenderSystemMessage ? onRenderSystemMessage(errorMessage) : errorMessage, textFieldRef: sendTextFieldRef, id: "sendbox", placeholderText: strings.placeholderText, textValue: textValue, onChange: (_, newValue) => setText(newValue), onKeyDown: (ev) => {
117
135
  const keyWasSendingMessage = ev.key === 'Enter' && (ev.shiftKey === false || !supportNewline);
118
136
  if (!keyWasSendingMessage) {
@@ -135,16 +153,6 @@ export const SendBox = (props) => {
135
153
  /**
136
154
  * @private
137
155
  */
138
- const hasIncompleteFileUploads = (props) => {
139
- const activeFileUploads = activeFileUploadsTrampoline(props);
140
- return !!((activeFileUploads === null || activeFileUploads === void 0 ? void 0 : activeFileUploads.length) &&
141
- !activeFileUploads.filter((fileUpload) => !fileUpload.error).every((fileUpload) => fileUpload.uploadComplete));
142
- };
143
- const hasFile = (props) => {
144
- const activeFileUploads = activeFileUploadsTrampoline(props);
145
- return !!(activeFileUploads === null || activeFileUploads === void 0 ? void 0 : activeFileUploads.find((file) => !file.error));
146
- return false;
147
- };
148
156
  const sanitizeText = (message) => {
149
157
  if (EMPTY_MESSAGE_REGEX.test(message)) {
150
158
  return '';
@@ -153,9 +161,4 @@ const sanitizeText = (message) => {
153
161
  return message;
154
162
  }
155
163
  };
156
- const activeFileUploadsTrampoline = (props) => {
157
- /* @conditional-compile-remove(file-sharing) */
158
- return props.activeFileUploads;
159
- return [];
160
- };
161
164
  //# sourceMappingURL=SendBox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SendBox.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/SendBox.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useState, useMemo, useCallback } from 'react';\nimport { IStyle, ITextField, mergeStyles, concatStyleSets, Icon, Stack } from '@fluentui/react';\nimport { sendButtonStyle, sendIconStyle, sendBoxWrapperStyles, borderAndBoxShadowStyle } from './styles/SendBox.styles';\nimport { BaseCustomStyles } from '../types';\nimport { useTheme } from '../theming';\nimport { useLocale } from '../localization';\nimport { useIdentifiers } from '../identifiers';\nimport { InputBoxButton, InputBoxComponent } from './InputBoxComponent';\nimport { SendBoxErrors } from './SendBoxErrors';\n/* @conditional-compile-remove(file-sharing) */\nimport { _FileUploadCards } from './FileUploadCards';\n/* @conditional-compile-remove(file-sharing) */\nimport { fileUploadCardsStyles } from './styles/SendBox.styles';\nimport { SendBoxErrorBarError } from './SendBoxErrorBar';\n/* @conditional-compile-remove(mention) */\nimport { MentionLookupOptions } from './MentionPopover';\n\nconst EMPTY_MESSAGE_REGEX = /^\\s*$/;\nconst MAXIMUM_LENGTH_OF_MESSAGE = 8000;\n\n/**\n * Fluent styles for {@link Sendbox}.\n *\n * @public\n */\nexport interface SendBoxStylesProps extends BaseCustomStyles {\n /** Styles for the text field. */\n textField?: IStyle;\n /** styles for the text field container */\n textFieldContainer?: IStyle;\n /** Styles for the container of the send message icon. */\n sendMessageIconContainer?: IStyle;\n /** Styles for the send message icon; These styles will be ignored when a custom send message icon is provided. */\n sendMessageIcon?: IStyle;\n /** Styles for the system message; These styles will be ignored when a custom system message component is provided. */\n systemMessage?: IStyle;\n}\n\n/**\n * Attributes required for SendBox to show file uploads like name, progress etc.\n * @beta\n */\nexport interface ActiveFileUpload {\n /**\n * Unique identifier for the file upload.\n */\n id: string;\n\n /**\n * File name to be rendered for uploaded file.\n */\n filename: string;\n\n /**\n * A number between 0 and 1 indicating the progress of the upload.\n * This is unrelated to the `uploadComplete` property.\n * It is only used to show the progress of the upload.\n * Progress of 1 doesn't mark the upload as complete, set the `uploadComplete`\n * property to true to mark the upload as complete.\n */\n progress: number;\n\n /**\n * Error to be displayed to the user if the upload fails.\n */\n error?: SendBoxErrorBarError;\n\n /**\n * `true` means that the upload is completed.\n * This is independent of the upload `progress`.\n */\n uploadComplete?: boolean;\n}\n\n/**\n * Strings of {@link SendBox} that can be overridden.\n *\n * @public\n */\nexport interface SendBoxStrings {\n /**\n * Placeholder text in SendBox when there is no user input\n */\n placeholderText: string;\n /**\n * The warning message when send box text length is more than max limit\n */\n textTooLong: string;\n /**\n * Aria label for send message button\n */\n sendButtonAriaLabel: string;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Error message indicating that all file uploads are not complete.\n */\n fileUploadsPendingError: string;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Aria label to notify user when focus is on cancel file upload button.\n */\n removeFile: string;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Aria label to notify user file uploading starts.\n */\n uploading: string;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Aria label to notify user file is uploaded.\n */\n uploadCompleted: string;\n}\n\n/**\n * Props for {@link SendBox}.\n *\n * @public\n */\nexport interface SendBoxProps {\n /**\n * Optional boolean to disable text box\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * Optional text for system message below text box\n */\n systemMessage?: string;\n /**\n * Optional override behavior on send button click\n */\n onSendMessage?: (content: string) => Promise<void>;\n /* @conditional-compile-remove(mention) */\n /**\n * Optional props needed to lookup suggestions in the mention scenario.\n * @beta\n */\n mentionLookupOptions?: MentionLookupOptions;\n\n /**\n * Optional callback called when user is typing\n */\n onTyping?: () => Promise<void>;\n /**\n * Optional callback to render system message below the SendBox.\n * @defaultValue MessageBar\n */\n onRenderSystemMessage?: (systemMessage: string | undefined) => React.ReactElement;\n /**\n * Optional boolean to support new line in SendBox.\n * @defaultValue false\n */\n supportNewline?: boolean;\n /**\n * Optional callback to render send button icon to the right of the SendBox.\n * @defaultValue SendBoxSendHovered icon when mouse over icon and SendBoxSend icon otherwise\n */\n onRenderIcon?: (isHover: boolean) => JSX.Element;\n /**\n * Allows users to pass in an object contains custom CSS styles.\n * @Example\n * ```\n * <SendBox styles={{ root: { background: 'blue' } }} />\n * ```\n */\n styles?: SendBoxStylesProps;\n /**\n * Optional strings to override in component\n */\n strings?: Partial<SendBoxStrings>;\n /**\n * enumerable to determine if the input box has focus on render or not.\n * When undefined nothing has focus on render\n */\n autoFocus?: 'sendBoxTextField';\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Optional callback to render uploaded files in the SendBox. The sendBox will expand\n * vertically to accommodate the uploaded files. File uploads will\n * be rendered below the text area in sendBox.\n * @beta\n */\n onRenderFileUploads?: () => JSX.Element;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Optional array of active file uploads where each object has attributes\n * of a file upload like name, progress, errorMessage etc.\n * @beta\n */\n activeFileUploads?: ActiveFileUpload[];\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Optional callback to remove the file upload before sending by clicking on\n * cancel icon.\n * @beta\n */\n onCancelFileUpload?: (fileId: string) => void;\n}\n\n/**\n * Component for typing and sending messages.\n *\n * Supports sending typing notification when user starts entering text.\n * Supports an optional message below the text input field.\n *\n * @public\n */\nexport const SendBox = (props: SendBoxProps): JSX.Element => {\n const {\n disabled,\n systemMessage,\n supportNewline,\n onSendMessage,\n onTyping,\n onRenderIcon,\n onRenderSystemMessage,\n styles,\n autoFocus,\n /* @conditional-compile-remove(mention) */\n mentionLookupOptions\n } = props;\n const theme = useTheme();\n const localeStrings = useLocale().strings.sendBox;\n const strings = { ...localeStrings, ...props.strings };\n const ids = useIdentifiers();\n const activeFileUploads = activeFileUploadsTrampoline(props);\n\n const [textValue, setTextValue] = useState('');\n const [textValueOverflow, setTextValueOverflow] = useState(false);\n\n const sendTextFieldRef = React.useRef<ITextField>(null);\n\n const [fileUploadsPendingError, setFileUploadsPendingError] = useState<SendBoxErrorBarError | undefined>(undefined);\n\n const sendMessageOnClick = (): void => {\n // don't send a message when disabled\n if (disabled || textValueOverflow) {\n return;\n }\n\n // Don't send message until all files have been uploaded successfully\n setFileUploadsPendingError(undefined);\n\n if (hasIncompleteFileUploads(props)) {\n /* @conditional-compile-remove(file-sharing) */\n setFileUploadsPendingError({ message: strings.fileUploadsPendingError, timestamp: Date.now() });\n return;\n }\n\n const message = textValue;\n // we don't want to send empty messages including spaces, newlines, tabs\n // Message can be empty if there is a valid file upload\n if (!EMPTY_MESSAGE_REGEX.test(message) || hasFile(props)) {\n onSendMessage && onSendMessage(sanitizeText(message));\n setTextValue('');\n }\n sendTextFieldRef.current?.focus();\n };\n\n const setText = (newValue?: string | undefined): void => {\n if (newValue === undefined) {\n return;\n }\n\n if (newValue.length > MAXIMUM_LENGTH_OF_MESSAGE) {\n setTextValueOverflow(true);\n } else {\n setTextValueOverflow(false);\n }\n setTextValue(newValue);\n };\n\n const textTooLongMessage = textValueOverflow ? strings.textTooLong : undefined;\n const errorMessage = systemMessage ?? textTooLongMessage;\n\n const mergedSendButtonStyle = useMemo(\n () => mergeStyles(sendButtonStyle, styles?.sendMessageIconContainer),\n [styles?.sendMessageIconContainer]\n );\n\n const mergedStyles = useMemo(() => concatStyleSets(styles), [styles]);\n\n const hasText = !!textValue;\n const hasTextOrFile = hasText || hasFile(props);\n\n const mergedSendIconStyle = useMemo(\n () =>\n mergeStyles(\n sendIconStyle,\n {\n color: !!errorMessage || !hasTextOrFile ? theme.palette.neutralTertiary : theme.palette.themePrimary\n },\n styles?.sendMessageIcon\n ),\n [errorMessage, hasTextOrFile, theme, styles?.sendMessageIcon]\n );\n\n const onRenderSendIcon = useCallback(\n (isHover: boolean) =>\n onRenderIcon ? (\n onRenderIcon(isHover)\n ) : (\n <Icon iconName={isHover && textValue ? 'SendBoxSendHovered' : 'SendBoxSend'} className={mergedSendIconStyle} />\n ),\n [mergedSendIconStyle, onRenderIcon, textValue]\n );\n\n // Ensure that errors are cleared when there are no files in sendBox\n React.useEffect(() => {\n if (!activeFileUploads?.filter((upload) => !upload.error).length) {\n setFileUploadsPendingError(undefined);\n }\n }, [activeFileUploads]);\n\n const sendBoxErrorsProps = useMemo(() => {\n return {\n fileUploadsPendingError: fileUploadsPendingError,\n fileUploadError: activeFileUploads?.filter((fileUpload) => fileUpload.error).pop()?.error\n };\n }, [activeFileUploads, fileUploadsPendingError]);\n\n /* @conditional-compile-remove(file-sharing) */\n const onRenderFileUploads = useCallback(() => {\n if (!activeFileUploads?.filter((upload) => !upload.error).length) {\n return null;\n }\n return props.onRenderFileUploads ? (\n props.onRenderFileUploads()\n ) : (\n <Stack className={fileUploadCardsStyles}>\n <_FileUploadCards\n activeFileUploads={activeFileUploads}\n onCancelFileUpload={props.onCancelFileUpload}\n strings={{\n removeFile: props.strings?.removeFile ?? localeStrings.removeFile,\n uploading: props.strings?.uploading ?? localeStrings.uploading,\n uploadCompleted: props.strings?.uploadCompleted ?? localeStrings.uploadCompleted\n }}\n />\n </Stack>\n );\n }, [activeFileUploads, props, localeStrings]);\n\n return (\n <Stack\n className={mergeStyles(\n sendBoxWrapperStyles,\n { overflow: 'visible' } // This is needed for the mention popup to be visible\n )}\n >\n <SendBoxErrors {...sendBoxErrorsProps} />\n <Stack\n className={mergeStyles(\n borderAndBoxShadowStyle({\n theme,\n hasErrorMessage: !!errorMessage,\n disabled: !!disabled\n })\n )}\n >\n <InputBoxComponent\n autoFocus={autoFocus}\n data-ui-id={ids.sendboxTextField}\n disabled={disabled}\n errorMessage={onRenderSystemMessage ? onRenderSystemMessage(errorMessage) : errorMessage}\n textFieldRef={sendTextFieldRef}\n id=\"sendbox\"\n placeholderText={strings.placeholderText}\n textValue={textValue}\n onChange={(_, newValue) => setText(newValue)}\n onKeyDown={(ev) => {\n const keyWasSendingMessage = ev.key === 'Enter' && (ev.shiftKey === false || !supportNewline);\n if (!keyWasSendingMessage) {\n onTyping?.();\n }\n }}\n onEnterKeyDown={() => {\n sendMessageOnClick();\n }}\n styles={mergedStyles}\n supportNewline={supportNewline}\n maxLength={MAXIMUM_LENGTH_OF_MESSAGE}\n /* @conditional-compile-remove(mention) */\n mentionLookupOptions={mentionLookupOptions}\n >\n <InputBoxButton\n onRenderIcon={onRenderSendIcon}\n onClick={(e) => {\n if (!textValueOverflow) {\n sendMessageOnClick();\n }\n e.stopPropagation();\n }}\n id={'sendIconWrapper'}\n className={mergedSendButtonStyle}\n ariaLabel={localeStrings.sendButtonAriaLabel}\n tooltipContent={localeStrings.sendButtonAriaLabel}\n />\n </InputBoxComponent>\n {\n /* @conditional-compile-remove(file-sharing) */\n onRenderFileUploads()\n }\n </Stack>\n </Stack>\n );\n};\n\n/**\n * @private\n */\nconst hasIncompleteFileUploads = (props: SendBoxProps): boolean => {\n const activeFileUploads = activeFileUploadsTrampoline(props);\n return !!(\n activeFileUploads?.length &&\n !activeFileUploads.filter((fileUpload) => !fileUpload.error).every((fileUpload) => fileUpload.uploadComplete)\n );\n};\n\nconst hasFile = (props: SendBoxProps): boolean => {\n const activeFileUploads = activeFileUploadsTrampoline(props);\n return !!activeFileUploads?.find((file) => !file.error);\n return false;\n};\n\nconst sanitizeText = (message: string): string => {\n if (EMPTY_MESSAGE_REGEX.test(message)) {\n return '';\n } else {\n return message;\n }\n};\n\nconst activeFileUploadsTrampoline = (props: SendBoxProps): ActiveFileUpload[] | undefined => {\n /* @conditional-compile-remove(file-sharing) */\n return props.activeFileUploads;\n return [];\n};\n"]}
1
+ {"version":3,"file":"SendBox.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/SendBox.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useState, useMemo, useCallback } from 'react';\nimport { IStyle, ITextField, mergeStyles, concatStyleSets, Icon, Stack } from '@fluentui/react';\nimport { sendButtonStyle, sendIconStyle, sendBoxWrapperStyles, borderAndBoxShadowStyle } from './styles/SendBox.styles';\nimport { BaseCustomStyles } from '../types';\nimport { useTheme } from '../theming';\nimport { useLocale } from '../localization';\nimport { useIdentifiers } from '../identifiers';\nimport { InputBoxComponent } from './InputBoxComponent';\nimport { InputBoxButton } from './InputBoxButton';\n/* @conditional-compile-remove(file-sharing) */\nimport { SendBoxErrors } from './SendBoxErrors';\n/* @conditional-compile-remove(file-sharing) */\nimport { ActiveFileUpload, _FileUploadCards } from './FileUploadCards';\n/* @conditional-compile-remove(file-sharing) */\nimport { fileUploadCardsStyles } from './styles/SendBox.styles';\n/* @conditional-compile-remove(file-sharing) */\nimport { SendBoxErrorBarError } from './SendBoxErrorBar';\n/* @conditional-compile-remove(file-sharing) */\nimport { hasCompletedFileUploads, hasIncompleteFileUploads } from './utils/SendBoxUtils';\n/* @conditional-compile-remove(mention) */\nimport { MentionLookupOptions } from './MentionPopover';\n\nconst MAXIMUM_LENGTH_OF_MESSAGE = 8000;\nconst EMPTY_MESSAGE_REGEX = /^\\s*$/;\n\n/**\n * Fluent styles for {@link Sendbox}.\n *\n * @public\n */\nexport interface SendBoxStylesProps extends BaseCustomStyles {\n /** Styles for the text field. */\n textField?: IStyle;\n /** styles for the text field container */\n textFieldContainer?: IStyle;\n /** Styles for the container of the send message icon. */\n sendMessageIconContainer?: IStyle;\n /** Styles for the send message icon; These styles will be ignored when a custom send message icon is provided. */\n sendMessageIcon?: IStyle;\n /** Styles for the system message; These styles will be ignored when a custom system message component is provided. */\n systemMessage?: IStyle;\n}\n\n/**\n * Strings of {@link SendBox} that can be overridden.\n *\n * @public\n */\nexport interface SendBoxStrings {\n /**\n * Placeholder text in SendBox when there is no user input\n */\n placeholderText: string;\n /**\n * The warning message when send box text length is more than max limit\n */\n textTooLong: string;\n /**\n * Aria label for send message button\n */\n sendButtonAriaLabel: string;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Error message indicating that all file uploads are not complete.\n */\n fileUploadsPendingError: string;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Aria label to notify user when focus is on cancel file upload button.\n */\n removeFile: string;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Aria label to notify user file uploading starts.\n */\n uploading: string;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Aria label to notify user file is uploaded.\n */\n uploadCompleted: string;\n}\n\n/**\n * Props for {@link SendBox}.\n *\n * @public\n */\nexport interface SendBoxProps {\n /**\n * Optional boolean to disable text box\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * Optional text for system message below text box\n */\n systemMessage?: string;\n /**\n * Optional override behavior on send button click\n */\n onSendMessage?: (content: string) => Promise<void>;\n /* @conditional-compile-remove(mention) */\n /**\n * Optional props needed to lookup suggestions in the mention scenario.\n * @beta\n */\n mentionLookupOptions?: MentionLookupOptions;\n\n /**\n * Optional callback called when user is typing\n */\n onTyping?: () => Promise<void>;\n /**\n * Optional callback to render system message below the SendBox.\n * @defaultValue MessageBar\n */\n onRenderSystemMessage?: (systemMessage: string | undefined) => React.ReactElement;\n /**\n * Optional boolean to support new line in SendBox.\n * @defaultValue false\n */\n supportNewline?: boolean;\n /**\n * Optional callback to render send button icon to the right of the SendBox.\n * @defaultValue SendBoxSendHovered icon when mouse over icon and SendBoxSend icon otherwise\n */\n onRenderIcon?: (isHover: boolean) => JSX.Element;\n /**\n * Allows users to pass in an object contains custom CSS styles.\n * @Example\n * ```\n * <SendBox styles={{ root: { background: 'blue' } }} />\n * ```\n */\n styles?: SendBoxStylesProps;\n /**\n * Optional strings to override in component\n */\n strings?: Partial<SendBoxStrings>;\n /**\n * enumerable to determine if the input box has focus on render or not.\n * When undefined nothing has focus on render\n */\n autoFocus?: 'sendBoxTextField';\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Optional callback to render uploaded files in the SendBox. The sendBox will expand\n * vertically to accommodate the uploaded files. File uploads will\n * be rendered below the text area in sendBox.\n * @beta\n */\n onRenderFileUploads?: () => JSX.Element;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Optional array of active file uploads where each object has attributes\n * of a file upload like name, progress, errorMessage etc.\n * @beta\n */\n activeFileUploads?: ActiveFileUpload[];\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Optional callback to remove the file upload before sending by clicking on\n * cancel icon.\n * @beta\n */\n onCancelFileUpload?: (fileId: string) => void;\n}\n\n/**\n * Component for typing and sending messages.\n *\n * Supports sending typing notification when user starts entering text.\n * Supports an optional message below the text input field.\n *\n * @public\n */\nexport const SendBox = (props: SendBoxProps): JSX.Element => {\n const {\n disabled,\n systemMessage,\n supportNewline,\n onSendMessage,\n onTyping,\n onRenderIcon,\n onRenderSystemMessage,\n styles,\n autoFocus,\n /* @conditional-compile-remove(mention) */\n mentionLookupOptions,\n /* @conditional-compile-remove(file-sharing) */\n activeFileUploads\n } = props;\n const theme = useTheme();\n const localeStrings = useLocale().strings.sendBox;\n const strings = { ...localeStrings, ...props.strings };\n const ids = useIdentifiers();\n\n const [textValue, setTextValue] = useState('');\n const [textValueOverflow, setTextValueOverflow] = useState(false);\n\n const sendTextFieldRef = React.useRef<ITextField>(null);\n\n /* @conditional-compile-remove(file-sharing) */\n const [fileUploadsPendingError, setFileUploadsPendingError] = useState<SendBoxErrorBarError | undefined>(undefined);\n\n const sendMessageOnClick = (): void => {\n // don't send a message when disabled\n if (disabled || textValueOverflow) {\n return;\n }\n\n // Don't send message until all files have been uploaded successfully\n /* @conditional-compile-remove(file-sharing) */\n setFileUploadsPendingError(undefined);\n\n /* @conditional-compile-remove(file-sharing) */\n if (hasIncompleteFileUploads(activeFileUploads)) {\n setFileUploadsPendingError({ message: strings.fileUploadsPendingError, timestamp: Date.now() });\n return;\n }\n\n const message = textValue;\n // we don't want to send empty messages including spaces, newlines, tabs\n // Message can be empty if there is a valid file upload\n if (\n !EMPTY_MESSAGE_REGEX.test(message) ||\n /* @conditional-compile-remove(file-sharing) */ hasCompletedFileUploads(activeFileUploads)\n ) {\n onSendMessage && onSendMessage(sanitizeText(message));\n setTextValue('');\n }\n sendTextFieldRef.current?.focus();\n };\n\n const setText = (newValue?: string | undefined): void => {\n if (newValue === undefined) {\n return;\n }\n\n if (newValue.length > MAXIMUM_LENGTH_OF_MESSAGE) {\n setTextValueOverflow(true);\n } else {\n setTextValueOverflow(false);\n }\n setTextValue(newValue);\n };\n\n const textTooLongMessage = textValueOverflow ? strings.textTooLong : undefined;\n const errorMessage = systemMessage ?? textTooLongMessage;\n\n const mergedSendButtonStyle = useMemo(\n () => mergeStyles(sendButtonStyle, styles?.sendMessageIconContainer),\n [styles?.sendMessageIconContainer]\n );\n\n const mergedStyles = useMemo(() => concatStyleSets(styles), [styles]);\n\n const mergedSendIconStyle = useMemo(\n () =>\n sendIconStyle({\n theme,\n hasText: !!textValue,\n /* @conditional-compile-remove(file-sharing) */ hasFile: hasCompletedFileUploads(activeFileUploads),\n hasErrorMessage: !!errorMessage,\n customSendIconStyle: styles?.sendMessageIcon\n }),\n [\n theme,\n textValue,\n /* @conditional-compile-remove(file-sharing) */ activeFileUploads,\n errorMessage,\n styles?.sendMessageIcon\n ]\n );\n\n const onRenderSendIcon = useCallback(\n (isHover: boolean) =>\n onRenderIcon ? (\n onRenderIcon(isHover)\n ) : (\n <Icon iconName={isHover && textValue ? 'SendBoxSendHovered' : 'SendBoxSend'} className={mergedSendIconStyle} />\n ),\n [mergedSendIconStyle, onRenderIcon, textValue]\n );\n\n // Ensure that errors are cleared when there are no files in sendBox\n /* @conditional-compile-remove(file-sharing) */\n React.useEffect(() => {\n if (!activeFileUploads?.filter((upload) => !upload.error).length) {\n setFileUploadsPendingError(undefined);\n }\n }, [activeFileUploads]);\n\n /* @conditional-compile-remove(file-sharing) */\n const sendBoxErrorsProps = useMemo(() => {\n return {\n fileUploadsPendingError: fileUploadsPendingError,\n fileUploadError: activeFileUploads?.filter((fileUpload) => fileUpload.error).pop()?.error\n };\n }, [activeFileUploads, fileUploadsPendingError]);\n\n /* @conditional-compile-remove(file-sharing) */\n const onRenderFileUploads = useCallback(() => {\n if (!activeFileUploads?.filter((upload) => !upload.error).length) {\n return null;\n }\n return props.onRenderFileUploads ? (\n props.onRenderFileUploads()\n ) : (\n <Stack className={fileUploadCardsStyles}>\n <_FileUploadCards\n activeFileUploads={activeFileUploads}\n onCancelFileUpload={props.onCancelFileUpload}\n strings={{\n removeFile: props.strings?.removeFile ?? localeStrings.removeFile,\n uploading: props.strings?.uploading ?? localeStrings.uploading,\n uploadCompleted: props.strings?.uploadCompleted ?? localeStrings.uploadCompleted\n }}\n />\n </Stack>\n );\n }, [activeFileUploads, props, localeStrings]);\n\n return (\n <Stack\n className={mergeStyles(\n sendBoxWrapperStyles,\n { overflow: 'visible' } // This is needed for the mention popup to be visible\n )}\n >\n {/* @conditional-compile-remove(file-sharing) */ <SendBoxErrors {...sendBoxErrorsProps} />}\n <Stack\n className={borderAndBoxShadowStyle({\n theme,\n hasErrorMessage: !!errorMessage,\n disabled: !!disabled\n })}\n >\n <InputBoxComponent\n autoFocus={autoFocus}\n data-ui-id={ids.sendboxTextField}\n disabled={disabled}\n errorMessage={onRenderSystemMessage ? onRenderSystemMessage(errorMessage) : errorMessage}\n textFieldRef={sendTextFieldRef}\n id=\"sendbox\"\n placeholderText={strings.placeholderText}\n textValue={textValue}\n onChange={(_, newValue) => setText(newValue)}\n onKeyDown={(ev) => {\n const keyWasSendingMessage = ev.key === 'Enter' && (ev.shiftKey === false || !supportNewline);\n if (!keyWasSendingMessage) {\n onTyping?.();\n }\n }}\n onEnterKeyDown={() => {\n sendMessageOnClick();\n }}\n styles={mergedStyles}\n supportNewline={supportNewline}\n maxLength={MAXIMUM_LENGTH_OF_MESSAGE}\n /* @conditional-compile-remove(mention) */\n mentionLookupOptions={mentionLookupOptions}\n >\n <InputBoxButton\n onRenderIcon={onRenderSendIcon}\n onClick={(e) => {\n if (!textValueOverflow) {\n sendMessageOnClick();\n }\n e.stopPropagation();\n }}\n id={'sendIconWrapper'}\n className={mergedSendButtonStyle}\n ariaLabel={localeStrings.sendButtonAriaLabel}\n tooltipContent={localeStrings.sendButtonAriaLabel}\n />\n </InputBoxComponent>\n {\n /* @conditional-compile-remove(file-sharing) */\n onRenderFileUploads()\n }\n </Stack>\n </Stack>\n );\n};\n\n/**\n * @private\n */\nconst sanitizeText = (message: string): string => {\n if (EMPTY_MESSAGE_REGEX.test(message)) {\n return '';\n } else {\n return message;\n }\n};\n"]}