Skip to content

Commit

Permalink
feat(bubble): add typing suffix support
Browse files Browse the repository at this point in the history
- Add suffix option to typing configuration
- Display suffix while typing is in progress
- Update demo and tests to showcase typing suffix feature
- Set default suffix to empty string
- Add type assertions in test utils to pass lint check
  • Loading branch information
BQXBQX committed Dec 5, 2024
1 parent 0cafa79 commit 5e8c881
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 12 deletions.
9 changes: 7 additions & 2 deletions components/bubble/Bubble.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const Bubble: React.ForwardRefRenderFunction<BubbleRef, BubbleProps> = (props, r
const contextConfig = useXComponentConfig('bubble');

// ============================ Typing ============================
const [typingEnabled, typingStep, typingInterval] = useTypingConfig(typing);
const [typingEnabled, typingStep, typingInterval, typingSuffix] = useTypingConfig(typing);

const [typedContent, isTyping] = useTypedEffect(
content,
Expand Down Expand Up @@ -116,7 +116,12 @@ const Bubble: React.ForwardRefRenderFunction<BubbleRef, BubbleProps> = (props, r
if (loading) {
contentNode = loadingRender ? loadingRender() : <Loading prefixCls={prefixCls} />;
} else {
contentNode = mergedContent as React.ReactNode;
contentNode = (
<>
{mergedContent as React.ReactNode}
{isTyping && typingSuffix}
</>
);
}

let fullContent: React.ReactNode = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1308,7 +1308,7 @@ exports[`renders components/bubble/demo/typing.tsx extend context correctly 1`]
<div
class="ant-bubble-content ant-bubble-content-filled"
>
A
A💗
</div>
</div>
<button
Expand Down
2 changes: 2 additions & 0 deletions components/bubble/__tests__/__snapshots__/demo.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,8 @@ exports[`renders components/bubble/demo/typing.tsx correctly 1`] = `
class="ant-bubble-content ant-bubble-content-filled"
>
A
<!-- -->
💗
</div>
</div>
<button
Expand Down
4 changes: 2 additions & 2 deletions components/bubble/demo/typing.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { UserOutlined } from '@ant-design/icons';
import { Bubble } from '@ant-design/x';
import { Button, Flex } from 'antd';
import React from 'react';

const text = 'Ant Design X love you! ';

Expand All @@ -12,7 +12,7 @@ const App = () => {
<Flex vertical gap="small">
<Bubble
content={text.repeat(repeat)}
typing={{ step: 2, interval: 50 }}
typing={{ step: 2, interval: 50, suffix: <>💗</> }}
avatar={{ icon: <UserOutlined /> }}
/>

Expand Down
10 changes: 7 additions & 3 deletions components/bubble/hooks/useTypingConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@ import * as React from 'react';
import type { BubbleProps, TypingOption } from '../interface';

function useTypingConfig(typing: BubbleProps['typing']) {
return React.useMemo<[enableTyping: boolean, step: number, interval: number]>(() => {
return React.useMemo<
[enableTyping: boolean, step: number, interval: number, suffix: React.ReactNode]
>(() => {
if (!typing) {
return [false, 0, 0];
return [false, 0, 0, null];
}

let baseConfig: Required<TypingOption> = {
step: 1,
interval: 50,
// set default suffix is empty
suffix: '',
};

if (typeof typing === 'object') {
baseConfig = { ...baseConfig, ...typing };
}

return [true, baseConfig.step, baseConfig.interval];
return [true, baseConfig.step, baseConfig.interval, baseConfig.suffix];
}, [typing]);
}

Expand Down
4 changes: 4 additions & 0 deletions components/bubble/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export interface TypingOption {
* @default 50
*/
interval?: number;
/**
* @default ""
*/
suffix?: React.ReactNode;
}

type SemanticType = 'avatar' | 'content' | 'header' | 'footer';
Expand Down
8 changes: 4 additions & 4 deletions tests/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { ReactElement } from 'react';
import React, { createRef, StrictMode } from 'react';
import type { RenderOptions } from '@testing-library/react';
import type { RenderOptions, RenderResult } from '@testing-library/react';
import { act, render } from '@testing-library/react';
import MockDate from 'mockdate';
import { _rs as onEsResize } from 'rc-resize-observer/es/utils/observerUtil';
import { _rs as onLibResize } from 'rc-resize-observer/lib/utils/observerUtil';
import type { ReactElement } from 'react';
import React, { createRef, StrictMode } from 'react';

export function assertsExist<T>(item?: T): asserts item is T {
expect(item).not.toBeUndefined();
Expand All @@ -29,7 +29,7 @@ export const sleep = async (timeout = 0) => {
});
};

const customRender = (ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>) =>
const customRender = (ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>): RenderResult =>
render(ui, { wrapper: StrictMode, ...options });

export function renderHook<T>(func: () => T): { result: React.RefObject<T> } {
Expand Down

0 comments on commit 5e8c881

Please sign in to comment.