@sierra-95/svelte-scaffold 1.0.81 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/Core/components/Form/Button/Flip/button.svelte +1 -52
  2. package/dist/Core/components/Form/Button/Flip/button.svelte.d.ts +1 -0
  3. package/dist/Core/components/Form/Button/Swipe/button.svelte +2 -34
  4. package/dist/Core/components/Form/Button/Swipe/button.svelte.d.ts +1 -0
  5. package/dist/Core/components/Form/Input/FileInput/fileInput.svelte +11 -9
  6. package/dist/Core/components/others/Previews/Audio/audio.svelte +5 -2
  7. package/dist/Core/components/others/Progress/LinearProgress/LinearProgress.svelte +4 -77
  8. package/dist/Core/features/ToastManager/toastManager.svelte +56 -0
  9. package/dist/Core/features/ToastManager/toastManager.svelte.d.ts +3 -0
  10. package/dist/Hooks/layout_menu.js +11 -3
  11. package/dist/Modules/Editor/Hooks/extractContent.js +5 -2
  12. package/dist/Modules/Editor/Nodes/Images/images.svelte +10 -3
  13. package/dist/Modules/Editor/export.svelte +12 -3
  14. package/dist/Modules/FilePicker/ActionsMenu/delete_media.svelte +13 -4
  15. package/dist/Modules/FilePicker/ActionsMenu/download_media.svelte +13 -4
  16. package/dist/Modules/FilePicker/ActionsMenu/media_storage.svelte +11 -3
  17. package/dist/Modules/FilePicker/Cloud/cloudStore.svelte +9 -3
  18. package/dist/Modules/FilePicker/main.svelte +15 -4
  19. package/dist/Modules/Layout/main.svelte +2 -2
  20. package/dist/index.d.ts +5 -6
  21. package/dist/index.js +5 -7
  22. package/dist/stores/features/toastManager.d.ts +21 -0
  23. package/dist/stores/features/toastManager.js +67 -0
  24. package/package.json +3 -2
  25. package/dist/Core/components/Alerts/Toast/toast.css +0 -39
  26. package/dist/Core/components/Alerts/Toast/toast.svelte +0 -32
  27. package/dist/Core/components/Alerts/Toast/toast.svelte.d.ts +0 -26
  28. package/dist/Core/components/Alerts/site-under-maintenance/site-under-maintenance.svelte +0 -34
  29. package/dist/Core/components/Alerts/site-under-maintenance/site-under-maintenance.svelte.d.ts +0 -11
  30. /package/dist/Core/components/{Alerts → others}/Backdrop/backdrop.svelte +0 -0
  31. /package/dist/Core/components/{Alerts → others}/Backdrop/backdrop.svelte.d.ts +0 -0
  32. /package/dist/Core/components/{Alerts → others}/Modal/modal.svelte +0 -0
  33. /package/dist/Core/components/{Alerts → others}/Modal/modal.svelte.d.ts +0 -0
  34. /package/dist/Core/components/{Alerts → others}/Wrapper/wrapper.svelte +0 -0
  35. /package/dist/Core/components/{Alerts → others}/Wrapper/wrapper.svelte.d.ts +0 -0
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import './button.css';
2
3
  type _buttonType = 'button' | 'submit' | 'reset';
3
4
  const {
4
5
  back = "back",
@@ -25,55 +26,3 @@
25
26
  rest.onclick?.(e);
26
27
  }}
27
28
  ></button>
28
- <style>.btn-flip {
29
- position: relative;
30
- display: inline-block;
31
- width: 150px; /* you can fix width if needed */
32
- height: 40px;
33
- text-align: center;
34
- perspective: 1000px;
35
- color: var(--text-color);
36
- }
37
-
38
- .btn-flip::before,
39
- .btn-flip::after {
40
- content: attr(data-front);
41
- position: absolute;
42
- top: 0;
43
- left: 0;
44
- width: 100%;
45
- height: 100%;
46
- display: flex;
47
- align-items: center;
48
- justify-content: center;
49
- padding: 0 30px;
50
- line-height: 40px;
51
- transition: 0.5s;
52
- backface-visibility: hidden;
53
- box-sizing: border-box;
54
- }
55
-
56
- .btn-flip::before {
57
- content: attr(data-front);
58
- background: var(--bg-front);
59
- transform: translateY(0) rotateX(0);
60
- opacity: 1;
61
- }
62
-
63
- .btn-flip::after {
64
- content: attr(data-back);
65
- background: var(--bg-back);
66
- transform: translateY(-50%) rotateX(90deg);
67
- opacity: 0;
68
- }
69
-
70
- .btn-flip:hover::before {
71
- opacity: 0;
72
- transform: translateY(50%) rotateX(90deg);
73
- }
74
-
75
- .btn-flip:hover::after {
76
- opacity: 1;
77
- transform: translateY(0) rotateX(0);
78
- }
79
- </style>
@@ -1,3 +1,4 @@
1
+ import './button.css';
1
2
  declare const Button: import("svelte").Component<{
2
3
  back?: string;
3
4
  front?: string;
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import './button.css';
2
3
  import {buttonRipple} from '../../../../../index.js'
3
4
 
4
5
  type _buttonType = 'button' | 'submit' | 'reset';
@@ -22,37 +23,4 @@
22
23
  onclick={(e: MouseEvent) => {
23
24
  rest.onclick?.(e);
24
25
  }}
25
- >{text}</button>
26
- <style>.swipe-btn {
27
- position: relative;
28
- display: block;
29
- width:130px;
30
- height: 30px;
31
- line-height: 27px;
32
- text-align: center;
33
- border: 1px solid var(--btn-color);
34
- border-radius: 50px;
35
- overflow: hidden;
36
- cursor: pointer;
37
- z-index: 0;
38
- color: var(--text-color);
39
- transition: color 0.4s ease;
40
- }
41
- /* Swipe layer */
42
- .swipe-btn::before {
43
- content: '';
44
- position: absolute;
45
- top: 0; left: 0; bottom: 0; right: 0;
46
- background-color: var(--btn-color);
47
- transform: translateX(-100%);
48
- transition: transform 0.4s ease;
49
- z-index: -1;
50
- }
51
- /* Hover triggers swipe */
52
- .swipe-btn:hover::before {
53
- transform: translateX(0);
54
- }
55
- .swipe-btn:hover {
56
- color: var(--button-text);
57
- }
58
- </style>
26
+ >{text}</button>
@@ -1,3 +1,4 @@
1
+ import './button.css';
1
2
  declare const Button: import("svelte").Component<{
2
3
  text?: string;
3
4
  bg?: string;
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { onDestroy } from 'svelte';
3
- import {fileInputStore, Button, setToastMessage, DOCUMENT_MIME_TYPES} from '../../../../../index.js'
3
+ import {fileInputStore, Button, DOCUMENT_MIME_TYPES, addToast} from '../../../../../index.js'
4
4
  import Preview from './preview.svelte';
5
5
 
6
6
  const {
@@ -44,18 +44,20 @@
44
44
 
45
45
  for (const file of files) {
46
46
  if (!isAllowedType(file)) {
47
- setToastMessage(
48
- 'error',
49
- `"${file.name}" is not an allowed file type. Allowed types: ${allowedTypes()}`
50
- );
47
+ addToast({
48
+ status: 'error',
49
+ message: `"${file.name}" is not an allowed file type. Allowed types: ${allowedTypes()}`,
50
+ priority: 'high'
51
+ })
51
52
  continue; // skip invalid
52
53
  }
53
54
 
54
55
  if (file.size > $fileInputStore.sizeConstraint) {
55
- setToastMessage(
56
- 'error',
57
- `"${file.name}" exceeds the allowed file size`
58
- );
56
+ addToast({
57
+ status: 'error',
58
+ message: `"${file.name}" exceeds the allowed file size`,
59
+ priority: 'high'
60
+ });
59
61
  continue; // skip oversized
60
62
  }
61
63
  validFiles.push(file);
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import {setToastMessage,ButtonTimes, fileInputStore, ButtonSelect, removeFileForMedia, toggleSelectForMedia} from '../../../../../index.js'
2
+ import {ButtonTimes, fileInputStore, ButtonSelect, removeFileForMedia, toggleSelectForMedia, addToast} from '../../../../../index.js'
3
3
  export let media;
4
4
  export let buttonTimes = false;
5
5
  export let urlsOnly = true;
@@ -8,7 +8,10 @@
8
8
  let audioRefs: Record<string, HTMLAudioElement> = {};
9
9
  function togglePlay(id: string) {
10
10
  if(!urlsOnly){
11
- setToastMessage('warning', 'Audio preview is disabled for local files.');
11
+ addToast({
12
+ status: 'warning',
13
+ message: 'Audio preview is disabled for local files.'
14
+ });
12
15
  return;
13
16
  }
14
17
  const audio = audioRefs[id];
@@ -1,86 +1,13 @@
1
1
  <script>
2
+ import './LinearProgress.css';
2
3
  const {
3
4
  color = 'var(--primary-bg)',
4
5
  } = $props();
5
6
  </script>
6
- <style>.pure-material-progress-linear {
7
- -webkit-appearance: none;
8
- -moz-appearance: none;
9
- appearance: none;
10
- border: none;
11
- height: 0.25em;
12
- background-color: rgba( 33, 150, 243, 0.12);
13
- font-size: 16px;
14
- }
15
7
 
16
- .pure-material-progress-linear::-webkit-progress-bar {
17
- background-color: transparent;
18
- }
19
-
20
- /* Determinate */
21
-
22
- .pure-material-progress-linear::-webkit-progress-value {
23
- background-color: currentColor;
24
- transition: all 0.2s;
25
- }
26
-
27
- .pure-material-progress-linear::-moz-progress-bar {
28
- background-color: currentColor;
29
- transition: all 0.2s;
30
- }
31
-
32
- .pure-material-progress-linear::-ms-fill {
33
- border: none;
34
- background-color: currentColor;
35
- transition: all 0.2s;
36
- }
37
-
38
- /* Indeterminate */
39
-
40
- .pure-material-progress-linear:indeterminate {
41
- background-size: 200% 100%;
42
- background-image: linear-gradient(to right, transparent 50%, currentColor 50%, currentColor 60%, transparent 60%, transparent 71.5%, currentColor 71.5%, currentColor 84%, transparent 84%);
43
- animation: pure-material-progress-linear 2s infinite linear;
44
- }
45
-
46
- .pure-material-progress-linear:indeterminate::-moz-progress-bar {
47
- background-color: transparent;
48
- }
49
-
50
- .pure-material-progress-linear:indeterminate::-ms-fill {
51
- animation-name: none;
52
- }
53
-
54
- @keyframes pure-material-progress-linear {
55
- 0% {
56
- background-size: 200% 100%;
57
- background-position: left -31.25% top 0%;
58
- }
59
- 50% {
60
- background-size: 800% 100%;
61
- background-position: left -49% top 0%;
62
- }
63
- 100% {
64
- background-size: 400% 100%;
65
- background-position: left -102% top 0%;
66
- }
67
- }
68
-
69
- .cover{
70
- position: relative;
71
- height: 0.25em;
72
- }
73
-
74
- .child{
75
- width: 100%;
76
- position: absolute;
77
- left: 0;
78
- right: 0;
79
- }
80
- </style>
81
- <div class="cover">
8
+ <div style="position: relative; height: 0.25em;">
82
9
  <progress
83
- style="color: {color};"
84
- class="pure-material-progress-linear child"
10
+ style="color: {color}; width: 100%; position: absolute; left: 0; right: 0;"
11
+ class="pure-material-progress-linear"
85
12
  ></progress>
86
13
  </div>
@@ -0,0 +1,56 @@
1
+ <script lang="ts">
2
+ import { toasts, removeToast, ButtonTimes } from '../../../index.js';
3
+ import type { Toast } from '../../../stores/features/toastManager.js';
4
+
5
+ let elements =$state<HTMLDivElement[]>([]);
6
+ let toastMessages=$state<Toast[]>([]);
7
+
8
+ $effect(()=>{
9
+ toastMessages = $toasts;
10
+ })
11
+
12
+ const getOffset = (index: number) => {
13
+ let offset = 0;
14
+
15
+ for (let i = 0; i < index; i++) {
16
+ offset += elements[i]?.offsetHeight || 0;
17
+ offset += 10; // gap between toasts
18
+ }
19
+ return offset;
20
+ };
21
+ </script>
22
+
23
+ <style>
24
+ #toast{
25
+ position: fixed;
26
+ top: 80px;
27
+ right: 20px;
28
+ width: 300px;
29
+ border-top-right-radius: 5px;
30
+ border-bottom-right-radius: 5px;
31
+ border-left: 6px solid var(--retval);
32
+ box-shadow: var(--box-shadow);
33
+ background-color: var(--menu-bg);
34
+ transition: transform 0.3s ease, opacity 0.3s ease;
35
+ z-index: 25;
36
+ }
37
+ </style>
38
+ {#each toastMessages as toast,i (toast.id)}
39
+ <div
40
+ id="toast"
41
+ bind:this={elements[i]}
42
+ style="--retval: {toast.color};
43
+ transform: translateY({getOffset(i)}px);
44
+ ">
45
+ <div style="display: flex; align-items: center; justify-content: space-between; padding: 5px 5px 5px 10px;">
46
+ <div style="display: flex;align-items: center; gap: 10px;">
47
+ <i style="color: {toast.color};" class="fa-solid {toast.icon}"></i>
48
+ <p style="font-weight: bold; color: {toast.color}; max-width: 250px;"
49
+ class="sierra-text-wrap"
50
+ >{toast.status}</p>
51
+ </div>
52
+ <ButtonTimes width="50px" height="100%" absolute={false} iconSize="18px" onclick={() => removeToast(toast.id)}/>
53
+ </div>
54
+ <div style="padding: 0px 5px 5px 20px;">{ toast.message }</div>
55
+ </div>
56
+ {/each}
@@ -0,0 +1,3 @@
1
+ declare const ToastManager: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type ToastManager = ReturnType<typeof ToastManager>;
3
+ export default ToastManager;
@@ -1,5 +1,5 @@
1
1
  import { get } from 'svelte/store';
2
- import { setToastMessage, layoutStore } from '../index.js';
2
+ import { layoutStore, addToast } from '../index.js';
3
3
  export function validateLayoutMenuSections(sections) {
4
4
  const seenPaths = new Set();
5
5
  for (const section of sections) {
@@ -9,12 +9,20 @@ export function validateLayoutMenuSections(sections) {
9
9
  continue;
10
10
  // Check for missing id
11
11
  if (!item.id) {
12
- setToastMessage('warning', `Parent item "${item.label}" with path "${item.path}" is missing an 'id'. Each parent must have a unique 'id'.`);
12
+ addToast({
13
+ status: 'warning',
14
+ message: `Parent item "${item.label}" with path "${item.path}" is missing an 'id'. Each parent must have a unique 'id'.`,
15
+ persistent: true
16
+ });
13
17
  console.warn(`Missing id on parent item:`, item);
14
18
  }
15
19
  // Check for duplicate paths
16
20
  if (seenPaths.has(item.path)) {
17
- setToastMessage('warning', `Duplicate parent path detected: "${item.path}". Each parent must have a unique path.`);
21
+ addToast({
22
+ status: 'warning',
23
+ message: `Duplicate parent path detected: "${item.path}". Each parent must have a unique path.`,
24
+ persistent: true
25
+ });
18
26
  console.warn(`Duplicate parent path: "${item.path}"`, item);
19
27
  }
20
28
  else {
@@ -1,4 +1,4 @@
1
- import { setToastMessage } from '../../../index.js';
1
+ import { addToast } from '../../../index.js';
2
2
  /**
3
3
  * @param {import('@tiptap/core').Editor} editor
4
4
  */
@@ -9,6 +9,9 @@ export async function exractContent(editor) {
9
9
  const html_content = editor.getHTML();
10
10
  return { json_content, html_content};
11
11
  }catch (error) {
12
- setToastMessage('error', 'An error occurred while processing content.');
12
+ addToast({
13
+ status: 'error',
14
+ message: 'An error occurred while processing content.'
15
+ });
13
16
  }
14
17
  }
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { insertImageAndMoveCursor } from '../../tools.js';
3
- import {fileInputStore, resetFileInputStore, editorStore, setToastMessage, modalStore, Input, DropdownContainer, MenuItem} from '../../../../index.js';
3
+ import {fileInputStore, resetFileInputStore, editorStore, modalStore, Input, DropdownContainer, MenuItem, addToast} from '../../../../index.js';
4
4
 
5
5
 
6
6
  import type { Editor } from "@tiptap/core";
@@ -16,7 +16,11 @@
16
16
  !$editorStore.serverStorageUrl ||
17
17
  !$editorStore.serverDownloadUrl
18
18
  ){
19
- setToastMessage('error','Server configuration is missing.');
19
+ addToast({
20
+ status: 'error',
21
+ message: 'Please configure the server settings in the editor configuration.',
22
+ persistent: true
23
+ });
20
24
  return;
21
25
  }
22
26
  fileInputStore.update(store => ({
@@ -56,7 +60,10 @@
56
60
  title: 'Editor',
57
61
  onConfirm: () => {
58
62
  if (!isValidUrl(value)) {
59
- setToastMessage('error', 'Please enter a valid image URL.');
63
+ addToast({
64
+ status: 'error',
65
+ message: 'Please enter a valid image URL.'
66
+ });
60
67
  return;
61
68
  }
62
69
  insertImageAndMoveCursor(value, editor);
@@ -1,19 +1,28 @@
1
1
  <script lang="ts">
2
- import { setToastMessage,isLoading, editorStore} from '../../index.js';
2
+ import {isLoading, editorStore,addToast} from '../../index.js';
3
3
  import { exractContent } from './tools.js';
4
4
 
5
5
  import type { Editor } from "@tiptap/core";
6
6
  export let editor: Editor;
7
7
 
8
8
  async function onSave() {
9
- if(editor?.isEmpty) setToastMessage('warning','Editor is empty')
9
+ if(editor?.isEmpty) {
10
+ addToast({
11
+ status: 'warning',
12
+ message: 'Editor is empty'
13
+ });
14
+ return;
15
+ }
10
16
  try {
11
17
  isLoading.set(true);
12
18
  const content = await exractContent(editor);
13
19
  editorStore.update((state) => ({ ...state, content }));
14
20
  if($editorStore.content) $editorStore.onExport();
15
21
  }catch (error) {
16
- setToastMessage('error', 'An error occurred while processing content.');
22
+ addToast({
23
+ status: 'error',
24
+ message: 'An error occurred while processing content.'
25
+ });
17
26
  } finally {
18
27
  isLoading.set(false);
19
28
  }
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { get } from "svelte/store";
3
- import {modalStore, fileInputStore, setToastMessage, MenuItem} from "../../../index.js";
3
+ import {modalStore, fileInputStore, MenuItem, addToast} from "../../../index.js";
4
4
 
5
5
  let {
6
6
  processing = $bindable(),
@@ -41,13 +41,19 @@
41
41
 
42
42
  if (!response.ok) {
43
43
  //console.error('Delete request failed:', data);
44
- setToastMessage('error', data || 'Failed to delete files.');
44
+ addToast({
45
+ status: 'error',
46
+ message: data || 'Failed to delete files.'
47
+ });
45
48
  return;
46
49
  }
47
50
 
48
51
  data.forEach((item: { id: string; code: number }) => {
49
52
  if (item.code === 404) {
50
- setToastMessage('error', `Failed to delete file with ID: ${item.id}`);
53
+ addToast({
54
+ status: 'error',
55
+ message: `Failed to delete file with ID: ${item.id}`
56
+ });
51
57
  }
52
58
  });
53
59
  fileInputStore.update(store => ({
@@ -57,7 +63,10 @@
57
63
  }));
58
64
 
59
65
  } catch (error) {
60
- setToastMessage('error', `Error deleting files: ${error}`);
66
+ addToast({
67
+ status: 'error',
68
+ message: `Error deleting files: ${error}`
69
+ });
61
70
  } finally {
62
71
  processing = false;
63
72
  }
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { get } from "svelte/store";
3
- import {MenuItem, fileInputStore, User, setToastMessage} from "../../../index.js";
3
+ import {MenuItem, fileInputStore, User, addToast} from "../../../index.js";
4
4
 
5
5
  let {
6
6
  processing = $bindable(),
@@ -11,7 +11,10 @@
11
11
  openActionsMenu = false;
12
12
  const store = get(fileInputStore);
13
13
  if (!store.submissions?.length || !$User.userId) {
14
- setToastMessage('error', 'An error occurred while processing your request.');
14
+ addToast({
15
+ status: 'error',
16
+ message: 'An error occurred while processing your request.'
17
+ });
15
18
  return;
16
19
  };
17
20
  try {
@@ -41,7 +44,10 @@
41
44
  });
42
45
 
43
46
  if (!res.ok) {
44
- setToastMessage('error', await res.json() || 'Upload failed' );
47
+ addToast({
48
+ status: 'error',
49
+ message: await res.json() || 'Download failed'
50
+ });
45
51
  return;
46
52
  }
47
53
 
@@ -66,7 +72,10 @@
66
72
  URL.revokeObjectURL(url);
67
73
 
68
74
  } catch (err) {
69
- setToastMessage('error', `Upload failed: ${err}`);
75
+ addToast({
76
+ status: 'error',
77
+ message: `Download failed: ${err}`
78
+ });
70
79
  }
71
80
  }
72
81
  </script>
@@ -1,6 +1,6 @@
1
1
  <script>
2
2
  import { onMount } from 'svelte';
3
- import { fileInputStore, User, setToastMessage, CustomProgress} from '../../../index.js';
3
+ import { fileInputStore, User, CustomProgress, addToast} from '../../../index.js';
4
4
 
5
5
  export let padding = "0.5rem";
6
6
  export let hidden = false;
@@ -25,14 +25,22 @@
25
25
  const data = await res.json();
26
26
 
27
27
  if (!res.ok) {
28
- setToastMessage("error", data || "Failed to fetch storage usage.");
28
+ addToast({
29
+ status: 'error',
30
+ message: data || "Failed to fetch storage usage.",
31
+ persistent: true
32
+ });
29
33
  return;
30
34
  }
31
35
  const { usedBytes, maxBytes } = data.storage;
32
36
  progress = (usedBytes / maxBytes) * 100;
33
37
  } catch (e) {
34
38
  console.error("catch error:", e);
35
- setToastMessage("error", "An error occurred while fetching storage usage.");
39
+ addToast({
40
+ status: 'error',
41
+ message: "An error occurred while fetching storage usage.",
42
+ persistent: true
43
+ });
36
44
  }
37
45
  }
38
46
 
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { onMount } from 'svelte';
3
- import { fileInputStore, User, setToastMessage, buttonRipple, isMobile, isTablet } from '../../../index.js';
3
+ import { fileInputStore, User, buttonRipple, isMobile, isTablet, addToast } from '../../../index.js';
4
4
  import Previews from './previews.svelte';
5
5
  import Storage from '../ActionsMenu/media_storage.svelte';
6
6
 
@@ -47,13 +47,19 @@
47
47
 
48
48
  if (!res.ok) {
49
49
  //console.log('Error fetching media:', data);
50
- setToastMessage("error", data || "Failed to fetch media.");
50
+ addToast({
51
+ status: 'error',
52
+ message: data || "Failed to fetch media."
53
+ });
51
54
  return;
52
55
  }
53
56
  media = data;
54
57
  } catch (e) {
55
58
  console.error("catch error:", e);
56
- setToastMessage("error", "An error occurred while fetching media.");
59
+ addToast({
60
+ status: 'error',
61
+ message: "An error occurred while fetching media."
62
+ });
57
63
  } finally {
58
64
  processing = false;
59
65
  }
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import {Backdrop,Wrapper,fileInputStore, LinearProgress,FileInput, User, setToastMessage, Tabs, resetFileInputStore} from '../../index.js'
2
+ import {Backdrop,Wrapper,fileInputStore, LinearProgress,FileInput, User, Tabs, resetFileInputStore, addToast} from '../../index.js'
3
3
  import CloudStore from './Cloud/cloudStore.svelte';
4
4
  import Actions from './ActionsMenu/Actions.svelte';
5
5
 
@@ -24,13 +24,20 @@
24
24
  const data = await res.json();
25
25
 
26
26
  if (!res.ok) {
27
- setToastMessage('error', data || 'Upload failed' );
27
+ addToast({
28
+ status: 'error',
29
+ message: data || 'Upload failed',
30
+ persistent: true
31
+ });
28
32
  return;
29
33
  }
30
34
 
31
35
  data.forEach((item: { original_name: string; code: number; }) => {
32
36
  if (item.code === 500) {
33
- setToastMessage('error', `Failed to upload file: ${item.original_name}`);
37
+ addToast({
38
+ status: 'error',
39
+ message: `Failed to upload file: ${item.original_name}`
40
+ });
34
41
  }
35
42
  });
36
43
 
@@ -41,7 +48,11 @@
41
48
  return store;
42
49
  });
43
50
  } catch (err) {
44
- setToastMessage('error', `Upload failed: ${err}`);
51
+ addToast({
52
+ status: 'error',
53
+ message: `Upload failed: ${err}`,
54
+ persistent: true
55
+ });
45
56
  } finally {
46
57
  processing = false;
47
58
  }
@@ -1,7 +1,7 @@
1
1
  <script>
2
2
  import './main.css';
3
3
  import { onMount } from 'svelte';
4
- import {LinearProgress, isLoading, isMobile, isTablet, Modal, Toast, theme,FilePicker, layoutStore} from '../../index.js'
4
+ import {LinearProgress, isLoading, isMobile, isTablet, Modal, theme,FilePicker, layoutStore, ToastManager} from '../../index.js'
5
5
  import Header from './Header/header.svelte';
6
6
  import Menu from './Menu/menu.svelte';
7
7
  import Background from './background.svelte';
@@ -59,8 +59,8 @@
59
59
 
60
60
  <main style="height: 100vh;">
61
61
  <Modal />
62
- <Toast />
63
62
  <FilePicker />
63
+ <ToastManager/>
64
64
  <Header {toggleMenu}/>
65
65
  {#if $isLoading}<LinearProgress />{/if}
66
66
  <div id="sierra-layout">
package/dist/index.d.ts CHANGED
@@ -23,15 +23,13 @@ export { default as PreviewImage } from './Core/components/others/Previews/Image
23
23
  export { default as PreviewVideo } from './Core/components/others/Previews/Video/video.svelte';
24
24
  export { default as PreviewDocument } from './Core/components/others/Previews/Document/documents.svelte';
25
25
  export { default as PreviewGenericFile } from './Core/components/others/Previews/GenericFile/genericFile.svelte';
26
- export { default as Modal } from './Core/components/Alerts/Modal/modal.svelte';
27
- export { default as Backdrop } from './Core/components/Alerts/Backdrop/backdrop.svelte';
28
- export { default as Wrapper } from './Core/components/Alerts/Wrapper/wrapper.svelte';
29
- export { default as Toast } from './Core/components/Alerts/Toast/toast.svelte';
30
- export { default as SiteUnderMaintenance } from './Core/components/Alerts/site-under-maintenance/site-under-maintenance.svelte';
31
26
  export { default as MenuItem } from './Core/components/Menus/MenuItem/menuItem.svelte';
32
27
  export { default as DropdownContainer } from './Core/components/Menus/DropdownContainer/dropdown.svelte';
33
28
  export { default as Tabs } from './Core/components/Menus/Tabs/main.svelte';
34
29
  export { default as HamburgerMenu } from './Core/components/Menus/Hamburger/hamburger.svelte';
30
+ export { default as Modal } from './Core/components/others/Modal/modal.svelte';
31
+ export { default as Backdrop } from './Core/components/others/Backdrop/backdrop.svelte';
32
+ export { default as Wrapper } from './Core/components/others/Wrapper/wrapper.svelte';
35
33
  export { default as Time } from './Core/components/others/Calender/Time/time.svelte';
36
34
  export { default as Date } from './Core/components/others/Calender/Date/date.svelte';
37
35
  export { default as Hr } from './Core/components/others/Hr/Hr/hr.svelte';
@@ -42,6 +40,7 @@ export { default as Carousel } from './Core/components/others/Carousel/carousel.
42
40
  export { default as Avatar } from './Core/components/others/Avatar/avatar.svelte';
43
41
  export { default as ColorPicker } from './Core/components/others/ColorPicker/main.svelte';
44
42
  export { default as GlobalSearch } from './Core/features/GlobalSearch/main.svelte';
43
+ export { default as ToastManager } from './Core/features/ToastManager/toastManager.svelte';
45
44
  export { default as Editor } from './Modules/Editor/main.svelte';
46
45
  export { default as Layout } from './Modules/Layout/main.svelte';
47
46
  export { default as FilePicker } from './Modules/FilePicker/main.svelte';
@@ -52,8 +51,8 @@ export { modalStore, resetModalStore } from './stores/core/modal.js';
52
51
  export { editorStore, resetEditorStore } from './stores/modules/editor.js';
53
52
  export { fileInputStore, resetFileInputStore } from './stores/modules/fileInput.js';
54
53
  export type { FileInputStoreMediaItem } from './stores/modules/fileInput.js';
55
- export { toastCarrier, setToastMessage, clearToastMessage } from './stores/modules/toast.js';
56
54
  export { layoutStore, resetLayoutStore } from './stores/modules/layout.js';
55
+ export { addToast, removeToast, toasts } from './stores/features/toastManager.js';
57
56
  export { getPreviewUrlForMedia, toggleSelectForMedia, removeFileForMedia, DOCUMENT_MIME_TYPES, IMAGE_MIME_TYPES_PREVIEW } from './Hooks/preview.js';
58
57
  export { validateLayoutMenuSections, filterSectionsByRole } from './Hooks/layout_menu.js';
59
58
  export { buttonRipple } from './Hooks/button.js';
package/dist/index.js CHANGED
@@ -28,18 +28,15 @@ export { default as PreviewImage } from './Core/components/others/Previews/Image
28
28
  export { default as PreviewVideo } from './Core/components/others/Previews/Video/video.svelte';
29
29
  export { default as PreviewDocument } from './Core/components/others/Previews/Document/documents.svelte';
30
30
  export { default as PreviewGenericFile } from './Core/components/others/Previews/GenericFile/genericFile.svelte';
31
- //Alerts
32
- export { default as Modal } from './Core/components/Alerts/Modal/modal.svelte';
33
- export { default as Backdrop } from './Core/components/Alerts/Backdrop/backdrop.svelte';
34
- export { default as Wrapper } from './Core/components/Alerts/Wrapper/wrapper.svelte';
35
- export { default as Toast } from './Core/components/Alerts/Toast/toast.svelte';
36
- export { default as SiteUnderMaintenance } from './Core/components/Alerts/site-under-maintenance/site-under-maintenance.svelte';
37
31
  //Menus
38
32
  export { default as MenuItem } from './Core/components/Menus/MenuItem/menuItem.svelte';
39
33
  export { default as DropdownContainer } from './Core/components/Menus/DropdownContainer/dropdown.svelte';
40
34
  export { default as Tabs } from './Core/components/Menus/Tabs/main.svelte';
41
35
  export { default as HamburgerMenu } from './Core/components/Menus/Hamburger/hamburger.svelte';
42
36
  //others
37
+ export { default as Modal } from './Core/components/others/Modal/modal.svelte';
38
+ export { default as Backdrop } from './Core/components/others/Backdrop/backdrop.svelte';
39
+ export { default as Wrapper } from './Core/components/others/Wrapper/wrapper.svelte';
43
40
  export { default as Time } from './Core/components/others/Calender/Time/time.svelte';
44
41
  export { default as Date } from './Core/components/others/Calender/Date/date.svelte';
45
42
  export { default as Hr } from './Core/components/others/Hr/Hr/hr.svelte';
@@ -51,6 +48,7 @@ export { default as Avatar } from './Core/components/others/Avatar/avatar.svelte
51
48
  export { default as ColorPicker } from './Core/components/others/ColorPicker/main.svelte';
52
49
  //####################Features##################################
53
50
  export { default as GlobalSearch } from './Core/features/GlobalSearch/main.svelte';
51
+ export { default as ToastManager } from './Core/features/ToastManager/toastManager.svelte';
54
52
  //####################MODULES COMPONENTS########################
55
53
  export { default as Editor } from './Modules/Editor/main.svelte';
56
54
  export { default as Layout } from './Modules/Layout/main.svelte';
@@ -64,8 +62,8 @@ export { modalStore, resetModalStore } from './stores/core/modal.js';
64
62
  //Modules
65
63
  export { editorStore, resetEditorStore } from './stores/modules/editor.js';
66
64
  export { fileInputStore, resetFileInputStore } from './stores/modules/fileInput.js';
67
- export { toastCarrier, setToastMessage, clearToastMessage } from './stores/modules/toast.js';
68
65
  export { layoutStore, resetLayoutStore } from './stores/modules/layout.js';
66
+ export { addToast, removeToast, toasts } from './stores/features/toastManager.js';
69
67
  //#######################HOOKS/UTILS########################
70
68
  export { getPreviewUrlForMedia, toggleSelectForMedia, removeFileForMedia, DOCUMENT_MIME_TYPES, IMAGE_MIME_TYPES_PREVIEW } from './Hooks/preview.js';
71
69
  export { validateLayoutMenuSections, filterSectionsByRole } from './Hooks/layout_menu.js';
@@ -0,0 +1,21 @@
1
+ export type ToastPriority = 'high' | 'medium' | 'low';
2
+ export interface Toast {
3
+ id: string;
4
+ status: 'info' | 'success' | 'warning' | 'error';
5
+ message: string;
6
+ priority: ToastPriority;
7
+ persistent: boolean;
8
+ duration: number;
9
+ createdAt: number;
10
+ icon?: string;
11
+ color?: string;
12
+ }
13
+ export declare const toasts: import("svelte/store").Writable<Toast[]>;
14
+ export declare const removeToast: (id: string) => void;
15
+ export declare const addToast: ({ status, message, priority, persistent, duration }: {
16
+ status: Toast["status"];
17
+ message: string;
18
+ priority?: ToastPriority;
19
+ persistent?: boolean;
20
+ duration?: number;
21
+ }) => void;
@@ -0,0 +1,67 @@
1
+ import { writable } from 'svelte/store';
2
+ import { v4 as uuid } from 'uuid';
3
+ export const toasts = writable([]);
4
+ //Functionalities
5
+ export const removeToast = (id) => {
6
+ toasts.update((current) => current.filter((t) => t.id !== id));
7
+ };
8
+ const priorityRank = {
9
+ high: 3,
10
+ medium: 2,
11
+ low: 1
12
+ };
13
+ const statusMeta = {
14
+ info: {
15
+ icon: 'fa-circle-info',
16
+ color: 'var(--primary-bg)'
17
+ },
18
+ success: {
19
+ icon: 'fa-circle-check',
20
+ color: 'var(--primary-bg)'
21
+ },
22
+ error: {
23
+ icon: 'fa-circle-xmark',
24
+ color: 'var(--error-bg)'
25
+ },
26
+ warning: {
27
+ icon: 'fa-triangle-exclamation',
28
+ color: 'var(--warning-bg)'
29
+ }
30
+ };
31
+ const sortToasts = (list) => {
32
+ return list.sort((a, b) => {
33
+ // Persistent first
34
+ if (a.persistent !== b.persistent) {
35
+ return a.persistent ? -1 : 1;
36
+ }
37
+ // Priority next
38
+ if (priorityRank[a.priority] !== priorityRank[b.priority]) {
39
+ return priorityRank[b.priority] - priorityRank[a.priority];
40
+ }
41
+ // Oldest first
42
+ return a.createdAt - b.createdAt;
43
+ });
44
+ };
45
+ export const addToast = ({ status, message, priority = 'low', persistent = false, duration = 6000 }) => {
46
+ const meta = statusMeta[status];
47
+ const newToast = {
48
+ id: uuid(),
49
+ status,
50
+ message,
51
+ priority,
52
+ persistent,
53
+ duration,
54
+ createdAt: Date.now(),
55
+ icon: meta.icon,
56
+ color: meta.color
57
+ };
58
+ toasts.update((current) => {
59
+ const updated = [...current, newToast];
60
+ return sortToasts(updated);
61
+ });
62
+ if (!persistent) {
63
+ setTimeout(() => {
64
+ removeToast(newToast.id);
65
+ }, duration);
66
+ }
67
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sierra-95/svelte-scaffold",
3
- "version": "1.0.81",
3
+ "version": "1.1.1",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",
@@ -73,6 +73,7 @@
73
73
  "@tiptap/extension-text-style": "^3.13.0",
74
74
  "@tiptap/extension-youtube": "^3.13.0",
75
75
  "@tiptap/pm": "^3.13.0",
76
- "@tiptap/starter-kit": "^3.13.0"
76
+ "@tiptap/starter-kit": "^3.13.0",
77
+ "uuid": "^13.0.0"
77
78
  }
78
79
  }
@@ -1,39 +0,0 @@
1
- #toast{
2
- position: fixed;
3
- top: 80px;
4
- right: 20px;
5
- width: 300px;
6
- border-top-right-radius: 5px;
7
- border-bottom-right-radius: 5px;
8
- border-left: 6px solid var(--retval);
9
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
10
- background-color: var(--menu-bg);
11
- z-index: 25;
12
- }
13
- #toast div:nth-child(1){
14
- display: flex;
15
- align-items: center;
16
- justify-content: space-between;
17
- font-weight: bold;
18
- color: var(--retval);
19
- padding: 5px 5px 5px 10px;
20
- }
21
- #toast div:nth-child(1) div{
22
- display: flex;
23
- align-items: center;
24
- gap: 10px;
25
- }
26
- #toast div:nth-child(2){
27
- padding: 0px 5px 5px 20px;
28
- }
29
- #toast p {
30
- max-width: 250px;
31
- white-space: normal;
32
- overflow-wrap: break-word;
33
- word-break: normal;
34
- }
35
- #toast i.fa-times{
36
- color: var(--text);
37
- cursor: pointer;
38
- padding-right: 20px;
39
- }
@@ -1,32 +0,0 @@
1
- <script>
2
- import './toast.css';
3
- import {toastCarrier, clearToastMessage} from '../../../../index.js';
4
-
5
- const statusClass = {
6
- info: 'var(--primary-bg)',
7
- success: 'var(--primary-bg)',
8
- error: 'var(--error-bg)',
9
- warning: 'var(--warning-bg)'
10
- };
11
- $: retval = statusClass[$toastCarrier.status]
12
- </script>
13
- {#if $toastCarrier.message}
14
- <div id="toast" style="--retval: {retval};">
15
- <div>
16
- <div>
17
- {#if $toastCarrier.status === 'info'}
18
- <i class="fa-solid fa-circle-info"></i>
19
- {:else if $toastCarrier.status === 'success'}
20
- <i class="fa-solid fa-circle-check"></i>
21
- {:else if $toastCarrier.status === 'error'}
22
- <i class="fa-solid fa-circle-xmark"></i>
23
- {:else if $toastCarrier.status === 'warning'}
24
- <i class="fa-solid fa-triangle-exclamation"></i>
25
- {/if}
26
- <p>{$toastCarrier.status}</p>
27
- </div>
28
- <i on:click={clearToastMessage} role="none" class="fa-solid fa-times"></i>
29
- </div>
30
- <div>{ $toastCarrier.message }</div>
31
- </div>
32
- {/if}
@@ -1,26 +0,0 @@
1
- export default Toast;
2
- type Toast = SvelteComponent<{
3
- [x: string]: never;
4
- }, {
5
- [evt: string]: CustomEvent<any>;
6
- }, {}> & {
7
- $$bindings?: string | undefined;
8
- };
9
- declare const Toast: $$__sveltets_2_IsomorphicComponent<{
10
- [x: string]: never;
11
- }, {
12
- [evt: string]: CustomEvent<any>;
13
- }, {}, {}, string>;
14
- interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
15
- new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
16
- $$bindings?: Bindings;
17
- } & Exports;
18
- (internal: unknown, props: {
19
- $$events?: Events;
20
- $$slots?: Slots;
21
- }): Exports & {
22
- $set?: any;
23
- $on?: any;
24
- };
25
- z_$$bindings?: Bindings;
26
- }
@@ -1,34 +0,0 @@
1
- <script>
2
- const {email} = $props();
3
- </script>
4
- <style>
5
- #maintenance {
6
- position: fixed;
7
- top: 0;
8
- right: 0;
9
- bottom: 0;
10
- left: 0;
11
- background-color: rgba(0, 0, 0, 0.7);
12
- display: flex;
13
- flex-direction: column;
14
- align-items: center;
15
- justify-content: center;
16
- gap: 10px;
17
- padding: 1rem;
18
- z-index: 5;
19
- backdrop-filter: blur(2px);
20
- color: white;
21
- }
22
- #maintenance a{
23
- text-decoration: underline;
24
- }
25
- </style>
26
-
27
- <div id="maintenance">
28
- <h1>Under Construction</h1>
29
- <p>This site is still being built and will be available soon. Thanks for your patience.</p>
30
- <p>
31
- Need immediate assistance?<br>
32
- Contact <a href="mailto:{email}">{email}</a>
33
- </p>
34
- </div>
@@ -1,11 +0,0 @@
1
- export default SiteUnderMaintenance;
2
- type SiteUnderMaintenance = {
3
- $on?(type: string, callback: (e: any) => void): () => void;
4
- $set?(props: Partial<$$ComponentProps>): void;
5
- };
6
- declare const SiteUnderMaintenance: import("svelte").Component<{
7
- email: any;
8
- }, {}, "">;
9
- type $$ComponentProps = {
10
- email: any;
11
- };