Skip to content

Commit a2a7599

Browse files
committed
CSS Modules: migrate ActivityStatus
1 parent 70c5452 commit a2a7599

File tree

9 files changed

+74
-26
lines changed

9 files changed

+74
-26
lines changed

__tests__/html2/citation/claimInterpreter/dangerousLink.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565

6666
expect(markdownLinks[0].getAttribute('href')).toBe('https://aka.ms/claim');
6767

68-
const claimInterpreterElement = pageElements.activities()[0].querySelector('.webchat__activity-status__originator');
68+
const claimInterpreterElement = pageElements.activities()[0].querySelector('.activity-status__originator');
6969

7070
expect(claimInterpreterElement).toHaveProperty('tagName', 'SPAN');
7171
expect(claimInterpreterElement).toHaveProperty('textContent', 'Surfaced with Azure OpenAI');
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
:global(.webchat) .activity-status {
2+
color: var(--webchat__color--timestamp);
3+
font-family: var(--webchat__font--primary);
4+
font-size: var(--webchat__font-size--small);
5+
margin-block-start: calc(var(--webchat__padding--regular) / 2);
6+
7+
&.activity-status--slotted {
8+
display: inline-flex;
9+
gap: 4px;
10+
}
11+
}
12+
13+
:global(.webchat) .activity-status-slot {
14+
display: contents;
15+
16+
&:not(:first-child)::before {
17+
content: '|';
18+
}
19+
20+
&:empty {
21+
display: none;
22+
}
23+
}
24+
25+
:global(.webchat) .activity-status__originator {
26+
align-items: center;
27+
28+
&.activity-status__originator--has-link {
29+
color: var(--webchat__color--accent);
30+
}
31+
}

packages/component/src/ActivityStatus/OthersActivityStatus.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { warnOnce } from '@msinternal/botframework-webchat-base/utils';
2+
import { useStyles } from '@msinternal/botframework-webchat-styles/react';
23
import { hooks } from 'botframework-webchat-api';
34
import {
45
getOrgSchemaMessage,
@@ -7,27 +8,28 @@ import {
78
parseClaim,
89
type WebChatActivity
910
} from 'botframework-webchat-core';
10-
import classNames from 'classnames';
11+
import cx from 'classnames';
1112
import React, { memo, useMemo } from 'react';
1213

1314
import ActivityFeedback from '../ActivityFeedback/ActivityFeedback';
14-
import useStyleSet from '../hooks/useStyleSet';
1515
import dereferenceBlankNodes from '../Utils/JSONLinkedData/dereferenceBlankNodes';
1616
import Originator from './private/Originator';
1717
import StatusSlot from './StatusSlot';
1818
import Timestamp from './Timestamp';
1919

20+
import styles from './ActivityStatus.module.css';
21+
2022
const { useStyleOptions } = hooks;
2123

22-
type Props = Readonly<{ activity: WebChatActivity; className?: string | undefined }>;
24+
type Props = Readonly<{ activity: WebChatActivity; className?: string | undefined; slotted?: boolean }>;
2325

2426
const warnRootLevelThings = warnOnce(
2527
'Root-level things are being deprecated, please relate all things to `entities[@id=""]` instead. This feature will be removed in 2025-03-06.'
2628
);
2729

28-
const OthersActivityStatus = memo(({ activity, className }: Props) => {
30+
const OthersActivityStatus = memo(({ activity, className, slotted }: Props) => {
2931
const [{ feedbackActionsPlacement }] = useStyleOptions();
30-
const [{ sendStatus }] = useStyleSet();
32+
const classNames = useStyles(styles);
3133
const { timestamp } = activity;
3234
const graph = useMemo(() => dereferenceBlankNodes(activity.entities || []), [activity.entities]);
3335

@@ -60,7 +62,9 @@ const OthersActivityStatus = memo(({ activity, className }: Props) => {
6062
}, [graph, messageThing]);
6163

6264
return (
63-
<span className={classNames('webchat__activity-status', className, sendStatus + '')}>
65+
<span
66+
className={cx(classNames['activity-status'], { [classNames['activity-status--slotted']]: slotted }, className)}
67+
>
6468
{timestamp && (
6569
<StatusSlot>
6670
<Timestamp key="timestamp" timestamp={timestamp} />

packages/component/src/ActivityStatus/SelfActivityStatus.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1+
import { useStyles } from '@msinternal/botframework-webchat-styles/react';
12
import { type WebChatActivity } from 'botframework-webchat-core';
2-
import classNames from 'classnames';
3+
import cx from 'classnames';
34
import React, { memo } from 'react';
45

56
import Timestamp from './Timestamp';
6-
import useStyleSet from '../hooks/useStyleSet';
77

8-
type Props = Readonly<{ activity: WebChatActivity; className?: string | undefined }>;
8+
import styleClassNames from './ActivityStatus.module.css';
99

10-
const SelftActivityStatus = memo(({ activity, className }: Props) => {
11-
const [{ sendStatus }] = useStyleSet();
10+
type Props = Readonly<{ activity: WebChatActivity; className?: string | undefined; slotted?: boolean }>;
11+
12+
const SelftActivityStatus = memo(({ activity, className, slotted }: Props) => {
13+
const classNames = useStyles(styleClassNames);
1214
const { timestamp } = activity;
1315

1416
return timestamp ? (
1517
<span
16-
className={classNames('webchat__activity-status', 'webchat__activity-status--self', className, sendStatus + '')}
18+
className={cx(classNames['activity-status'], { [classNames['activity-status--slotted']]: slotted }, className)}
1719
>
1820
<Timestamp timestamp={timestamp} />
1921
</span>

packages/component/src/ActivityStatus/SendStatus/SendStatus.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { validateProps } from '@msinternal/botframework-webchat-react-valibot';
22
import { hooks } from 'botframework-webchat-api';
3-
import classNames from 'classnames';
3+
import { useStyles } from '@msinternal/botframework-webchat-styles/react';
44
import React, { memo, useCallback } from 'react';
55
import { any, literal, object, pipe, readonly, union, type InferInput } from 'valibot';
66

77
import useFocus from '../../hooks/useFocus';
8-
import useStyleSet from '../../hooks/useStyleSet';
98
import { SENDING, SEND_FAILED, SENT } from '../../types/internal/SendStatus';
109
import SendFailedRetry from './private/SendFailedRetry';
1110

11+
import styles from '../ActivityStatus.module.css';
12+
1213
const { useLocalizer, usePostActivity } = hooks;
1314

1415
const sendStatusPropsSchema = pipe(
@@ -24,10 +25,10 @@ type SendStatusProps = InferInput<typeof sendStatusPropsSchema>;
2425
function SendStatus(props: SendStatusProps) {
2526
const { activity, sendStatus } = validateProps(sendStatusPropsSchema, props);
2627

27-
const [{ sendStatus: sendStatusStyleSet }] = useStyleSet();
2828
const focus = useFocus();
2929
const localize = useLocalizer();
3030
const postActivity = usePostActivity();
31+
const classNames = useStyles(styles);
3132

3233
const handleRetryClick = useCallback(() => {
3334
postActivity(activity);
@@ -40,7 +41,7 @@ function SendStatus(props: SendStatusProps) {
4041

4142
return (
4243
<React.Fragment>
43-
<span className={classNames('webchat__activity-status', 'webchat__activity-status--sending', sendStatusStyleSet)}>
44+
<span className={classNames['activity-status']}>
4445
{sendStatus === SENDING ? (
4546
sendingText
4647
) : sendStatus === SEND_FAILED ? (

packages/component/src/ActivityStatus/StatusSlot.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
import { useStyles } from '@msinternal/botframework-webchat-styles/react';
12
import React, { memo, ReactNode } from 'react';
2-
import classNames from 'classnames';
3+
import cx from 'classnames';
4+
5+
import styles from './ActivityStatus.module.css';
36

47
type Props = Readonly<{ className?: string; children?: ReactNode | undefined }>;
58

6-
const StatusSlot = ({ children, className }: Props) => (
7-
<span className={classNames('webchat__activity-status-slot', className)}>{children}</span>
8-
);
9+
const StatusSlot = ({ children, className }: Props) => {
10+
const classNames = useStyles(styles);
11+
12+
return <span className={cx(classNames['activity-status-slot'], className)}>{children}</span>;
13+
};
914

1015
StatusSlot.displayName = 'StatusSlot';
1116

packages/component/src/ActivityStatus/private/Originator.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import { validateProps } from '@msinternal/botframework-webchat-react-valibot';
2+
import { useStyles } from '@msinternal/botframework-webchat-styles/react';
23
import { type OrgSchemaProject } from 'botframework-webchat-core';
4+
import cx from 'classnames';
35
import React, { memo } from 'react';
46
import { custom, object, optional, pipe, readonly, safeParse, string, type InferInput } from 'valibot';
57

68
import useSanitizeHrefCallback from '../../hooks/internal/useSanitizeHrefCallback';
79

10+
import styles from '../ActivityStatus.module.css';
11+
812
const originatorPropsSchema = pipe(
913
object({
1014
// TODO: [P1] We should build this schema into `OrgSchemaProject` instead, or build a Schema.org query library.
@@ -33,6 +37,7 @@ const Originator = memo(function Originator(props: OriginatorProps) {
3337
} = validateProps(originatorPropsSchema, props);
3438

3539
const sanitizeHref = useSanitizeHrefCallback();
40+
const classNames = useStyles(styles);
3641

3742
const { sanitizedHref } = sanitizeHref(url);
3843
const text = slogan || name;
@@ -41,15 +46,15 @@ const Originator = memo(function Originator(props: OriginatorProps) {
4146
// Link is sanitized.
4247
// eslint-disable-next-line react/forbid-elements
4348
<a
44-
className="webchat__activity-status__originator webchat__activity-status__originator--has-link"
49+
className={cx(classNames['activity-status__originator'], classNames['activity-status__originator--has-link'])}
4550
href={sanitizedHref}
4651
rel="noopener noreferrer"
4752
target="_blank"
4853
>
4954
{text}
5055
</a>
5156
) : (
52-
<span className="webchat__activity-status__originator">{text}</span>
57+
<span className={classNames['activity-status__originator']}>{text}</span>
5358
);
5459
});
5560

packages/component/src/Middleware/ActivityStatus/createTimestampMiddleware.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ export default function createTimestampMiddleware(): ActivityStatusMiddleware {
2020
// If "hideTimestamp" is set, we will not render the visual timestamp. But continue to render the screen reader only version.
2121
return <AbsoluteTime hide={true} value={activity.timestamp} />;
2222
} else if (activity.from.role === 'bot') {
23-
return <OthersActivityStatus activity={activity} className={'webchat__activity-status--slotted'} />;
23+
return <OthersActivityStatus activity={activity} slotted={true} />;
2424
}
2525

26-
return <SelfActivityStatus activity={activity} className={'webchat__activity-status--slotted'} />;
26+
return <SelfActivityStatus activity={activity} slotted={true} />;
2727
};
2828
}

packages/fluent-theme/src/components/activity/PartGroupingDecorator.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@
746746
max-width: unset;
747747
}
748748

749-
:global(.webchat__activity-status) {
749+
:global(.activity-status) {
750750
margin: 0 0 var(--webchat-spacingHorizontalXXS);
751751
}
752752

0 commit comments

Comments
 (0)