@azure/communication-react 1.12.1-alpha-202401230013 → 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.
- package/dist/communication-react.d.ts +39 -5
- package/dist/dist-cjs/communication-react/index.js +769 -494
- package/dist/dist-cjs/communication-react/index.js.map +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
- package/dist/dist-esm/communication-react/src/index.d.ts +1 -1
- package/dist/dist-esm/communication-react/src/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsEditBox.js +2 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsEditBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/Dialpad/Dialpad.d.ts +9 -5
- package/dist/dist-esm/react-components/src/components/Dialpad/Dialpad.js +5 -9
- package/dist/dist-esm/react-components/src/components/Dialpad/Dialpad.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/FileUploadCards.d.ts +32 -1
- package/dist/dist-esm/react-components/src/components/FileUploadCards.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/InputBoxButton.d.ts +19 -0
- package/dist/dist-esm/react-components/src/components/InputBoxButton.js +32 -0
- package/dist/dist-esm/react-components/src/components/InputBoxButton.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/InputBoxComponent.d.ts +0 -17
- package/dist/dist-esm/react-components/src/components/InputBoxComponent.js +3 -29
- package/dist/dist-esm/react-components/src/components/InputBoxComponent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RTE/RTEInputBoxComponent.d.ts +19 -0
- package/dist/dist-esm/react-components/src/components/RTE/RTEInputBoxComponent.js +13 -0
- package/dist/dist-esm/react-components/src/components/RTE/RTEInputBoxComponent.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RTE/RTESendBox.d.ts +34 -1
- package/dist/dist-esm/react-components/src/components/RTE/RTESendBox.js +45 -3
- package/dist/dist-esm/react-components/src/components/RTE/RTESendBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RTE/RTESendBoxErrors.d.ts +15 -0
- package/dist/dist-esm/react-components/src/components/RTE/RTESendBoxErrors.js +18 -0
- package/dist/dist-esm/react-components/src/components/RTE/RTESendBoxErrors.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RTE/RichTextEditor.d.ts +18 -0
- package/dist/dist-esm/react-components/src/components/RTE/RichTextEditor.js +40 -0
- package/dist/dist-esm/react-components/src/components/RTE/RichTextEditor.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/SendBox.d.ts +1 -32
- package/dist/dist-esm/react-components/src/components/SendBox.js +33 -30
- package/dist/dist-esm/react-components/src/components/SendBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.d.ts +0 -17
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js +1 -28
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/index.d.ts +2 -1
- package/dist/dist-esm/react-components/src/components/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/InputBoxButton.style.d.ts +13 -0
- package/dist/dist-esm/react-components/src/components/styles/InputBoxButton.style.js +30 -0
- package/dist/dist-esm/react-components/src/components/styles/InputBoxButton.style.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/styles/InputBoxComponent.style.d.ts +0 -16
- package/dist/dist-esm/react-components/src/components/styles/InputBoxComponent.style.js +0 -32
- package/dist/dist-esm/react-components/src/components/styles/InputBoxComponent.style.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.d.ts +5 -0
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js +16 -0
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/styles/SendBox.styles.d.ts +8 -2
- package/dist/dist-esm/react-components/src/components/styles/SendBox.styles.js +13 -7
- package/dist/dist-esm/react-components/src/components/styles/SendBox.styles.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.d.ts +10 -0
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js +18 -0
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/CallComposite.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.d.ts +20 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.d.ts +2 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.js +5 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/CallPage.js +65 -10
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/CallPage.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/DtmfDialpadPage.d.ts +26 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/DtmfDialpadPage.js +66 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/DtmfDialpadPage.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/baseSelectors.d.ts +5 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/baseSelectors.js +4 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/baseSelectors.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/DtmfDialpadPage.styles.d.ts +8 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/DtmfDialpadPage.styles.js +18 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/DtmfDialpadPage.styles.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/MediaGalleryUtils.d.ts +7 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/MediaGalleryUtils.js +13 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/MediaGalleryUtils.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/timerUtils.d.ts +17 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/timerUtils.js +30 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/timerUtils.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CommonCallControlBar.d.ts +2 -0
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CommonCallControlBar.js +22 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CommonCallControlBar.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DesktopMoreButton.d.ts +2 -0
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DesktopMoreButton.js +40 -18
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DesktopMoreButton.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DtmfDialerButton.d.ts +18 -0
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DtmfDialerButton.js +41 -0
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DtmfDialerButton.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/common/icons.d.ts +3 -0
- package/dist/dist-esm/react-composites/src/composites/common/icons.js +3 -1
- package/dist/dist-esm/react-composites/src/composites/common/icons.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/types/CommonCallControlOptions.d.ts +6 -0
- package/dist/dist-esm/react-composites/src/composites/common/types/CommonCallControlOptions.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/localization/locales/en-US/strings.json +5 -0
- package/dist/tsdoc-metadata.json +1 -1
- package/package.json +5 -1
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"InputBoxComponent.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/InputBoxComponent.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAwB,WAAW,EAAE,MAAM,OAAO,CAAC;AAE3E,OAAO,EACL,KAAK,EACL,SAAS,EACT,WAAW,EAGX,eAAe,EACf,UAAU,EACV,WAAW,EAGZ,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,qCAAqC,EAAE,MAAM,SAAS,CAAC;AAEhE,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EACjB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,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;AAgBF;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAA0B,EAAe,EAAE;IACxE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;IAClF,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,iBAAiB,GAAG,WAAW,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;IAEnE,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,YAAY,GAAmC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC;IAElH,uDAAuD;IACvD,MAAM,YAAY,GAAG;QACnB,QAAQ,EAAE,CAAC;QACX,MAAM,EAAE,YAAY;QACpB,eAAe,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE;KACzE,CAAC;IACF,OAAO,CACL,oBAAC,WAAW,IAAC,aAAa,EAAE,uBAAuB,EAAE,OAAO,EAAE,cAAc,EAAE,YAAY,oBAAO,YAAY;QAC3G,oBAAC,UAAU,IACT,SAAS,EAAE,iBAAiB,EAC5B,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,EAAE,EACN,YAAY,EAAE,GAAG,EAAE;gBACjB,UAAU,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC,EACD,YAAY,EAAE,GAAG,EAAE;gBACjB,UAAU,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;YACD,yJAAyJ;YACzJ,YAAY,EAAE,GAAG,EAAE,CAAC,oBAAC,KAAK,IAAC,SAAS,EAAE,gBAAgB,IAAG,YAAY,CAAC,OAAO,CAAC,CAAS,GACvF,CACU,CACf,CAAC;AACJ,CAAC,CAAC","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":"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","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
|
-
|
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 {
|
11
|
-
|
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;
|
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 {
|
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 {
|
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
|
-
|
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
|
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
|
-
|
47
|
-
|
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) ||
|
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
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
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:
|
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"]}
|