Skip to content

Commit 2c3ce82

Browse files
authored
feat: notice semantic (#318)
* feat: Notice support semantic props * test: add test case * chore: string key
1 parent fb157e9 commit 2c3ce82

File tree

3 files changed

+77
-15
lines changed

3 files changed

+77
-15
lines changed

src/NoticeList.tsx

+29-15
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@ const NoticeList: FC<NoticeListProps> = (props) => {
4545

4646
const { classNames: ctxCls } = useContext(NotificationContext);
4747

48-
const dictRef = useRef<Record<React.Key, HTMLDivElement>>({});
48+
const dictRef = useRef<Record<string, HTMLDivElement>>({});
4949
const [latestNotice, setLatestNotice] = useState<HTMLDivElement>(null);
50-
const [hoverKeys, setHoverKeys] = useState<React.Key[]>([]);
50+
const [hoverKeys, setHoverKeys] = useState<string[]>([]);
5151

5252
const keys = configList.map((config) => ({
5353
config,
54-
key: config.key,
54+
key: String(config.key),
5555
}));
5656

5757
const [stack, { offset, threshold, gap }] = useStack(stackConfig);
@@ -96,8 +96,15 @@ const NoticeList: FC<NoticeListProps> = (props) => {
9696
nodeRef,
9797
) => {
9898
const { key, times } = config as InnerOpenConfig;
99-
const { className: configClassName, style: configStyle } = config as NoticeConfig;
100-
const dataIndex = keys.findIndex((item) => item.key === key);
99+
const strKey = String(key);
100+
const {
101+
className: configClassName,
102+
style: configStyle,
103+
classNames: configClassNames,
104+
styles: configStyles,
105+
...restConfig
106+
} = config as NoticeConfig;
107+
const dataIndex = keys.findIndex((item) => item.key === strKey);
101108

102109
// If dataIndex is -1, that means this notice has been removed in data, but still in dom
103110
// Should minus (motionIndex - 1) to get the correct index because keys.length is not the same as dom length
@@ -107,7 +114,7 @@ const NoticeList: FC<NoticeListProps> = (props) => {
107114
const transformX = placement === 'top' || placement === 'bottom' ? '-50%' : '0';
108115
if (index > 0) {
109116
stackStyle.height = expanded
110-
? dictRef.current[key]?.offsetHeight
117+
? dictRef.current[strKey]?.offsetHeight
111118
: latestNotice?.offsetHeight;
112119

113120
// Transform
@@ -119,9 +126,9 @@ const NoticeList: FC<NoticeListProps> = (props) => {
119126
const transformY =
120127
(expanded ? verticalOffset : index * offset) * (placement.startsWith('top') ? 1 : -1);
121128
const scaleX =
122-
!expanded && latestNotice?.offsetWidth && dictRef.current[key]?.offsetWidth
129+
!expanded && latestNotice?.offsetWidth && dictRef.current[strKey]?.offsetWidth
123130
? (latestNotice?.offsetWidth - offset * 2 * (index < 3 ? index : 3)) /
124-
dictRef.current[key]?.offsetWidth
131+
dictRef.current[strKey]?.offsetWidth
125132
: 1;
126133
stackStyle.transform = `translate3d(${transformX}, ${transformY}px, 0) scaleX(${scaleX})`;
127134
} else {
@@ -132,28 +139,35 @@ const NoticeList: FC<NoticeListProps> = (props) => {
132139
return (
133140
<div
134141
ref={nodeRef}
135-
className={clsx(`${prefixCls}-notice-wrapper`, motionClassName)}
142+
className={clsx(
143+
`${prefixCls}-notice-wrapper`,
144+
motionClassName,
145+
configClassNames?.wrapper,
146+
)}
136147
style={{
137148
...motionStyle,
138149
...stackStyle,
139-
...configStyle,
150+
...configStyles?.wrapper,
140151
}}
141152
onMouseEnter={() =>
142-
setHoverKeys((prev) => (prev.includes(key) ? prev : [...prev, key]))
153+
setHoverKeys((prev) => (prev.includes(strKey) ? prev : [...prev, strKey]))
143154
}
144-
onMouseLeave={() => setHoverKeys((prev) => prev.filter((k) => k !== key))}
155+
onMouseLeave={() => setHoverKeys((prev) => prev.filter((k) => k !== strKey))}
145156
>
146157
<Notice
147-
{...config}
158+
{...restConfig}
148159
ref={(node) => {
149160
if (dataIndex > -1) {
150-
dictRef.current[key] = node;
161+
dictRef.current[strKey] = node;
151162
} else {
152-
delete dictRef.current[key];
163+
delete dictRef.current[strKey];
153164
}
154165
}}
155166
prefixCls={prefixCls}
167+
classNames={configClassNames}
168+
styles={configStyles}
156169
className={clsx(configClassName, ctxCls?.notice)}
170+
style={configStyle}
157171
times={times}
158172
key={key}
159173
eventKey={key}

src/interface.ts

+8
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@ import type React from 'react';
22

33
export type Placement = 'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight';
44

5+
type NoticeSemanticProps = 'wrapper';
6+
57
export interface NoticeConfig {
68
content?: React.ReactNode;
79
duration?: number | null;
810
closeIcon?: React.ReactNode;
911
closable?: boolean;
1012
className?: string;
1113
style?: React.CSSProperties;
14+
classNames?: {
15+
[key in NoticeSemanticProps]?: string;
16+
};
17+
styles?: {
18+
[key in NoticeSemanticProps]?: React.CSSProperties;
19+
};
1220
/** @private Internal usage. Do not override in your code */
1321
props?: React.HTMLAttributes<HTMLDivElement> & Record<string, any>;
1422

tests/index.test.tsx

+40
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,46 @@ describe('Notification.Basic', () => {
493493
});
494494
});
495495

496+
it('should open style and className work', () => {
497+
const { instance } = renderDemo();
498+
499+
act(() => {
500+
instance.open({
501+
style: {
502+
content: 'little',
503+
},
504+
className: 'bamboo',
505+
});
506+
});
507+
508+
expect(document.querySelector('.rc-notification-notice')).toHaveStyle({
509+
content: 'little',
510+
});
511+
expect(document.querySelector('.rc-notification-notice')).toHaveClass('bamboo');
512+
});
513+
514+
it('should open styles and classNames work', () => {
515+
const { instance } = renderDemo();
516+
517+
act(() => {
518+
instance.open({
519+
styles: {
520+
wrapper: {
521+
content: 'little',
522+
},
523+
},
524+
classNames: {
525+
wrapper: 'bamboo',
526+
},
527+
});
528+
});
529+
530+
expect(document.querySelector('.rc-notification-notice-wrapper')).toHaveStyle({
531+
content: 'little',
532+
});
533+
expect(document.querySelector('.rc-notification-notice-wrapper')).toHaveClass('bamboo');
534+
});
535+
496536
it('should className work', () => {
497537
const { instance } = renderDemo({
498538
className: (placement) => `bamboo-${placement}`,

0 commit comments

Comments
 (0)