@sierra-95/svelte-scaffold 1.0.32 → 1.0.34

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 (49) hide show
  1. package/dist/components/Core/Alerts/Backdrop/backdrop.svelte +6 -12
  2. package/dist/components/Core/Alerts/Backdrop/backdrop.svelte.d.ts +1 -0
  3. package/dist/components/Core/Alerts/Wrapper/wrapper.svelte +9 -1
  4. package/dist/components/Core/Alerts/Wrapper/wrapper.svelte.d.ts +2 -0
  5. package/dist/components/Core/Form/Input/SearchBar/search.svelte +5 -14
  6. package/dist/components/Core/Menus/MenuItem/menuItem.svelte +2 -1
  7. package/dist/components/Core/Menus/MenuItem/menuItem.svelte.d.ts +1 -0
  8. package/dist/components/Core/Menus/Tabs/main.css +22 -0
  9. package/dist/components/Core/Menus/Tabs/main.svelte +45 -0
  10. package/dist/components/Core/Menus/Tabs/main.svelte.d.ts +12 -0
  11. package/dist/components/Core/others/Previews/Image/image.svelte +11 -4
  12. package/dist/components/Modules/Editor/Hooks/extractContent.d.ts +1 -1
  13. package/dist/components/Modules/Editor/Hooks/extractContent.js +3 -4
  14. package/dist/components/Modules/Editor/controls.svelte +38 -52
  15. package/dist/components/Modules/Editor/controls.svelte.d.ts +0 -2
  16. package/dist/components/Modules/Editor/export.svelte +30 -0
  17. package/dist/components/Modules/Editor/{save.svelte.d.ts → export.svelte.d.ts} +3 -5
  18. package/dist/components/Modules/Editor/main.svelte +1 -2
  19. package/dist/components/Modules/Editor/main.svelte.d.ts +0 -1
  20. package/dist/components/Modules/Editor/styles/controls.css +2 -13
  21. package/dist/components/Modules/Editor/styles/main.css +1 -1
  22. package/dist/components/Modules/Editor/tools.d.ts +1 -2
  23. package/dist/components/Modules/Editor/tools.js +1 -3
  24. package/dist/components/Modules/FilePicker/ActionsMenu/Actions.svelte +52 -0
  25. package/dist/components/Modules/FilePicker/ActionsMenu/Actions.svelte.d.ts +5 -0
  26. package/dist/components/Modules/FilePicker/ActionsMenu/delete_media.svelte +1 -1
  27. package/dist/components/Modules/FilePicker/ActionsMenu/download_media.svelte +1 -1
  28. package/dist/components/Modules/FilePicker/Cloud/cloudStore.svelte +26 -9
  29. package/dist/components/Modules/FilePicker/Cloud/previews.svelte +1 -1
  30. package/dist/components/Modules/FilePicker/main.svelte +26 -9
  31. package/dist/components/Modules/Layout/main.svelte +9 -7
  32. package/dist/index.d.ts +2 -2
  33. package/dist/index.js +2 -2
  34. package/dist/stores/core/deviceWidth.d.ts +6 -0
  35. package/dist/stores/core/deviceWidth.js +26 -0
  36. package/dist/stores/modules/editor.d.ts +3 -0
  37. package/dist/stores/modules/editor.js +3 -0
  38. package/dist/stores/modules/fileInput.d.ts +1 -1
  39. package/dist/stores/modules/fileInput.js +1 -1
  40. package/package.json +1 -1
  41. package/dist/components/Core/Menus/UserMenu/profile.svelte +0 -35
  42. package/dist/components/Core/Menus/UserMenu/profile.svelte.d.ts +0 -11
  43. package/dist/components/Modules/Editor/Hooks/extractImage.d.ts +0 -7
  44. package/dist/components/Modules/Editor/Hooks/extractImage.js +0 -30
  45. package/dist/components/Modules/Editor/save.svelte +0 -28
  46. package/dist/components/Modules/FilePicker/controls.svelte +0 -95
  47. package/dist/components/Modules/FilePicker/controls.svelte.d.ts +0 -5
  48. package/dist/stores/core/ismobile.d.ts +0 -1
  49. package/dist/stores/core/ismobile.js +0 -14
@@ -1,10 +1,9 @@
1
1
  <script lang="ts">
2
- import { onMount, onDestroy } from "svelte";
3
- import { browser } from "$app/environment";
4
2
 
5
3
  let {
6
4
  open = $bindable(false),
7
5
  zIndex = 15,
6
+ onClose = () => {},
8
7
  children
9
8
  } = $props();
10
9
 
@@ -12,18 +11,10 @@
12
11
  if (e.key === 'Escape' && open) {
13
12
  e.preventDefault();
14
13
  open = false;
14
+ onClose();
15
15
  }
16
16
  }
17
-
18
- onMount(() => {
19
- if (!browser) return;
20
- window.addEventListener('keydown', handleEscape);
21
- });
22
-
23
- onDestroy(() => {
24
- if (!browser) return;
25
- window.removeEventListener('keydown', handleEscape);
26
- });
17
+
27
18
  </script>
28
19
  <style>
29
20
  #sierra-blur {
@@ -40,6 +31,9 @@
40
31
  backdrop-filter: blur(2px);
41
32
  }
42
33
  </style>
34
+
35
+
36
+ <svelte:window on:keydown={handleEscape} />
43
37
  {#if open}
44
38
  <div id="sierra-blur" style="z-index: {zIndex};">
45
39
  {@render children?.()}
@@ -1,6 +1,7 @@
1
1
  declare const Backdrop: import("svelte").Component<{
2
2
  open?: boolean;
3
3
  zIndex?: number;
4
+ onClose?: Function;
4
5
  children: any;
5
6
  }, {}, "open">;
6
7
  type Backdrop = ReturnType<typeof Backdrop>;
@@ -3,6 +3,7 @@
3
3
  padding = '20px',
4
4
  minHeight = '100px',
5
5
  maxWidth = '500px',
6
+ height = '',
6
7
  children
7
8
  } = $props();
8
9
  </script>
@@ -14,6 +15,13 @@
14
15
  width: 100%;
15
16
  }
16
17
  </style>
17
- <div id="sierra-wrapper" role='none' style="max-width: {maxWidth}; min-height: {minHeight}; padding: {padding};" onclick={e => e.stopPropagation()}>
18
+ <div id="sierra-wrapper" role='none'
19
+ style="
20
+ max-width: {maxWidth};
21
+ min-height: {minHeight};
22
+ padding: {padding};
23
+ {height? `height: ${height}`:''}
24
+ "
25
+ onclick={e => e.stopPropagation()}>
18
26
  {@render children?.()}
19
27
  </div>
@@ -7,11 +7,13 @@ declare const Wrapper: import("svelte").Component<{
7
7
  padding?: string;
8
8
  minHeight?: string;
9
9
  maxWidth?: string;
10
+ height?: string;
10
11
  children: any;
11
12
  }, {}, "">;
12
13
  type $$ComponentProps = {
13
14
  padding?: string;
14
15
  minHeight?: string;
15
16
  maxWidth?: string;
17
+ height?: string;
16
18
  children: any;
17
19
  };
@@ -1,7 +1,4 @@
1
- <script lang="ts">
2
- import { onMount, onDestroy } from 'svelte';
3
- import { browser } from '$app/environment';
4
-
1
+ <script lang="ts">
5
2
  let {
6
3
  width = '200px',
7
4
  height = '40px',
@@ -21,16 +18,6 @@
21
18
  onHotkey?.();
22
19
  }
23
20
  }
24
-
25
- onMount(() => {
26
- if (!enableHotkey || !browser) return;
27
- window.addEventListener('keydown', handleKeydown);
28
- });
29
-
30
- onDestroy(() => {
31
- if(!browser) return;
32
- window.removeEventListener('keydown', handleKeydown);
33
- });
34
21
  </script>
35
22
  <style>
36
23
  #sierra-search-bar{
@@ -71,6 +58,10 @@
71
58
  border-left: none;
72
59
  }
73
60
  </style>
61
+
62
+
63
+ <svelte:window on:keydown={handleKeydown} />
64
+
74
65
  <main id="sierra-search-bar" role="none" style="height: {height}; display:flex; }">
75
66
 
76
67
  <button
@@ -4,6 +4,7 @@
4
4
  active = false,
5
5
  disabled = false,
6
6
  iconSize = '20px',
7
+ iconGap = '20px',
7
8
  iconBg: iconBg = 'var(--primary-bg)',
8
9
  children = null,
9
10
  ...rest
@@ -40,5 +41,5 @@
40
41
  <i style="font-size: {iconSize}; color: {iconBg}"
41
42
  class="fa {icon}"></i>
42
43
  {/if}
43
- <h4 style="margin-left: {icon ? '20px' : '0'};">{@render children?.()}</h4>
44
+ <h4 style="margin-left: {icon ? iconGap : '0'};">{@render children?.()}</h4>
44
45
  </div>
@@ -3,6 +3,7 @@ declare const MenuItem: import("svelte").Component<{
3
3
  active?: boolean;
4
4
  disabled?: boolean;
5
5
  iconSize?: string;
6
+ iconGap?: string;
6
7
  iconBg?: string;
7
8
  children?: any;
8
9
  } & Record<string, any>, {}, "">;
@@ -0,0 +1,22 @@
1
+ #sierra-tabs {
2
+ position: relative;
3
+ background-color: var(--background-secondary);
4
+ }
5
+ #sierra-tabs .tab-row {
6
+ display: flex;
7
+ justify-content: space-between;
8
+ }
9
+ #sierra-tabs .tab {
10
+ display: flex;
11
+ align-items: center;
12
+ padding: 4px 16px;
13
+ border-radius: 4px 4px 0 0;
14
+ }
15
+
16
+ #sierra-tabs .tab.active {
17
+ background-color: var(--background);
18
+ }
19
+ #sierra-tabs .tab-content{
20
+ padding: 1rem;
21
+ background-color: var(--background);
22
+ }
@@ -0,0 +1,45 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte';
3
+ import './main.css';
4
+
5
+ let {
6
+ tabs,
7
+ snippets,
8
+ active = $bindable(),
9
+ iconBg = 'var(--primary-bg)',
10
+ iconSize = '15px',
11
+ boxShadow = false,
12
+ actions,
13
+ } = $props();
14
+
15
+ onMount(()=>{
16
+ if(!active && tabs?.length > 0){
17
+ active = tabs[0].key;
18
+ }
19
+ })
20
+ </script>
21
+
22
+ <div id="sierra-tabs" style="{boxShadow? 'box-shadow: var(--box-shadow)':''}">
23
+ <div class="tab-row">
24
+ <div style="display: flex;">
25
+ {#each tabs as tab}
26
+ <button
27
+ class="tab {active === tab.key ? 'active' : ''}"
28
+ onclick={() => active = tab.key}
29
+ >
30
+ {#if tab.icon}
31
+ <i style="font-size: {iconSize}; color: {iconBg}; margin-right: 8px;" class="fa {tab.icon}"></i>
32
+ {/if}
33
+ {tab.title}
34
+ </button>
35
+ {/each}
36
+ </div>
37
+ {@render actions?.()}
38
+ </div>
39
+
40
+ <div class="tab-content">
41
+ {#if snippets?.[active]}
42
+ {@render snippets[active]()}
43
+ {/if}
44
+ </div>
45
+ </div>
@@ -0,0 +1,12 @@
1
+ import './main.css';
2
+ declare const Main: import("svelte").Component<{
3
+ tabs: any;
4
+ snippets: any;
5
+ active?: any;
6
+ iconBg?: string;
7
+ iconSize?: string;
8
+ boxShadow?: boolean;
9
+ actions: any;
10
+ }, {}, "active">;
11
+ type Main = ReturnType<typeof Main>;
12
+ export default Main;
@@ -16,7 +16,6 @@
16
16
 
17
17
  function previewUrl(item: any): string | null {
18
18
  if (!item) return null;
19
-
20
19
  return isPreviewable(item)
21
20
  ? (urlsOnly ? (item).url : getPreviewUrlForMedia(item))
22
21
  : null;
@@ -24,18 +23,26 @@
24
23
 
25
24
  </script>
26
25
 
26
+ <style>
27
+ #sierra-preview-image img{
28
+ width: 100%;
29
+ height: 100px;
30
+ object-fit: cover;
31
+ }
32
+ </style>
33
+
27
34
  {#snippet imageTag(url: string)}
28
- <img src={url} alt={url} style="width: 100%; height: 100px; object-fit: cover" />
35
+ <img src={url} alt={url} />
29
36
  {/snippet}
30
37
 
31
38
  {#if media.Images.length === 0}
32
39
  <p>No images available.</p>
33
40
  {:else}
34
- <div style="display: flex; flex-wrap: wrap; gap: 1rem;">
41
+ <div id="sierra-preview-image" style="display: flex; flex-wrap: wrap; gap: 1rem;">
35
42
  {#each media.Images as item}
36
43
  <div on:click={() => toggleSelectForMedia(item, urlsOnly)} role="none" class="sierra-translate" style="position:relative; cursor: pointer; width: {previewUrl(item)? '150px':''}">
37
44
  {#if previewUrl(item)}
38
- {@render imageTag(item.url)}
45
+ {@render imageTag(previewUrl(item)!)}
39
46
  {:else}
40
47
  <Generic/>
41
48
  {/if}
@@ -3,5 +3,5 @@
3
3
  */
4
4
  export function exractContent(editor: import("@tiptap/core").Editor): Promise<{
5
5
  json_content: import("@tiptap/core").DocumentType<Record<string, any> | undefined, import("@tiptap/core").NodeType<string, Record<string, any> | undefined, any, (import("@tiptap/core").NodeType<any, any, any, any> | import("@tiptap/core").TextType<import("@tiptap/core").MarkType<any, any>>)[]>[]>;
6
- images: string[];
6
+ html_content: string;
7
7
  } | undefined>;
@@ -1,5 +1,4 @@
1
1
  import { setToastMessage } from '../../../../index.js';
2
- import { extractImagesFromJSON } from '../tools.js';
3
2
  /**
4
3
  * @param {import('@tiptap/core').Editor} editor
5
4
  */
@@ -7,9 +6,9 @@ export async function exractContent(editor) {
7
6
  if (!editor) return;
8
7
  try {
9
8
  const json_content = editor.getJSON();
10
- const fnl_imgs = extractImagesFromJSON(json_content);
11
- return { json_content, images: fnl_imgs };
9
+ const html_content = editor.getHTML();
10
+ return { json_content, html_content};
12
11
  }catch (error) {
13
- setToastMessage('error', 'An error occurred while saving.');
12
+ setToastMessage('error', 'An error occurred while processing content.');
14
13
  }
15
14
  }
@@ -1,73 +1,59 @@
1
1
  <script lang="ts">
2
2
  import {
3
3
  TextFormatting, Headings, TextColor, TextAlign, Images, History, Youtube,
4
- Save, Lists, Links
4
+ Export, Lists, Links
5
5
  } from './tools.js';
6
6
  import type { Editor } from "@tiptap/core";
7
7
  import './styles/controls.css';
8
- import {isMobile} from '../../../index.js';
8
+ import {Tabs} from '../../../index.js';
9
9
 
10
10
  export let editor: Editor;
11
- export let exportText: string;
12
- export let content: any = {};
13
11
 
14
- const menuItems = [
15
- {
16
- id: 'home',
17
- label: 'Home',
18
- icon: 'fa-home',
19
- components: [
20
- TextFormatting,
12
+ const HomeItems = [
13
+ TextFormatting,
21
14
  History,
22
15
  Headings,
23
16
  TextColor,
24
17
  TextAlign,
25
18
  Lists,
26
- ]
27
- },
28
- {
29
- id: 'insert',
30
- label: 'Insert',
31
- icon: 'fa-plus',
32
- components: [
33
- Images,
34
- Links,
35
- Youtube,
36
- ]
37
- },
38
19
  ] as const;
39
-
40
- type MenuItem = typeof menuItems[number];
41
- type MenuId = MenuItem['id'];
42
-
43
- let activeTab: MenuId = 'home';
44
- </script>
45
20
 
21
+ const InsertItems = [
22
+ Images,
23
+ Links,
24
+ Youtube,
25
+ ] as const;
26
+ </script>
46
27
 
47
- <main id="controls">
48
- <div class="controls-menu" style="display: flex; gap: 0.5rem;"
49
- >
50
- <Save bind:content {exportText} {editor} />
51
- {#each menuItems as item, index (item.id)}
52
- <button
53
- style="padding: 2px 4px;"
54
- aria-label={item.label}
55
- class={` ${activeTab === item.id ? 'active' : ''}`}
56
- on:click={() => {activeTab = item.id}}
57
- ><i class="fa {item.icon}"></i><span hidden={$isMobile} style="margin-left: 5px;">{item.label}</span>
58
- </button>
59
- {/each}
28
+ {#snippet Home()}
29
+ <div id="controls">
30
+ <div class="controls-buttons">
31
+ {#each HomeItems as Component}
32
+ <Component {editor} />
33
+ {/each}
34
+ </div>
60
35
  </div>
61
-
62
- <div class="controls">
63
- {#each menuItems as item, index (item.id)}
64
- <div class={`controls-buttons
65
- ${activeTab === item.id ? 'active' : ''}
66
- `}>
67
- {#each item.components as Component}
36
+ {/snippet}
37
+
38
+ {#snippet Insert()}
39
+ <div id="controls">
40
+ <div class="controls-buttons">
41
+ {#each InsertItems as Component}
68
42
  <Component {editor} />
69
43
  {/each}
70
- </div>
71
- {/each}
44
+ </div>
72
45
  </div>
73
- </main>
46
+ {/snippet}
47
+
48
+ {#snippet actions()}
49
+ <Export {editor}/>
50
+ {/snippet}
51
+
52
+ <Tabs
53
+ tabs={[
54
+ { key: 'Home', title: 'Home', icon: 'fa-home' },
55
+ { key: 'Insert', title: 'Insert', icon: 'fa-plus' }
56
+ ]}
57
+ snippets={{ Home, Insert }}
58
+ actions={actions}
59
+ />
@@ -15,8 +15,6 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
15
15
  }
16
16
  declare const Controls: $$__sveltets_2_IsomorphicComponent<{
17
17
  editor: Editor;
18
- exportText: string;
19
- content?: any;
20
18
  }, {
21
19
  [evt: string]: CustomEvent<any>;
22
20
  }, {}, {}, string>;
@@ -0,0 +1,30 @@
1
+ <script lang="ts">
2
+ import { setToastMessage,isLoading, editorStore} from '../../../index.js';
3
+ import { exractContent } from './tools.js';
4
+
5
+ import type { Editor } from "@tiptap/core";
6
+ export let editor: Editor;
7
+
8
+ async function onSave() {
9
+ if(editor?.isEmpty) setToastMessage('warning','Editor is empty')
10
+ try {
11
+ isLoading.set(true);
12
+ const content = await exractContent(editor);
13
+ editorStore.update((state) => ({ ...state, content }));
14
+ $editorStore.onExport();
15
+ }catch (error) {
16
+ setToastMessage('error', 'An error occurred while processing content.');
17
+ } finally {
18
+ isLoading.set(false);
19
+ }
20
+ }
21
+
22
+ $: if($editorStore.export){
23
+ editorStore.update( store =>{
24
+ store.export = false
25
+ return store;
26
+ })
27
+ onSave();
28
+ }
29
+
30
+ </script>
@@ -12,12 +12,10 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
12
12
  };
13
13
  z_$$bindings?: Bindings;
14
14
  }
15
- declare const Save: $$__sveltets_2_IsomorphicComponent<{
15
+ declare const Export: $$__sveltets_2_IsomorphicComponent<{
16
16
  editor: Editor;
17
- exportText: string;
18
- content?: any;
19
17
  }, {
20
18
  [evt: string]: CustomEvent<any>;
21
19
  }, {}, {}, string>;
22
- type Save = InstanceType<typeof Save>;
23
- export default Save;
20
+ type Export = InstanceType<typeof Export>;
21
+ export default Export;
@@ -8,7 +8,6 @@
8
8
 
9
9
  export let content: any = {};
10
10
  export let readOnly: boolean = false;
11
- export let exportText: string = 'Save';
12
11
 
13
12
  let editor: Editor;
14
13
  let element: HTMLElement;
@@ -36,7 +35,7 @@
36
35
 
37
36
  <main id="editor">
38
37
  {#if editor && !readOnly}
39
- <Controls bind:content {exportText} {editor} />
38
+ <Controls {editor} />
40
39
  {/if}
41
40
  <div bind:this={element}></div>
42
41
  </main>
@@ -15,7 +15,6 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
15
15
  declare const Main: $$__sveltets_2_IsomorphicComponent<{
16
16
  content?: any;
17
17
  readOnly?: boolean;
18
- exportText?: string;
19
18
  }, {
20
19
  [evt: string]: CustomEvent<any>;
21
20
  }, {}, {}, string>;
@@ -1,11 +1,7 @@
1
1
  #editor #controls{
2
- margin: 0px 10px;
3
- padding-top: 5px;
4
- }
5
- #editor #controls .controls {
6
2
  margin-top: 5px;
7
3
  position: relative;
8
- background-color: var(--background-tertiary);
4
+ background-color: var(--background-secondary);
9
5
  border-radius: 15px;
10
6
  }
11
7
 
@@ -15,19 +11,12 @@
15
11
  align-items: center;
16
12
  padding: 2px 10px;
17
13
  gap: 10px;
18
- position: absolute;
14
+ position: relative;
19
15
  top: 0;
20
16
  left: 0;
21
17
  width: 100%;
22
- opacity: 0;
23
- pointer-events: none;
24
18
  transition: opacity 0.2s ease;
25
19
  }
26
- #editor #controls .controls-buttons.active {
27
- position: relative;
28
- opacity: 1;
29
- pointer-events: all;
30
- }
31
20
  #editor #controls button{
32
21
  align-self: center;
33
22
  }
@@ -1,6 +1,6 @@
1
1
  #editor{
2
2
  height: 100%;
3
- background-color: var(--background-secondary);
3
+ background-color: var(--background);
4
4
  box-shadow: var(--box-shadow);
5
5
  }
6
6
 
@@ -7,8 +7,7 @@ export { default as Lists } from "./Nodes/Lists/lists.svelte";
7
7
  export { default as TextFormatting } from "./Marks/TextFormatting/textFormatting.svelte";
8
8
  export { default as Links } from "./Marks/Links/links.svelte";
9
9
  export { default as History } from "./Nodes/History/history.svelte";
10
- export { default as Save } from "./save.svelte";
10
+ export { default as Export } from "./export.svelte";
11
11
  export { insertImageAndMoveCursor } from "./Hooks/insertImage.js";
12
12
  export { addYoutubeVideo } from "./Hooks/insertYoutube.js";
13
- export { extractImagesFromJSON } from "./Hooks/extractImage.js";
14
13
  export { exractContent } from "./Hooks/extractContent.js";
@@ -13,11 +13,9 @@ export {default as Links} from './Marks/Links/links.svelte';
13
13
  //functionality
14
14
  export {default as History} from './Nodes/History/history.svelte';
15
15
 
16
-
17
16
  //Export
18
- export {default as Save} from './save.svelte';
17
+ export {default as Export} from './export.svelte';
19
18
  //Hooks
20
19
  export {insertImageAndMoveCursor} from './Hooks/insertImage.js';
21
20
  export {addYoutubeVideo} from './Hooks/insertYoutube.js';
22
- export {extractImagesFromJSON} from './Hooks/extractImage.js';
23
21
  export {exractContent} from './Hooks/extractContent.js';
@@ -0,0 +1,52 @@
1
+ <script lang="ts">
2
+ import { onDestroy } from "svelte";
3
+ import {fileInputStore,resetFileInputStore, DropdownContainer, MenuItem, buttonRipple} from "../../../../index.js";
4
+ import FileProperties from "./file_properties.svelte";
5
+ import DownloadMedia from "./download_media.svelte";
6
+ import DeleteMedia from "./delete_media.svelte";
7
+
8
+ let {
9
+ processing = $bindable(),
10
+ } = $props();
11
+
12
+ function handleSelect() {
13
+ fileInputStore.update(store => ({
14
+ ...store,
15
+ submissionComplete: true,
16
+ uploadModalOpen: false
17
+ }));
18
+ }
19
+
20
+ const iconSize = '12px';
21
+ let showProperties = $state(false);
22
+ let openActionsMenu = $state(false);
23
+ let disableActions = $state(true);
24
+ $effect(() => {
25
+ if($fileInputStore.submissions.length > 0 && $fileInputStore.activeTab === 'Cloud'){
26
+ disableActions = false;
27
+ } else {
28
+ disableActions = true;
29
+ }
30
+ });
31
+
32
+ onDestroy(() => {
33
+ resetFileInputStore();
34
+ });
35
+ </script>
36
+
37
+ <FileProperties bind:showProperties />
38
+ <div style="display: flex; gap: 1rem; align-items: center; margin-right: 1rem">
39
+ <button hidden={$fileInputStore.manage || disableActions} title="Select" onclick={handleSelect} style="color: var(--primary-bg);" aria-label="Select submissions"><i class="fa fa-check-circle-o"></i></button>
40
+ {#snippet TriggerMenu()}
41
+ <button hidden={$fileInputStore.activeTab !== 'Cloud'} disabled={$fileInputStore.submissions.length === 0} use:buttonRipple class="w-10" aria-label="Ellipsis" onclick={() => (openActionsMenu = !openActionsMenu)}>
42
+ <i class="fa fa-bars"></i>
43
+ </button>
44
+ {/snippet}
45
+ <DropdownContainer bind:open={openActionsMenu} dropdownTrigger={TriggerMenu}>
46
+ <MenuItem iconBg="var(--primary-bg)" iconGap="10px" onclick={() => { showProperties = true; openActionsMenu = false; }} icon="fa-info-circle" iconSize={iconSize}>Properties</MenuItem>
47
+ <DownloadMedia {iconSize} bind:processing bind:openActionsMenu/>
48
+ <DeleteMedia {iconSize} bind:processing bind:openActionsMenu />
49
+ </DropdownContainer>
50
+ <button title="Cancel" onclick={resetFileInputStore} aria-label="Cancel"><i class="fa fa-xmark"></i></button>
51
+ </div>
52
+
@@ -0,0 +1,5 @@
1
+ declare const Actions: import("svelte").Component<{
2
+ processing?: any;
3
+ }, {}, "processing">;
4
+ type Actions = ReturnType<typeof Actions>;
5
+ export default Actions;
@@ -65,4 +65,4 @@
65
65
  }
66
66
  </script>
67
67
 
68
- <MenuItem onclick={handleDelete} icon="fa-trash-o" iconBg="var(--error-bg)" iconSize={iconSize}>Delete</MenuItem>
68
+ <MenuItem iconGap="10px" onclick={handleDelete} icon="fa-trash-o" iconBg="var(--error-bg)" iconSize={iconSize}>Delete</MenuItem>
@@ -72,4 +72,4 @@
72
72
  }
73
73
  </script>
74
74
 
75
- <MenuItem onclick={handleDownload} icon="fa-download" iconBg="var(--text)" iconSize={iconSize}>Download</MenuItem>
75
+ <MenuItem iconGap="10px" onclick={handleDownload} icon="fa-download" iconBg="var(--primary-bg)" iconSize={iconSize}>Download</MenuItem>
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { onMount } from 'svelte';
3
- import { fileInputStore, User, setToastMessage, buttonRipple, isMobile } from '../../../../index.js';
3
+ import { fileInputStore, User, setToastMessage, buttonRipple, isMobile, isTablet } from '../../../../index.js';
4
4
  import Previews from './previews.svelte';
5
5
  import Storage from '../ActionsMenu/media_storage.svelte';
6
6
 
@@ -75,16 +75,33 @@
75
75
  </script>
76
76
 
77
77
  <style>
78
- #sierra-cloud-store{
79
- /**Dont remove, the Selected item count depends on this relative positioning*/
80
- position: relative;
78
+ #sierra-cloud-store nav{
79
+ flex-direction: column;
81
80
  }
82
81
  #sierra-cloud-store .icon-active {
82
+ border-radius: 3px;
83
83
  background-color: var(--menu-item-active);
84
84
  }
85
+ #sierra-cloud-store i{
86
+ color: var(--icon-theme);
87
+ }
88
+ #sierra-cloud-store .icon-active i{
89
+ color: var(--primary-bg);
90
+ }
91
+ @media (max-width: 768px) {
92
+ #sierra-cloud-store {
93
+ flex-direction: column-reverse;
94
+ }
95
+ #sierra-cloud-store nav{
96
+ flex-direction: row;
97
+ }
98
+ #sierra-cloud-store nav button {
99
+ justify-content: center;
100
+ }
101
+ }
85
102
  </style>
86
103
  <main id="sierra-cloud-store" style="display: flex; gap: 1rem; height: 100%; min-height: 300px;">
87
- <nav style="display: flex; flex-direction: column; gap: {$isMobile ? '1rem' : '0.5rem'}; padding-top: 1rem; background-color: var(--background); border-bottom-left-radius:5px;">
104
+ <nav style="display: flex; gap: {$isMobile ? '1rem' : '0.5rem'}; padding-top: 1rem; background-color: var(--background); border-bottom-left-radius:5px;">
88
105
  {#each tabs as tab}
89
106
  <button
90
107
  use:buttonRipple
@@ -95,16 +112,16 @@
95
112
  }))
96
113
  }
97
114
  style="
98
- width:100%; padding: 0.1rem 0.5rem;
99
- {$fileInputStore.disabledMenuItem?.includes(tab.name) ? 'display: none;' : 'display: flex;align-items: center; gap: 0.5rem;'}
115
+ width:100%; padding:{$isMobile? '0.5rem':' 0.1rem 0.5rem'};
116
+ {$fileInputStore.disabledMenuItem?.includes(tab.name) ? 'display: none;' : 'display: flex; align-items: center; gap: 0.5rem;'}
100
117
  "
101
118
  class={`sierra-text-ellipsis ${$fileInputStore.activeMenu === tab.name ? 'icon-active' : ''}`}
102
119
  >
103
- <i class={tab.icon} style="font-size: {$isMobile ? '' : '10px'}; color: var(--icon-theme);"></i>
120
+ <i class={tab.icon} style="font-size: {$isMobile ? '15px' : '10px'}; "></i>
104
121
  {$isMobile ? '' : tab.name}
105
122
  </button>
106
123
  {/each}
107
- <Storage hidden={$isMobile} bind:this={childFunctionRef}/>
124
+ <Storage hidden={$isMobile || $isTablet} bind:this={childFunctionRef}/>
108
125
  </nav>
109
126
  <Previews {media} />
110
127
  </main>
@@ -33,7 +33,7 @@
33
33
  {:else}
34
34
  <p>No media available.</p>
35
35
  {/if}
36
- <div hidden={itemCount === 0} style="position: absolute; bottom: 0; right: 0;padding: 2px 5px; box-shadow: var(--box-shadow); background: var(--background-secondary); z-index: 1;">
36
+ <div hidden={itemCount === 0} style="position: absolute; bottom: 0; right: 0;padding: 2px 5px; box-shadow: var(--box-shadow); background: var(--background); z-index: 1;">
37
37
  {itemCount} {itemCount === 1 ? 'item' : 'items'} selected ({totalSizeMB} MB)
38
38
  </div>
39
39
  </div>
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
- import {Backdrop,Wrapper,fileInputStore, FileInput, User, setToastMessage} from '../../../index.js'
2
+ import {Backdrop,Wrapper,fileInputStore, LinearProgress,FileInput, User, setToastMessage, Tabs} from '../../../index.js'
3
3
  import CloudStore from './Cloud/cloudStore.svelte';
4
- import Controls from './controls.svelte';
4
+ import Actions from './ActionsMenu/Actions.svelte';
5
5
 
6
6
  let processing: boolean = false;
7
7
 
@@ -36,7 +36,7 @@
36
36
 
37
37
  fileInputStore.update(store => {
38
38
  store.selectedFiles = [];
39
- store.activeTab = 'cloud';
39
+ store.activeTab = 'Cloud';
40
40
  store.requestReload = true;
41
41
  return store;
42
42
  });
@@ -48,13 +48,30 @@
48
48
  }
49
49
  </script>
50
50
 
51
+
52
+ {#snippet Cloud()}
53
+ <CloudStore bind:processing />
54
+ {/snippet}
55
+
56
+ {#snippet Upload()}
57
+ <FileInput bind:processing onclick={handleUpload} />
58
+ {/snippet}
59
+
60
+ {#snippet actions()}
61
+ <Actions bind:processing />
62
+ {/snippet}
63
+
51
64
  <Backdrop bind:open={$fileInputStore.uploadModalOpen} zIndex={15}>
52
65
  <Wrapper maxWidth="700px" minHeight="300px" padding="0px">
53
- <Controls bind:processing />
54
- {#if $fileInputStore.activeTab === 'cloud'}
55
- <CloudStore bind:processing />
56
- {:else}
57
- <FileInput bind:processing onclick={handleUpload} />
58
- {/if}
66
+ <Tabs
67
+ bind:active={$fileInputStore.activeTab}
68
+ tabs={[
69
+ { key: 'Cloud', title: 'Cloud', icon: 'fa-cloud' },
70
+ { key: 'Upload', title: 'Upload', icon: 'fa-plus' }
71
+ ]}
72
+ snippets={{ Cloud, Upload }}
73
+ actions={actions}
74
+ />
75
+ {#if processing}<LinearProgress />{/if}
59
76
  </Wrapper>
60
77
  </Backdrop>
@@ -1,7 +1,7 @@
1
1
  <script>
2
2
  import './main.css';
3
3
  import { onMount } from 'svelte';
4
- import {LinearProgress, isLoading, isMobile, Modal, Toast, theme,FilePicker} from '../../../index.js'
4
+ import {LinearProgress, isLoading, isMobile, isTablet, Modal, Toast, theme,FilePicker} 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';
@@ -23,10 +23,12 @@
23
23
  toggleMenuSize = "25px",
24
24
  } = $props();
25
25
 
26
-
26
+ let isSmallscreen = $state(true);
27
27
  let isMenuOpen = $state(false);
28
+
28
29
  $effect(() => {
29
- if ($isMobile) isMenuOpen = false;
30
+ isSmallscreen = $isMobile || $isTablet;
31
+ if (isSmallscreen) isMenuOpen = false;
30
32
  if ($theme){
31
33
  document.body.setAttribute('data-theme', $theme);
32
34
  localStorage.setItem('theme', $theme);
@@ -35,7 +37,7 @@
35
37
 
36
38
  onMount(() => {
37
39
  if (typeof localStorage !== 'undefined') {
38
- if(!$isMobile){
40
+ if(!isSmallscreen){
39
41
  const stored = localStorage.getItem('isMenuOpen');
40
42
  if (stored === null) {
41
43
  localStorage.setItem('isMenuOpen', 'true');
@@ -58,13 +60,13 @@
58
60
 
59
61
  const toggleMenu = () => {
60
62
  isMenuOpen = !isMenuOpen;
61
- if($isMobile) return;
63
+ if(isSmallscreen) return;
62
64
  if (typeof localStorage !== 'undefined') {
63
65
  localStorage.setItem('isMenuOpen', isMenuOpen.toString());
64
66
  }
65
67
  };
66
68
  const closeMobileMenu = () => {
67
- if ($isMobile && isMenuOpen) isMenuOpen = false;
69
+ if (isSmallscreen && isMenuOpen) isMenuOpen = false;
68
70
  };
69
71
  </script>
70
72
 
@@ -90,7 +92,7 @@
90
92
  class="menu"
91
93
  data-label="Menu Container"
92
94
  style={
93
- $isMobile
95
+ isSmallscreen
94
96
  ? `width:300px; transform: translateX(${isMenuOpen ? '0%' : '-100%'}); transition: transform 0.3s ease; position: fixed; left: 0; padding-bottom: 50px`
95
97
  : `width: ${isMenuOpen ? '300px' : '70px'}; transition: width 0.3s ease;`
96
98
  }
package/dist/index.d.ts CHANGED
@@ -25,7 +25,7 @@ export { default as Toast } from './components/Core/Alerts/Toast/toast.svelte';
25
25
  export { default as SiteUnderMaintenance } from './components/Core/Alerts/site-under-maintenance/site-under-maintenance.svelte';
26
26
  export { default as MenuItem } from './components/Core/Menus/MenuItem/menuItem.svelte';
27
27
  export { default as DropdownContainer } from './components/Core/Menus/DropdownContainer/dropdown.svelte';
28
- export { default as UserMenu } from './components/Core/Menus/UserMenu/profile.svelte';
28
+ export { default as Tabs } from './components/Core/Menus/Tabs/main.svelte';
29
29
  export { default as Time } from './components/Core/others/Clock/Time/time.svelte';
30
30
  export { default as Date } from './components/Core/others/Clock/Date/date.svelte';
31
31
  export { default as Hr } from './components/Core/Form/Hr/hr.svelte';
@@ -33,7 +33,7 @@ export { default as Editor } from './components/Modules/Editor/main.svelte';
33
33
  export { default as Layout } from './components/Modules/Layout/main.svelte';
34
34
  export { default as FilePicker } from './components/Modules/FilePicker/main.svelte';
35
35
  export { isLoading, isLoggedIn, theme, } from './stores/core/general.js';
36
- export { isMobile } from './stores/core/ismobile.js';
36
+ export { isMobile, isTablet, isDesktop } from './stores/core/deviceWidth.js';
37
37
  export { User, resetUserStore } from './stores/core/user.js';
38
38
  export { modalStore, resetModalStore } from './stores/core/modal.js';
39
39
  export { editorStore, resetEditorStore } from './stores/modules/editor.js';
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ export { default as SiteUnderMaintenance } from './components/Core/Alerts/site-u
32
32
  //Menus
33
33
  export { default as MenuItem } from './components/Core/Menus/MenuItem/menuItem.svelte';
34
34
  export { default as DropdownContainer } from './components/Core/Menus/DropdownContainer/dropdown.svelte';
35
- export { default as UserMenu } from './components/Core/Menus/UserMenu/profile.svelte';
35
+ export { default as Tabs } from './components/Core/Menus/Tabs/main.svelte';
36
36
  //others
37
37
  export { default as Time } from './components/Core/others/Clock/Time/time.svelte';
38
38
  export { default as Date } from './components/Core/others/Clock/Date/date.svelte';
@@ -44,7 +44,7 @@ export { default as FilePicker } from './components/Modules/FilePicker/main.svel
44
44
  //#######################STORES########################
45
45
  //Core
46
46
  export { isLoading, isLoggedIn, theme, } from './stores/core/general.js';
47
- export { isMobile } from './stores/core/ismobile.js';
47
+ export { isMobile, isTablet, isDesktop } from './stores/core/deviceWidth.js';
48
48
  export { User, resetUserStore } from './stores/core/user.js';
49
49
  export { modalStore, resetModalStore } from './stores/core/modal.js';
50
50
  //Modules
@@ -0,0 +1,6 @@
1
+ export const isMobile: import("svelte/store").Writable<boolean>;
2
+ export const isTablet: import("svelte/store").Writable<boolean>;
3
+ export const isDesktop: import("svelte/store").Writable<boolean>;
4
+ export const BP_MOBILE: 480;
5
+ export const BP_TABLET: 768;
6
+ export const BP_DESKTOP: 1024;
@@ -0,0 +1,26 @@
1
+ import { writable } from 'svelte/store';
2
+ import { browser } from '$app/environment';
3
+
4
+ export const isMobile = writable(true);
5
+ export const isTablet = writable(true);
6
+ export const isDesktop = writable(false);
7
+
8
+ export const BP_MOBILE = 480;
9
+ export const BP_TABLET = 768;
10
+ export const BP_DESKTOP = 1024;
11
+
12
+
13
+ if (browser) {
14
+ const updateDevice = () => {
15
+ const width = window.innerWidth;
16
+
17
+ isMobile.set(width < BP_MOBILE);
18
+ isTablet.set(width >= BP_MOBILE && width < BP_DESKTOP);
19
+ isDesktop.set(width >= BP_DESKTOP);
20
+ };
21
+
22
+ updateDevice();
23
+ window.addEventListener('resize', updateDevice);
24
+
25
+ // return () => window.removeEventListener('resize', updateDevice);
26
+ }
@@ -1,4 +1,7 @@
1
1
  export type EditorState = {
2
+ content: any;
3
+ export: boolean;
4
+ onExport: any;
2
5
  r2_key: string;
3
6
  serverGetUrl: string;
4
7
  serverUploadUrl: string;
@@ -1,5 +1,8 @@
1
1
  import { writable } from 'svelte/store';
2
2
  const defaultEditorState = {
3
+ content: {},
4
+ export: false,
5
+ onExport: () => { },
3
6
  r2_key: '',
4
7
  serverGetUrl: '',
5
8
  serverUploadUrl: '',
@@ -13,7 +13,7 @@ export type FileInputState = {
13
13
  selectedFiles: File[];
14
14
  sizeConstraint: number;
15
15
  uploadType: Array<'image' | 'audio' | 'video' | 'documents' | 'others'>;
16
- activeTab: 'cloud' | 'upload';
16
+ activeTab: 'Cloud' | 'Upload';
17
17
  activeMenu: 'Documents' | 'Music' | 'Pictures' | 'Videos' | 'Others';
18
18
  disabledMenuItem: Array<'Music' | 'Documents' | 'Pictures' | 'Videos' | 'Others'> | null;
19
19
  manage: boolean;
@@ -5,7 +5,7 @@ const defaultFileInputState = {
5
5
  sizeConstraint: 10 * 1024 * 1024,
6
6
  uploadType: ['image', 'audio', 'video', 'documents', 'others'],
7
7
  // FilePicker
8
- activeTab: 'cloud',
8
+ activeTab: 'Cloud',
9
9
  activeMenu: 'Documents',
10
10
  disabledMenuItem: null,
11
11
  manage: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sierra-95/svelte-scaffold",
3
- "version": "1.0.32",
3
+ "version": "1.0.34",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",
@@ -1,35 +0,0 @@
1
- <script lang="ts">
2
- import {DropdownContainer} from '../../../../index.js';
3
-
4
- let {
5
- top = '150%',
6
- width = '300px',
7
- iconSize = '30px',
8
- iconBg = 'var(--primary-bg)',
9
- user = $bindable({}),
10
- open = $bindable(false),
11
- children = null,
12
- } = $props();
13
-
14
- const handleClick = () => {
15
- open = !open;
16
- };
17
- </script>
18
-
19
- <DropdownContainer bind:open {top} {width}>
20
- {#snippet dropdownTrigger()}
21
- <button aria-label="none" onclick={handleClick}>
22
- <i style="font-size: {iconSize}; color: {iconBg}" class="fa-solid fa-user"></i>
23
- </button>
24
- {/snippet}
25
- <div style="padding:15px; border-bottom:1px solid var(--border);">
26
- {#if Object.keys(user).length > 0}
27
- {#each Object.entries(user) as [key, value], i}
28
- <p>{value}</p>
29
- {/each}
30
- {:else}
31
- <p>No user info</p>
32
- {/if}
33
- </div>
34
- {@render children?.()}
35
- </DropdownContainer>
@@ -1,11 +0,0 @@
1
- declare const Profile: import("svelte").Component<{
2
- top?: string;
3
- width?: string;
4
- iconSize?: string;
5
- iconBg?: string;
6
- user?: Record<string, any>;
7
- open?: boolean;
8
- children?: any;
9
- }, {}, "open" | "user">;
10
- type Profile = ReturnType<typeof Profile>;
11
- export default Profile;
@@ -1,7 +0,0 @@
1
- /**
2
- * Extract all image slugs from a Tiptap JSON document.
3
- *
4
- * @param {import('@tiptap/core').JSONContent} json - Tiptap JSON content
5
- * @returns {string[]} - Array of image slugs
6
- */
7
- export function extractImagesFromJSON(json: import("@tiptap/core").JSONContent): string[];
@@ -1,30 +0,0 @@
1
- /**
2
- * Extract all image slugs from a Tiptap JSON document.
3
- *
4
- * @param {import('@tiptap/core').JSONContent} json - Tiptap JSON content
5
- * @returns {string[]} - Array of image slugs
6
- */
7
-
8
- export function extractImagesFromJSON(json) {
9
- const slugs = new Set();
10
-
11
- /**
12
- * Recursively walk a node and collect image slugs
13
- * @param {any} node - Node in the JSON tree
14
- */
15
-
16
- function walk(node) {
17
- if (!node) return;
18
- if (node.type === 'image' && typeof node.attrs?.src === 'string') {
19
- const url = node.attrs.src;
20
- const slug = url.split('/').pop();
21
- if (slug) slugs.add(slug);
22
- }
23
- if (node.content && Array.isArray(node.content)) {
24
- node.content.forEach(walk);
25
- }
26
- }
27
-
28
- walk(json);
29
- return [...slugs];
30
- }
@@ -1,28 +0,0 @@
1
- <script lang="ts">
2
- import { setToastMessage,isLoading, Button} from '../../../index.js';
3
- import { exractContent } from './tools.js';
4
-
5
- import type { Editor } from "@tiptap/core";
6
- export let editor: Editor;
7
- export let exportText: string;
8
- export let content: any = {};
9
-
10
- $: disabled = $isLoading || editor?.isEmpty;
11
-
12
- async function onSave() {
13
- try {
14
- isLoading.set(true);
15
- content = await exractContent(editor);
16
- }catch (error) {
17
- setToastMessage('error', 'An error occurred while saving.');
18
- } finally {
19
- isLoading.set(false);
20
- }
21
- }
22
-
23
- </script>
24
-
25
- <Button
26
- onclick={onSave}
27
- disabled={disabled}
28
- >{exportText}</Button>
@@ -1,95 +0,0 @@
1
- <script lang="ts">
2
- import {fileInputStore, LinearProgress, resetFileInputStore, DropdownContainer, MenuItem, buttonRipple} from "../../../index.js";
3
- import FileProperties from "./ActionsMenu/file_properties.svelte";
4
- import DownloadMedia from "./ActionsMenu/download_media.svelte";
5
- import DeleteMedia from "./ActionsMenu/delete_media.svelte";
6
-
7
- let {
8
- processing = $bindable(),
9
- } = $props();
10
-
11
- const menuItems = [
12
- {
13
- id: 'cloud',
14
- label: 'Cloud',
15
- },
16
- {
17
- id: 'upload',
18
- label: 'Upload',
19
- },
20
- ] as const;
21
-
22
- function handleSelect() {
23
- fileInputStore.update(store => ({
24
- ...store,
25
- submissionComplete: true,
26
- uploadModalOpen: false
27
- }));
28
- }
29
-
30
- const iconSize = '15px';
31
- let showProperties = $state(false);
32
- let openActionsMenu = $state(false);
33
- let disableActions = $state(true);
34
- $effect(() => {
35
- if($fileInputStore.submissions.length > 0 && $fileInputStore.activeTab === 'cloud'){
36
- disableActions = false;
37
- } else {
38
- disableActions = true;
39
- }
40
- });
41
- </script>
42
-
43
- <style>
44
- .file-picker-controls {
45
- display: flex;
46
- flex-wrap: wrap;
47
- justify-content: space-between;
48
- gap : 1rem;
49
- width: 100%;
50
- padding: 0.5rem 1rem;
51
- border-top-left-radius: 5px;
52
- border-top-right-radius: 5px;
53
- background-color: var(--background-tertiary);
54
- }
55
- #file-picker-controls i{
56
- font-size: 18px;
57
- }
58
- #file-picker-controls button.active{
59
- padding: 0.2rem 0.5rem;
60
- border-radius: 3px;
61
- background-color: var(--text);
62
- color: var(--background);
63
- }
64
- </style>
65
-
66
- <main id="file-picker-controls" style="display: flex; justify-content: space-between; gap:1rem;">
67
- <div class="file-picker-controls">
68
- <div style="display: flex; align-items: last baseline; gap:1rem;">
69
- {#each menuItems as item, index (item.id)}
70
- <button
71
- class={$fileInputStore.activeTab === item.id ? 'active' : ''}
72
- onclick={() => {fileInputStore.update(store => ({ ...store, activeTab: item.id }))}}
73
- ><span>{item.label}</span>
74
- </button>
75
- {/each}
76
- </div>
77
- <div style="display: flex; gap: 1rem; align-items: last baseline;">
78
- <button hidden={$fileInputStore.manage || disableActions} title="Select" onclick={handleSelect} style="color: var(--primary-bg);" aria-label="Select submissions"><i class="fa fa-check-circle-o"></i></button>
79
- {#snippet TriggerMenu()}
80
- <button disabled={disableActions} use:buttonRipple class="w-10" aria-label="Ellipsis" onclick={() => (openActionsMenu = !openActionsMenu)}>
81
- <i class="fa fa-bars"></i>
82
- </button>
83
- {/snippet}
84
- <DropdownContainer bind:open={openActionsMenu} dropdownTrigger={TriggerMenu}>
85
- <MenuItem onclick={() => { showProperties = true; openActionsMenu = false; }} icon="fa-info-circle" iconBg="var(--text)" iconSize={iconSize}>Properties</MenuItem>
86
- <DownloadMedia {iconSize} bind:processing bind:openActionsMenu/>
87
- <DeleteMedia {iconSize} bind:processing bind:openActionsMenu />
88
- </DropdownContainer>
89
- <button title="Cancel" onclick={resetFileInputStore} aria-label="Cancel"><i class="fa fa-times-circle"></i></button>
90
- </div>
91
- </div>
92
- </main>
93
- {#if processing}<LinearProgress />{/if}
94
-
95
- <FileProperties bind:showProperties />
@@ -1,5 +0,0 @@
1
- declare const Controls: import("svelte").Component<{
2
- processing?: any;
3
- }, {}, "processing">;
4
- type Controls = ReturnType<typeof Controls>;
5
- export default Controls;
@@ -1 +0,0 @@
1
- export const isMobile: import("svelte/store").Writable<boolean>;
@@ -1,14 +0,0 @@
1
- import { writable } from 'svelte/store';
2
- import { browser } from '$app/environment';
3
-
4
- export const isMobile = writable(true);
5
-
6
- if (browser) {
7
- const updateIsMobile = () => {
8
- isMobile.set(window.innerWidth < 768);
9
- };
10
- updateIsMobile();
11
- window.addEventListener('resize', updateIsMobile);
12
-
13
- // return () => window.removeEventListener('resize', updateIsMobile);
14
- }