11/**
2- * @typedef Alert
3- * @type {object }
4- * @property {string } value
5- * @property {string } color
6- * @property {string } label
7- *
82 * @typedef Properties
93 * @type {object }
104 * @property {string? } icon
11- * @property {'info'|'success'|'error' } type
12- * @property {string? } message
5+ * @property {number? } timeout
6+ * @property {boolean? } closeable
7+ * @property {'info'|'success'|'warn'|'error' } type
138 */
149import van from '../van.min.js' ;
15- import { getValue , loadStylesheet } from '../utils.js' ;
10+ import { getValue , loadStylesheet , getRandomId } from '../utils.js' ;
1611import { Icon } from './icon.js' ;
12+ import { Button } from './button.js' ;
1713
1814const { div } = van . tags ;
1915const alertTypeColors = {
2016 info : { backgroundColor : 'rgba(28, 131, 225, 0.1)' , color : 'rgb(0, 66, 128)' } ,
2117 success : { backgroundColor : 'rgba(33, 195, 84, 0.1)' , color : 'rgb(23, 114, 51)' } ,
18+ warn : { backgroundColor : 'rgba(255, 227, 18, 0.2)' , color : 'rgb(255, 255, 194)' } ,
2219 error : { backgroundColor : 'rgba(255, 43, 43, 0.09)' , color : 'rgb(125, 53, 59)' } ,
2320} ;
2421
2522const Alert = ( /** @type Properties */ props , /** @type Array<HTMLElement> */ ...children ) => {
2623 loadStylesheet ( 'alert' , stylesheet ) ;
2724
25+ const elementId = getValue ( props . id ) ?? 'tg-alert-' + getRandomId ( ) ;
26+ const close = ( ) => {
27+ document . getElementById ( elementId ) ?. remove ( ) ;
28+ } ;
29+ const timeout = getValue ( props . timeout ) ;
30+ if ( timeout && timeout > 0 ) {
31+ setTimeout ( close , timeout ) ;
32+ }
33+
2834 return div (
2935 {
3036 ...props ,
31- class : ( ) => ( getValue ( props . class ) ?? '' ) + ` tg-alert flex-row` ,
32- style : ( ) => {
33- const colors = alertTypeColors [ getValue ( props . type ) ] ;
34- return `color: ${ colors . color } ; background-color: ${ colors . backgroundColor } ;` ;
35- } ,
37+ id : elementId ,
38+ class : ( ) => `tg-alert flex-row ${ getValue ( props . class ) ?? '' } tg-alert-${ getValue ( props . type ) } ` ,
3639 role : 'alert' ,
3740 } ,
3841 ( ) => {
@@ -43,6 +46,19 @@ const Alert = (/** @type Properties */ props, /** @type Array<HTMLElement> */ ..
4346 { class : 'flex-column' } ,
4447 ...children ,
4548 ) ,
49+ ( ) => {
50+ const isCloseable = getValue ( props . closeable ) ?? false ;
51+ if ( ! isCloseable ) {
52+ return '' ;
53+ }
54+
55+ const colors = alertTypeColors [ getValue ( props . type ) ] ;
56+ return Button ( {
57+ type : 'icon' ,
58+ icon : 'close' ,
59+ style : `margin-left: auto; color: ${ colors . color } ;` ,
60+ } ) ;
61+ } ,
4662 ) ;
4763} ;
4864
@@ -54,6 +70,34 @@ stylesheet.replace(`
5470 font-size: 16px;
5571 line-height: 24px;
5672}
73+
74+ .tg-alert-info {
75+ background-color: rgba(28, 131, 225, 0.1);
76+ color: rgb(0, 66, 128);
77+ }
78+
79+ .tg-alert-success {
80+ background-color: rgba(33, 195, 84, 0.1);
81+ color: rgb(23, 114, 51);
82+ }
83+
84+ .tg-alert-error {
85+ background-color: rgba(255, 43, 43, 0.09);
86+ color: rgb(125, 53, 59);
87+ }
88+
89+ .tg-alert-warn {
90+ background-color: rgba(255, 227, 18, 0.1);
91+ color: rgb(146, 108, 5);
92+ }
93+
94+ @media (prefers-color-scheme: dark) {
95+ .tg-alert-warn {
96+ background-color: rgba(255, 227, 18, 0.2);
97+ color: rgb(255, 255, 194);
98+ }
99+ }
100+
57101.tg-alert > .tg-icon {
58102 color: inherit !important;
59103}
0 commit comments