commit
672a662ab8
@ -0,0 +1,4 @@ |
|||||||
|
{ |
||||||
|
"presets": ["@nrwl/react/babel"], |
||||||
|
"plugins": [] |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
{ |
||||||
|
"env": { |
||||||
|
"browser": true, |
||||||
|
"es6": true |
||||||
|
}, |
||||||
|
"extends": "../../../.eslintrc", |
||||||
|
"globals": { |
||||||
|
"Atomics": "readonly", |
||||||
|
"SharedArrayBuffer": "readonly" |
||||||
|
}, |
||||||
|
"parserOptions": { |
||||||
|
"ecmaVersion": 11, |
||||||
|
"sourceType": "module" |
||||||
|
}, |
||||||
|
"rules": { |
||||||
|
"standard/no-callback-literal": "off" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
# remix-ui-toaster |
||||||
|
|
||||||
|
This library was generated with [Nx](https://nx.dev). |
||||||
|
|
||||||
|
## Running unit tests |
||||||
|
|
||||||
|
Run `nx test remix-ui-toaster` to execute the unit tests via [Jest](https://jestjs.io). |
@ -0,0 +1 @@ |
|||||||
|
export * from './lib/toaster' |
@ -0,0 +1,43 @@ |
|||||||
|
.remixui_tooltip { |
||||||
|
z-index: 1001; |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
position: fixed; |
||||||
|
min-height: 50px; |
||||||
|
padding: 16px 24px 12px; |
||||||
|
border-radius: 3px; |
||||||
|
left: 40%; |
||||||
|
font-size: 14px; |
||||||
|
text-align: center; |
||||||
|
bottom: -0px; |
||||||
|
flex-direction: row; |
||||||
|
} |
||||||
|
@-webkit-keyframes remixui_animatebottom { |
||||||
|
0% {bottom: -300px} |
||||||
|
100% {bottom: 0px} |
||||||
|
} |
||||||
|
@keyframes remixui_animatebottom { |
||||||
|
0% {bottom: -300px} |
||||||
|
100% {bottom: 0px} |
||||||
|
} |
||||||
|
@-webkit-keyframes remixui_animatetop { |
||||||
|
0% {bottom: 0px} |
||||||
|
100% {bottom: -300px} |
||||||
|
} |
||||||
|
@keyframes remixui_animatetop { |
||||||
|
0% {bottom: 0px} |
||||||
|
100% {bottom: -300px} |
||||||
|
} |
||||||
|
.remixui_animateTop { |
||||||
|
-webkit-animation-name: remixui_animatetop; |
||||||
|
-webkit-animation-duration: 2s; |
||||||
|
animation-name: remixui_animatetop; |
||||||
|
animation-duration: 2s; |
||||||
|
} |
||||||
|
.remixui_animateBottom { |
||||||
|
-webkit-animation-name: remixui_animatebottom; |
||||||
|
-webkit-animation-duration: 2s; |
||||||
|
animation-name: remixui_animatebottom; |
||||||
|
animation-duration: 2s; |
||||||
|
} |
@ -0,0 +1,108 @@ |
|||||||
|
import React, { useEffect, useState } from 'react' // eslint-disable-line
|
||||||
|
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
|
||||||
|
|
||||||
|
import './toaster.css' |
||||||
|
|
||||||
|
/* eslint-disable-next-line */ |
||||||
|
export interface ToasterProps { |
||||||
|
message: string |
||||||
|
timeOut?: number |
||||||
|
} |
||||||
|
|
||||||
|
export const Toaster = (props: ToasterProps) => { |
||||||
|
const [state, setState] = useState({ |
||||||
|
message: '', |
||||||
|
hide: true, |
||||||
|
hiding: false, |
||||||
|
timeOutId: null, |
||||||
|
timeOut: props.timeOut || 7000, |
||||||
|
showModal: false |
||||||
|
}) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (props.message) { |
||||||
|
const timeOutId = setTimeout(() => { |
||||||
|
setState(prevState => { |
||||||
|
return { ...prevState, hiding: true } |
||||||
|
}) |
||||||
|
}, state.timeOut) |
||||||
|
|
||||||
|
setState(prevState => { |
||||||
|
const shortTooltipText = props.message.length > 201 ? props.message.substring(0, 200) + '...' : props.message |
||||||
|
|
||||||
|
return { ...prevState, hide: false, hiding: false, timeOutId, message: shortTooltipText } |
||||||
|
}) |
||||||
|
} |
||||||
|
}, [props.message]) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (state.hiding) { |
||||||
|
setTimeout(() => { |
||||||
|
closeTheToaster() |
||||||
|
}, 1800) |
||||||
|
} |
||||||
|
}, [state.hiding]) |
||||||
|
|
||||||
|
const showFullMessage = () => { |
||||||
|
setState(prevState => { |
||||||
|
return { ...prevState, showModal: true } |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const hideFullMessage = () => { //eslint-disable-line
|
||||||
|
setState(prevState => { |
||||||
|
return { ...prevState, showModal: false } |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const closeTheToaster = () => { |
||||||
|
if (state.timeOutId) { |
||||||
|
clearTimeout(state.timeOutId) |
||||||
|
} |
||||||
|
setState(prevState => { |
||||||
|
return { ...prevState, message: '', hide: true, hiding: false, timeOutId: null, showModal: false } |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const handleMouseEnter = () => { |
||||||
|
if (state.timeOutId) { |
||||||
|
clearTimeout(state.timeOutId) |
||||||
|
} |
||||||
|
setState(prevState => { |
||||||
|
return { ...prevState, timeOutId: null } |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const handleMouseLeave = () => { |
||||||
|
if (!state.timeOutId) { |
||||||
|
const timeOutId = setTimeout(() => { |
||||||
|
setState(prevState => { |
||||||
|
return { ...prevState, hiding: true } |
||||||
|
}) |
||||||
|
}, state.timeOut) |
||||||
|
|
||||||
|
setState(prevState => { |
||||||
|
return { ...prevState, timeOutId } |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
{/* <ModalDialog /> */} |
||||||
|
{ !state.hide && |
||||||
|
<div data-shared="tooltipPopup" className={`remixui_tooltip alert alert-info p-2 ${state.hiding ? 'remixui_animateTop' : 'remixui_animateBottom'}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}> |
||||||
|
<span className="px-2"> |
||||||
|
{ state.message } |
||||||
|
{ (props.message.length > 201) && <button className="btn btn-secondary btn-sm mx-3" style={{ whiteSpace: 'nowrap' }} onClick={showFullMessage}>Show full message</button> } |
||||||
|
</span> |
||||||
|
<span style={{ alignSelf: 'baseline' }}> |
||||||
|
<button data-id="tooltipCloseButton" className="fas fa-times btn-info mx-1 p-0" onClick={closeTheToaster}></button> |
||||||
|
</span> |
||||||
|
</div> |
||||||
|
} |
||||||
|
</> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Toaster |
@ -0,0 +1,16 @@ |
|||||||
|
{ |
||||||
|
"extends": "../../../tsconfig.json", |
||||||
|
"compilerOptions": { |
||||||
|
"jsx": "react", |
||||||
|
"allowJs": true, |
||||||
|
"esModuleInterop": true, |
||||||
|
"allowSyntheticDefaultImports": true |
||||||
|
}, |
||||||
|
"files": [], |
||||||
|
"include": [], |
||||||
|
"references": [ |
||||||
|
{ |
||||||
|
"path": "./tsconfig.lib.json" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
{ |
||||||
|
"extends": "./tsconfig.json", |
||||||
|
"compilerOptions": { |
||||||
|
"outDir": "../../../dist/out-tsc", |
||||||
|
"types": ["node"] |
||||||
|
}, |
||||||
|
"files": [ |
||||||
|
"../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", |
||||||
|
"../../../node_modules/@nrwl/react/typings/image.d.ts" |
||||||
|
], |
||||||
|
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"], |
||||||
|
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] |
||||||
|
} |
Loading…
Reference in new issue