|
@@ -45,10 +45,14 @@ const createBaseToast = () => class ToastList extends BaseComponent<ToastListPro
|
|
onClose: PropTypes.func,
|
|
onClose: PropTypes.func,
|
|
icon: PropTypes.node,
|
|
icon: PropTypes.node,
|
|
direction: PropTypes.oneOf(strings.directions),
|
|
direction: PropTypes.oneOf(strings.directions),
|
|
|
|
+ stack: PropTypes.bool,
|
|
};
|
|
};
|
|
|
|
|
|
static defaultProps = {};
|
|
static defaultProps = {};
|
|
static wrapperId: null | string;
|
|
static wrapperId: null | string;
|
|
|
|
+ stack: boolean = false;
|
|
|
|
+
|
|
|
|
+ innerWrapperRef: React.RefObject<HTMLDivElement> = React.createRef();
|
|
|
|
|
|
constructor(props: ToastListProps) {
|
|
constructor(props: ToastListProps) {
|
|
super(props);
|
|
super(props);
|
|
@@ -56,6 +60,7 @@ const createBaseToast = () => class ToastList extends BaseComponent<ToastListPro
|
|
list: [],
|
|
list: [],
|
|
removedItems: [],
|
|
removedItems: [],
|
|
updatedItems: [],
|
|
updatedItems: [],
|
|
|
|
+ mouseInSide: false
|
|
};
|
|
};
|
|
this.foundation = new ToastListFoundation(this.adapter);
|
|
this.foundation = new ToastListFoundation(this.adapter);
|
|
}
|
|
}
|
|
@@ -66,9 +71,30 @@ const createBaseToast = () => class ToastList extends BaseComponent<ToastListPro
|
|
updateToast: (list: ToastInstance[], removedItems: ToastInstance[], updatedItems: ToastInstance[]) => {
|
|
updateToast: (list: ToastInstance[], removedItems: ToastInstance[], updatedItems: ToastInstance[]) => {
|
|
this.setState({ list, removedItems, updatedItems });
|
|
this.setState({ list, removedItems, updatedItems });
|
|
},
|
|
},
|
|
|
|
+ handleMouseInSideChange: (mouseInSide: boolean) => {
|
|
|
|
+ this.setState({ mouseInSide });
|
|
|
|
+ },
|
|
|
|
+ getInputWrapperRect: () => {
|
|
|
|
+ return this.innerWrapperRef.current?.getBoundingClientRect();
|
|
|
|
+ }
|
|
};
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ handleMouseEnter = (e: React.MouseEvent) => {
|
|
|
|
+ if (this.stack) {
|
|
|
|
+ this.foundation.handleMouseInSideChange(true);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ handleMouseLeave = (e: React.MouseEvent) => {
|
|
|
|
+ if (this.stack) {
|
|
|
|
+ const height = this.foundation.getInputWrapperRect()?.height;
|
|
|
|
+ if (height) {
|
|
|
|
+ this.foundation.handleMouseInSideChange(false);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
static create(opts: ToastReactProps) {
|
|
static create(opts: ToastReactProps) {
|
|
const id = opts.id ?? getUuid('toast');
|
|
const id = opts.id ?? getUuid('toast');
|
|
// this.id = id;
|
|
// this.id = id;
|
|
@@ -94,13 +120,14 @@ const createBaseToast = () => class ToastList extends BaseComponent<ToastListPro
|
|
} else {
|
|
} else {
|
|
document.body.appendChild(div);
|
|
document.body.appendChild(div);
|
|
}
|
|
}
|
|
- ReactDOM.render(React.createElement(
|
|
|
|
|
|
+ ReactDOM.render(React.createElement(
|
|
ToastList,
|
|
ToastList,
|
|
{ ref: instance => (ToastList.ref = instance) }
|
|
{ ref: instance => (ToastList.ref = instance) }
|
|
),
|
|
),
|
|
div,
|
|
div,
|
|
() => {
|
|
() => {
|
|
ToastList.ref.add({ ...opts, id });
|
|
ToastList.ref.add({ ...opts, id });
|
|
|
|
+ ToastList.ref.stack = Boolean(opts.stack);
|
|
});
|
|
});
|
|
} else {
|
|
} else {
|
|
const node = document.querySelector(`#${this.wrapperId}`) as HTMLElement;
|
|
const node = document.querySelector(`#${this.wrapperId}`) as HTMLElement;
|
|
@@ -109,6 +136,9 @@ const createBaseToast = () => class ToastList extends BaseComponent<ToastListPro
|
|
node.style[pos] = typeof opts[pos] === 'number' ? `${opts[pos]}px` : opts[pos];
|
|
node.style[pos] = typeof opts[pos] === 'number' ? `${opts[pos]}px` : opts[pos];
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
+ if (Boolean(opts.stack) !== ToastList.ref.stack) {
|
|
|
|
+ ToastList.ref.stack = Boolean(opts.stack);
|
|
|
|
+ }
|
|
if (ToastList.ref.has(id)) {
|
|
if (ToastList.ref.has(id)) {
|
|
ToastList.ref.update(id, { ...opts, id });
|
|
ToastList.ref.update(id, { ...opts, id });
|
|
} else {
|
|
} else {
|
|
@@ -218,20 +248,25 @@ const createBaseToast = () => class ToastList extends BaseComponent<ToastListPro
|
|
|
|
|
|
return (
|
|
return (
|
|
<React.Fragment>
|
|
<React.Fragment>
|
|
- {list.map((item, index) =>{
|
|
|
|
- const isRemoved = removedItems.find(removedItem=>removedItem.id===item.id) !== undefined;
|
|
|
|
- return <CSSAnimation key={item.id} motion={item.motion} animationState={isRemoved?"leave":"enter"} startClassName={isRemoved?`${cssClasses.PREFIX}-animation-hide`:`${cssClasses.PREFIX}-animation-show`}>
|
|
|
|
- {
|
|
|
|
- ({ animationClassName, animationEventsNeedBind, isAnimating })=>{
|
|
|
|
- return (isRemoved && !isAnimating) ? null : <Toast {...item} className={cls({
|
|
|
|
- [item.className]: Boolean(item.className),
|
|
|
|
- [animationClassName]: true
|
|
|
|
- })} {...animationEventsNeedBind} style={{ ...item.style }} close={id => this.remove(id)} ref={refFn} />;
|
|
|
|
|
|
+ <div className={cls({
|
|
|
|
+ [`${cssClasses.PREFIX}-innerWrapper`]: true,
|
|
|
|
+ [`${cssClasses.PREFIX}-innerWrapper-hover`]: this.state.mouseInSide
|
|
|
|
+ })} ref={this.innerWrapperRef} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
|
|
|
|
+ {list.map((item, index) =>{
|
|
|
|
+ const isRemoved = removedItems.find(removedItem=>removedItem.id===item.id) !== undefined;
|
|
|
|
+ return <CSSAnimation key={item.id} motion={item.motion} animationState={isRemoved?"leave":"enter"} startClassName={isRemoved?`${cssClasses.PREFIX}-animation-hide`:`${cssClasses.PREFIX}-animation-show`}>
|
|
|
|
+ {
|
|
|
|
+ ({ animationClassName, animationEventsNeedBind, isAnimating })=>{
|
|
|
|
+ return (isRemoved && !isAnimating) ? null : <Toast {...item} stack={this.stack} stackExpanded={this.state.mouseInSide} positionInList={{ length: list.length, index }} className={cls({
|
|
|
|
+ [item.className]: Boolean(item.className),
|
|
|
|
+ [animationClassName]: true
|
|
|
|
+ })} {...animationEventsNeedBind} style={{ ...item.style }} close={id => this.remove(id)} ref={refFn} />;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- }
|
|
|
|
- </CSSAnimation>;
|
|
|
|
- }
|
|
|
|
- )}
|
|
|
|
|
|
+ </CSSAnimation>;
|
|
|
|
+ }
|
|
|
|
+ )}
|
|
|
|
+ </div>
|
|
</React.Fragment>
|
|
</React.Fragment>
|
|
);
|
|
);
|
|
}
|
|
}
|