feature/tauri-v2
svelte 163 lines 4.64 KB
Raw
1 <script lang="ts">
2 import { onMount } from "svelte";
3 import { closeToast } from "./notifications";
4 import { fade } from "svelte/transition";
5 import Info from "carbon-icons-svelte/lib/Information.svelte";
6 import Warning from "carbon-icons-svelte/lib/WarningAlt.svelte";
7 import Error from "carbon-icons-svelte/lib/CloseOutline.svelte";
8
9 export let id: number;
10 export let type = "";
11 export let title = "";
12 export let message = "";
13 export let actions = [];
14
15 let notification: HTMLElement | null;
16
17 onMount(() => {
18 let timer = setTimeout(() => {
19 notification.remove();
20 closeToast(id)
21 clearTimeout(timer);
22 }, 100000)
23 return () => {
24 clearTimeout(timer)
25 }
26 })
27 </script>
28
29 <div bind:this={notification} class="notification-toast" class:error={type === "Error"} class:warning={type === "Warning"} transition:fade={{ duration: 150 }}>
30 <div class="notification-info">
31 <div class="details">
32 <div class="icon">
33 {#if type === "Error"}
34 <Error />
35 {:else if type === "Warning"}
36 <Warning />
37 {:else}
38 <Info />
39 {/if}
40 </div>
41 <div class="title">{type}: {title}</div>
42 </div>
43 <!-- svelte-ignore a11y-click-events-have-key-events -->
44 <span class="close-button" on:click={() => {closeToast(id)}}></span>
45 </div>
46
47 <div class="message">{message}</div>
48
49 {#if actions.length > 0}
50 <div class="actions">
51 {#each actions as action}
52 <!-- svelte-ignore a11y-click-events-have-key-events -->
53 <div class="action-button" on:click={action.action}>{action.label}</div>
54 {/each}
55 </div>
56 {/if}
57 </div>
58
59 <style lang="scss">
60 $notification-height: 3rem;
61 $notification-border-width: 1px;
62 $error-color: #c02b2b;
63 $warning-color: #ffeb10;
64 .notification-toast {
65 display: flex;
66 min-height: $notification-height;
67 margin-bottom: 0.8rem;
68 position: relative;
69 flex-direction: column;
70 justify-content: center;
71 z-index: 10;
72 .icon {
73 display: flex;
74 align-items: center;
75 justify-content: center;
76 :global(svg) {
77 height: 22px;
78 width: 22px;
79 }
80 }
81 &.warning {
82 border-top: 3px solid $warning-color;
83 .icon {
84 color: $warning-color !important;
85 }
86 }
87 &.error {
88 border-top: 3px solid $error-color;
89 .icon {
90 color: $error-color !important;
91 }
92 }
93 &::before {
94 position: absolute;
95 height: 100%;
96 width: 100%;
97 border-width: 0 $notification-border-width $notification-border-width $notification-border-width;
98 border-style: solid;
99 box-sizing: border-box;
100 content: "";
101 }
102 .notification-info {
103 display: flex;
104 justify-content: space-between;
105 min-height: 3rem;
106 }
107 .details {
108 display: flex;
109 margin: 0 0.5rem;
110 position: relative;
111 top: -1px;
112 align-items: center;
113 .icon {
114 border-radius: 50%;
115 min-width: 20px;
116 min-height: 20px;
117 margin-right: 10px;
118 }
119 }
120 .message {
121 font-size: 15px;
122 color: #6d6d6d;
123 margin: 0.5rem 0;
124 margin-left: 2.4rem;
125 margin-top: -0.5rem;
126 }
127 .actions {
128 display: flex;
129 margin: 0 0.5rem;
130 position: relative;
131 top: -1px;
132 align-items: center;
133 margin-left: 2.4rem;
134 margin-bottom: 0.5rem;
135 .action-button {
136 display: flex;
137 justify-content: center;
138 align-items: center;
139 cursor: pointer;
140 &:nth-child(2) {
141 margin: 0 0.6rem;
142 }
143 &:hover {
144 text-decoration: underline;
145 }
146 }
147 }
148 .close-button {
149 font-size: 12px;
150 padding: 0 7px;
151 display: flex;
152 align-items: center;
153 justify-content: center;
154 border-radius: 3px;
155 margin: 0 0.5rem;
156 cursor: pointer;
157 &::before {
158 content: "\2715";
159 }
160 z-index: 10;
161 }
162 }
163 </style>