Skip to content

Commit 1c606e9

Browse files
committed
Direct inject after building style elements
1 parent bfd5f2d commit 1c606e9

File tree

9 files changed

+91
-116
lines changed

9 files changed

+91
-116
lines changed

__tests__/html2/themeProvider/override.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@
127127
'fluent-theme',
128128
'component/decorator',
129129
'component',
130-
'component/CustomProperties'
130+
'component/CustomPropertiesContainer'
131131
]);
132132

133133
await directLine.emulateIncomingActivity('Hello, World!');
@@ -154,7 +154,7 @@
154154
'fluent-theme',
155155
'component/decorator',
156156
'component',
157-
'component/CustomProperties'
157+
'component/CustomPropertiesContainer'
158158
]);
159159
});
160160
</script>

packages/component/src/Composer.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import createDefaultSendBoxMiddleware from './SendBox/createMiddleware';
5050
import createDefaultSendBoxToolbarMiddleware from './SendBoxToolbar/createMiddleware';
5151
import createStyleSet from './Styles/createStyleSet';
5252
import CustomPropertiesContainer from './Styles/CustomPropertiesContainer';
53-
import InjectComponentCSS from './Styles/InjectComponentCSS';
53+
import ComponentCSS from './stylesheet/ComponentCSS';
5454
import { type ContextOf } from './types/ContextOf';
5555
import { type FocusTranscriptInit } from './types/internal/FocusTranscriptInit';
5656
import addTargetBlankToHyperlinksMarkdown from './Utils/addTargetBlankToHyperlinksMarkdown';
@@ -486,9 +486,9 @@ const InternalComposer = ({
486486

487487
const Composer = (props: ComposerProps) => (
488488
// eslint-disable-next-line react/destructuring-assignment
489-
<InjectComponentCSS nonce={props.nonce}>
489+
<ComponentCSS nonce={props.nonce}>
490490
<InternalComposer {...props} />
491-
</InjectComponentCSS>
491+
</ComponentCSS>
492492
);
493493

494494
Composer.defaultProps = {

packages/component/src/Styles/InjectCSS.tsx

Lines changed: 0 additions & 37 deletions
This file was deleted.

packages/component/src/Styles/InjectComponentCSS.tsx

Lines changed: 0 additions & 32 deletions
This file was deleted.

packages/component/src/decorator/private/InjectDecoratorCSS.tsx

Lines changed: 0 additions & 32 deletions
This file was deleted.

packages/component/src/decorator/private/WebChatDecorator.tsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@ import {
66
type DecoratorMiddleware
77
} from 'botframework-webchat-api/decorator';
88
import React, { memo } from 'react';
9-
import { object, optional, pipe, readonly, type InferInput } from 'valibot';
9+
import { object, optional, pipe, readonly, string, undefinedable, type InferInput } from 'valibot';
1010

11-
import useNonce from '../../hooks/internal/useNonce';
11+
import DecoratorCSS from '../../stylesheet/DecoratorCSS';
1212
import BorderFlair from './BorderFlair';
1313
import BorderLoader from './BorderLoader';
14-
import InjectDecoratorCSS from './InjectDecoratorCSS';
1514

1615
const middleware: readonly DecoratorMiddleware[] = Object.freeze([
1716
createActivityBorderMiddleware(function BorderFlairDecorator({ request, Next, ...props }) {
@@ -32,22 +31,21 @@ const middleware: readonly DecoratorMiddleware[] = Object.freeze([
3231

3332
const webChatDecoratorPropsSchema = pipe(
3433
object({
35-
children: optional(reactNode())
34+
children: optional(reactNode()),
35+
nonce: undefinedable(string())
3636
}),
3737
readonly()
3838
);
3939

4040
type WebChatDecoratorProps = InferInput<typeof webChatDecoratorPropsSchema>;
4141

4242
function WebChatDecorator(props: WebChatDecoratorProps) {
43-
const { children } = validateProps(webChatDecoratorPropsSchema, props);
44-
45-
const [nonce] = useNonce();
43+
const { children, nonce } = validateProps(webChatDecoratorPropsSchema, props);
4644

4745
return (
48-
<InjectDecoratorCSS nonce={nonce}>
46+
<DecoratorCSS nonce={nonce}>
4947
<DecoratorComposer middleware={middleware}>{children}</DecoratorComposer>
50-
</InjectDecoratorCSS>
48+
</DecoratorCSS>
5149
);
5250
}
5351

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// TODO: [P2] This component can be replaced by `bindProps(InjectCSS)({ cssContent, identifier })`.
2+
import { reactNode, validateProps } from '@msinternal/botframework-webchat-react-valibot';
3+
import { makeCreateStyles } from '@msinternal/botframework-webchat-styles';
4+
import React, { memo, useMemo } from 'react';
5+
import { object, optional, pipe, readonly, string, undefinedable, type InferInput } from 'valibot';
6+
7+
import { InjectStyleElementsComposer } from '../boot/internal';
8+
import { componentCSSContent } from '../cssContent';
9+
10+
const componentCSSPropsSchema = pipe(
11+
object({
12+
children: optional(reactNode()),
13+
nonce: undefinedable(string())
14+
}),
15+
readonly()
16+
);
17+
18+
type ComponentCSSProps = InferInput<typeof componentCSSPropsSchema>;
19+
20+
function ComponentCSS(props: ComponentCSSProps) {
21+
const { children, nonce } = validateProps(componentCSSPropsSchema, props);
22+
23+
const styleElements = useMemo(() => {
24+
const styleElements = makeCreateStyles(componentCSSContent)('component');
25+
26+
nonce && styleElements.forEach(element => element.setAttribute('nonce', nonce));
27+
28+
return styleElements;
29+
}, [nonce]);
30+
31+
return <InjectStyleElementsComposer styleElements={styleElements}>{children}</InjectStyleElementsComposer>;
32+
}
33+
34+
ComponentCSS.displayName = 'ComponentCSS';
35+
36+
export default memo(ComponentCSS);
37+
export { componentCSSPropsSchema, type ComponentCSSProps };
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// TODO: [P2] This component can be replaced by `bindProps(InjectCSS)({ cssContent, identifier })`.
2+
import { reactNode, validateProps } from '@msinternal/botframework-webchat-react-valibot';
3+
import { makeCreateStyles } from '@msinternal/botframework-webchat-styles';
4+
import React, { memo, useMemo } from 'react';
5+
import { object, optional, pipe, readonly, string, undefinedable, type InferInput } from 'valibot';
6+
7+
import { InjectStyleElementsComposer } from '../boot/internal';
8+
import { decoratorCSSContent } from '../cssContent';
9+
10+
const decoratorCSSPropsSchema = pipe(
11+
object({
12+
children: optional(reactNode()),
13+
nonce: undefinedable(string())
14+
}),
15+
readonly()
16+
);
17+
18+
type DecoratorCSSProps = InferInput<typeof decoratorCSSPropsSchema>;
19+
20+
function DecoratorCSS(props: DecoratorCSSProps) {
21+
const { children, nonce } = validateProps(decoratorCSSPropsSchema, props);
22+
23+
const styleElements = useMemo(() => {
24+
const styleElements = makeCreateStyles(decoratorCSSContent)('component/decorator');
25+
26+
nonce && styleElements.forEach(element => element.setAttribute('nonce', nonce));
27+
28+
return styleElements;
29+
}, [nonce]);
30+
31+
return <InjectStyleElementsComposer styleElements={styleElements}>{children}</InjectStyleElementsComposer>;
32+
}
33+
34+
DecoratorCSS.displayName = 'DecoratorCSS';
35+
36+
export default memo(DecoratorCSS);
37+
export { decoratorCSSPropsSchema, type DecoratorCSSProps };

packages/fluent-theme/src/private/FluentThemeProvider.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,11 @@ function FluentThemeProvider(props: FluentThemeProviderProps) {
107107
typingIndicatorMiddleware={typingIndicatorMiddleware}
108108
>
109109
<AssetComposer>
110-
<WebChatDecorator>
110+
{/*
111+
<Composer> is not set up yet, we have no place to send nonce.
112+
This is temporal, until we decided to fold <WebChatDecorator> back into <Composer>.
113+
*/}
114+
<WebChatDecorator nonce={nonce}>
111115
<DecoratorComposer middleware={decoratorMiddleware}>{children}</DecoratorComposer>
112116
</WebChatDecorator>
113117
</AssetComposer>

0 commit comments

Comments
 (0)