@sierra-95/svelte-scaffold 1.0.9 → 1.0.10
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.
- package/README.md +8 -8
- package/dist/Hooks/preview.d.ts +2 -1
- package/dist/Hooks/preview.js +4 -4
- package/dist/components/Core/Alerts/Backdrop/backdrop.svelte +26 -26
- package/dist/components/Core/Alerts/Modal/modal.svelte +40 -40
- package/dist/components/Core/Alerts/Toast/toast.css +38 -38
- package/dist/components/Core/Alerts/Toast/toast.svelte +32 -32
- package/dist/components/Core/Alerts/Wrapper/wrapper.svelte +18 -18
- package/dist/components/Core/Alerts/site-under-maintenance/site-under-maintenance.svelte +33 -33
- package/dist/components/Core/Form/Hr/hr.svelte +10 -10
- package/dist/components/Core/Form/Input/FileInput/fileInput.svelte +158 -158
- package/dist/components/Core/Form/Input/FileInput/preview.svelte +50 -50
- package/dist/components/Core/Form/Input/SearchBar/search.svelte +68 -68
- package/dist/components/Core/Form/Input/input/input.svelte +16 -16
- package/dist/components/Core/Form/Input/password/password.svelte +26 -26
- package/dist/components/Core/Menus/DropdownContainer/dropdown.svelte +94 -94
- package/dist/components/Core/Menus/MenuItem/menuItem.svelte +43 -43
- package/dist/components/Core/Menus/UserMenu/profile.svelte +34 -34
- package/dist/components/Core/others/Button/Flip/button.css +50 -50
- package/dist/components/Core/others/Button/Flip/button.svelte +79 -79
- package/dist/components/Core/others/Button/Marquee/button.css +36 -36
- package/dist/components/Core/others/Button/Marquee/button.svelte +58 -58
- package/dist/components/Core/others/Button/Swipe/button.css +32 -32
- package/dist/components/Core/others/Button/Swipe/button.svelte +57 -57
- package/dist/components/Core/others/Button/default/button.css +60 -60
- package/dist/components/Core/others/Button/default/button.svelte +124 -124
- package/dist/components/Core/others/Button/select/select.svelte +28 -28
- package/dist/components/Core/others/Button/theme/theme.css +121 -121
- package/dist/components/Core/others/Button/theme/theme.svelte +67 -67
- package/dist/components/Core/others/Button/times/times.svelte +24 -24
- package/dist/components/Core/others/Clock/Date/date.svelte +25 -25
- package/dist/components/Core/others/Clock/Time/time.svelte +35 -35
- package/dist/components/Core/others/Previews/Audio/audio.svelte +61 -61
- package/dist/components/Core/others/Previews/Document/documents.svelte +36 -36
- package/dist/components/Core/others/Previews/GenericFile/genericFile.svelte +25 -25
- package/dist/components/Core/others/Previews/Image/image.svelte +26 -26
- package/dist/components/Core/others/Previews/Video/video.svelte +28 -28
- package/dist/components/Core/others/Progress/CircularProgress/CircularProgress.svelte +55 -55
- package/dist/components/Core/others/Progress/CustomProgress/customProgress.svelte +64 -64
- package/dist/components/Core/others/Progress/LinearProgress/LinearProgress.css +60 -60
- package/dist/components/Core/others/Progress/LinearProgress/LinearProgress.svelte +86 -86
- package/dist/components/Modules/Editor/Hooks/extractContent.js +14 -14
- package/dist/components/Modules/Editor/Hooks/extractImage.js +30 -30
- package/dist/components/Modules/Editor/Hooks/insertImage.js +26 -26
- package/dist/components/Modules/Editor/Hooks/insertYoutube.js +34 -34
- package/dist/components/Modules/Editor/Marks/Links/links.svelte +78 -78
- package/dist/components/Modules/Editor/Marks/TextFormatting/textFormatting.svelte +32 -32
- package/dist/components/Modules/Editor/Nodes/Headings/heading.svelte +58 -58
- package/dist/components/Modules/Editor/Nodes/History/history.svelte +21 -21
- package/dist/components/Modules/Editor/Nodes/Images/images.svelte +85 -85
- package/dist/components/Modules/Editor/Nodes/Lists/lists.svelte +30 -30
- package/dist/components/Modules/Editor/Nodes/TextAlign/textAlign.svelte +55 -55
- package/dist/components/Modules/Editor/Nodes/TextColor/styles.css +18 -18
- package/dist/components/Modules/Editor/Nodes/TextColor/textColor.svelte +88 -88
- package/dist/components/Modules/Editor/Nodes/Youtube/youtube.svelte +32 -32
- package/dist/components/Modules/Editor/colors.js +21 -21
- package/dist/components/Modules/Editor/controls.svelte +71 -71
- package/dist/components/Modules/Editor/extensions.js +59 -59
- package/dist/components/Modules/Editor/main.svelte +41 -41
- package/dist/components/Modules/Editor/save.svelte +28 -28
- package/dist/components/Modules/Editor/styles/controls.css +68 -68
- package/dist/components/Modules/Editor/styles/main.css +42 -42
- package/dist/components/Modules/Editor/tools.js +22 -22
- package/dist/components/Modules/FilePicker/cloudStore.svelte +101 -98
- package/dist/components/Modules/FilePicker/controls.svelte +167 -141
- package/dist/components/Modules/FilePicker/controls.svelte.d.ts +4 -19
- package/dist/components/Modules/FilePicker/filePicker.svelte +59 -59
- package/dist/components/Modules/FilePicker/file_properties.svelte +33 -0
- package/dist/components/Modules/FilePicker/file_properties.svelte.d.ts +11 -0
- package/dist/components/Modules/FilePicker/previews.svelte +22 -22
- package/dist/components/Modules/Layout/Header/header.css +37 -37
- package/dist/components/Modules/Layout/Header/header.svelte +31 -31
- package/dist/components/Modules/Layout/Menu/menu.css +53 -53
- package/dist/components/Modules/Layout/Menu/menu.svelte +129 -129
- package/dist/components/Modules/Layout/background.svelte +28 -28
- package/dist/components/Modules/Layout/collapse.svelte +24 -24
- package/dist/components/Modules/Layout/main.css +31 -31
- package/dist/components/Modules/Layout/main.svelte +110 -110
- package/dist/global.css +246 -246
- package/dist/index.d.ts +1 -0
- package/dist/stores/core/general.js +4 -4
- package/dist/stores/core/ismobile.js +14 -14
- package/dist/stores/core/modal.js +35 -35
- package/dist/stores/modules/fileInput.d.ts +11 -4
- package/dist/stores/modules/fileInput.js +1 -1
- package/package.json +75 -75
|
@@ -1,159 +1,159 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { onDestroy } from 'svelte';
|
|
3
|
-
import {fileInputStore, Button, setToastMessage, DOCUMENT_MIME_TYPES} from '../../../../../index.js'
|
|
4
|
-
import Preview from './preview.svelte';
|
|
5
|
-
|
|
6
|
-
const {
|
|
7
|
-
processing=$bindable(false),
|
|
8
|
-
minHeight = '300px',
|
|
9
|
-
...rest
|
|
10
|
-
} = $props();
|
|
11
|
-
|
|
12
|
-
let fileInput: HTMLInputElement;
|
|
13
|
-
|
|
14
|
-
const typeMap: Record<'image' | 'audio' | 'video' | 'documents' | 'others', string[]> = {
|
|
15
|
-
image: ['image/'],
|
|
16
|
-
audio: ['audio/'],
|
|
17
|
-
video: ['video/'],
|
|
18
|
-
documents: Array.from(DOCUMENT_MIME_TYPES),
|
|
19
|
-
others: []
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
//Validate and add files
|
|
23
|
-
function isAllowedType(file: File): boolean {
|
|
24
|
-
return $fileInputStore.uploadType.some(type => {
|
|
25
|
-
if (type === 'others') return true;
|
|
26
|
-
const prefixes = typeMap[type];
|
|
27
|
-
return prefixes.some(prefix => file.type.startsWith(prefix));
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function allowedTypes(){
|
|
32
|
-
const allowedTypes = $fileInputStore.uploadType
|
|
33
|
-
.filter(t => t !== 'others')
|
|
34
|
-
.map(t => {
|
|
35
|
-
if (t === 'documents') return 'Documents (PDF, Word, Excel, TXT)';
|
|
36
|
-
return t.charAt(0).toUpperCase() + t.slice(1);
|
|
37
|
-
})
|
|
38
|
-
.join(', ');
|
|
39
|
-
return allowedTypes;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function processFiles(files: FileList | File[]) {
|
|
43
|
-
const validFiles: File[] = [];
|
|
44
|
-
|
|
45
|
-
for (const file of files) {
|
|
46
|
-
if (!isAllowedType(file)) {
|
|
47
|
-
setToastMessage(
|
|
48
|
-
'error',
|
|
49
|
-
`"${file.name}" is not an allowed file type. Allowed types: ${allowedTypes()}`
|
|
50
|
-
);
|
|
51
|
-
continue; // skip invalid
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (file.size > $fileInputStore.sizeConstraint) {
|
|
55
|
-
setToastMessage(
|
|
56
|
-
'error',
|
|
57
|
-
`"${file.name}" exceeds the allowed file size`
|
|
58
|
-
);
|
|
59
|
-
continue; // skip oversized
|
|
60
|
-
}
|
|
61
|
-
validFiles.push(file);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (validFiles.length > 0) {
|
|
65
|
-
fileInputStore.update(state => ({
|
|
66
|
-
...state,
|
|
67
|
-
selectedFiles: [...state.selectedFiles, ...validFiles]
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
|
-
clearInput();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
//Handle file selection via input
|
|
76
|
-
function handleFileChange(event: Event) {
|
|
77
|
-
const files = (event.target as HTMLInputElement).files;
|
|
78
|
-
if (!files || files.length === 0) return;
|
|
79
|
-
processFiles(files);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
//Handle drag and drop
|
|
83
|
-
function handleDrop(event: DragEvent) {
|
|
84
|
-
event.preventDefault();
|
|
85
|
-
if (!event.dataTransfer?.files.length) return;
|
|
86
|
-
processFiles(event.dataTransfer.files);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function handleDragOver(event: DragEvent) {
|
|
90
|
-
event.preventDefault();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function clearInput() {
|
|
94
|
-
if (fileInput) {
|
|
95
|
-
fileInput.value = '';
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
//Delete selected files
|
|
99
|
-
function handleClear() {
|
|
100
|
-
fileInputStore.update(state => ({
|
|
101
|
-
...state,
|
|
102
|
-
selectedFiles: []
|
|
103
|
-
}));
|
|
104
|
-
clearInput();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
onDestroy(() => {
|
|
108
|
-
handleClear();
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
</script>
|
|
112
|
-
|
|
113
|
-
<main style="padding: 1rem; height: 100%; min-height: {minHeight};">
|
|
114
|
-
<input
|
|
115
|
-
bind:this={fileInput}
|
|
116
|
-
type="file"
|
|
117
|
-
accept={$fileInputStore.uploadType
|
|
118
|
-
.map(t => {
|
|
119
|
-
if (t === 'documents') return Array.from(DOCUMENT_MIME_TYPES).join(',');
|
|
120
|
-
if (t === 'others') return '';
|
|
121
|
-
return `${t}/*`;
|
|
122
|
-
})
|
|
123
|
-
.filter(Boolean)
|
|
124
|
-
.join(',')
|
|
125
|
-
}
|
|
126
|
-
hidden
|
|
127
|
-
multiple
|
|
128
|
-
onchange={handleFileChange}
|
|
129
|
-
/>
|
|
130
|
-
<div
|
|
131
|
-
role="none"
|
|
132
|
-
ondrop={handleDrop}
|
|
133
|
-
ondragover={handleDragOver}
|
|
134
|
-
style="border: 2px dotted var(--text-tertiary);border-radius: 0.5rem; padding: 2rem; text-align: center; cursor: pointer;"
|
|
135
|
-
onclick={() => fileInput.click()}
|
|
136
|
-
>Drag & drop image here or click to choose file
|
|
137
|
-
</div>
|
|
138
|
-
|
|
139
|
-
<Preview />
|
|
140
|
-
|
|
141
|
-
<div style="display: flex; justify-content: flex-end; gap: 2rem; margin-top: 1rem;">
|
|
142
|
-
{#if $fileInputStore.selectedFiles.length > 0}
|
|
143
|
-
<Button
|
|
144
|
-
variant="outlined"
|
|
145
|
-
color="warning"
|
|
146
|
-
onclick={handleClear}
|
|
147
|
-
>Clear All
|
|
148
|
-
</Button>
|
|
149
|
-
{/if}
|
|
150
|
-
<Button
|
|
151
|
-
endIcon="fa-cloud-arrow-up"
|
|
152
|
-
onclick={(e: MouseEvent) => {
|
|
153
|
-
rest.onclick?.(e);
|
|
154
|
-
}}
|
|
155
|
-
isLoading={processing}
|
|
156
|
-
disabled={$fileInputStore.selectedFiles.length === 0}
|
|
157
|
-
>Upload</Button>
|
|
158
|
-
</div>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onDestroy } from 'svelte';
|
|
3
|
+
import {fileInputStore, Button, setToastMessage, DOCUMENT_MIME_TYPES} from '../../../../../index.js'
|
|
4
|
+
import Preview from './preview.svelte';
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
processing=$bindable(false),
|
|
8
|
+
minHeight = '300px',
|
|
9
|
+
...rest
|
|
10
|
+
} = $props();
|
|
11
|
+
|
|
12
|
+
let fileInput: HTMLInputElement;
|
|
13
|
+
|
|
14
|
+
const typeMap: Record<'image' | 'audio' | 'video' | 'documents' | 'others', string[]> = {
|
|
15
|
+
image: ['image/'],
|
|
16
|
+
audio: ['audio/'],
|
|
17
|
+
video: ['video/'],
|
|
18
|
+
documents: Array.from(DOCUMENT_MIME_TYPES),
|
|
19
|
+
others: []
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
//Validate and add files
|
|
23
|
+
function isAllowedType(file: File): boolean {
|
|
24
|
+
return $fileInputStore.uploadType.some(type => {
|
|
25
|
+
if (type === 'others') return true;
|
|
26
|
+
const prefixes = typeMap[type];
|
|
27
|
+
return prefixes.some(prefix => file.type.startsWith(prefix));
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function allowedTypes(){
|
|
32
|
+
const allowedTypes = $fileInputStore.uploadType
|
|
33
|
+
.filter(t => t !== 'others')
|
|
34
|
+
.map(t => {
|
|
35
|
+
if (t === 'documents') return 'Documents (PDF, Word, Excel, TXT)';
|
|
36
|
+
return t.charAt(0).toUpperCase() + t.slice(1);
|
|
37
|
+
})
|
|
38
|
+
.join(', ');
|
|
39
|
+
return allowedTypes;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function processFiles(files: FileList | File[]) {
|
|
43
|
+
const validFiles: File[] = [];
|
|
44
|
+
|
|
45
|
+
for (const file of files) {
|
|
46
|
+
if (!isAllowedType(file)) {
|
|
47
|
+
setToastMessage(
|
|
48
|
+
'error',
|
|
49
|
+
`"${file.name}" is not an allowed file type. Allowed types: ${allowedTypes()}`
|
|
50
|
+
);
|
|
51
|
+
continue; // skip invalid
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (file.size > $fileInputStore.sizeConstraint) {
|
|
55
|
+
setToastMessage(
|
|
56
|
+
'error',
|
|
57
|
+
`"${file.name}" exceeds the allowed file size`
|
|
58
|
+
);
|
|
59
|
+
continue; // skip oversized
|
|
60
|
+
}
|
|
61
|
+
validFiles.push(file);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (validFiles.length > 0) {
|
|
65
|
+
fileInputStore.update(state => ({
|
|
66
|
+
...state,
|
|
67
|
+
selectedFiles: [...state.selectedFiles, ...validFiles]
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
clearInput();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
//Handle file selection via input
|
|
76
|
+
function handleFileChange(event: Event) {
|
|
77
|
+
const files = (event.target as HTMLInputElement).files;
|
|
78
|
+
if (!files || files.length === 0) return;
|
|
79
|
+
processFiles(files);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
//Handle drag and drop
|
|
83
|
+
function handleDrop(event: DragEvent) {
|
|
84
|
+
event.preventDefault();
|
|
85
|
+
if (!event.dataTransfer?.files.length) return;
|
|
86
|
+
processFiles(event.dataTransfer.files);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function handleDragOver(event: DragEvent) {
|
|
90
|
+
event.preventDefault();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function clearInput() {
|
|
94
|
+
if (fileInput) {
|
|
95
|
+
fileInput.value = '';
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//Delete selected files
|
|
99
|
+
function handleClear() {
|
|
100
|
+
fileInputStore.update(state => ({
|
|
101
|
+
...state,
|
|
102
|
+
selectedFiles: []
|
|
103
|
+
}));
|
|
104
|
+
clearInput();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
onDestroy(() => {
|
|
108
|
+
handleClear();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
</script>
|
|
112
|
+
|
|
113
|
+
<main style="padding: 1rem; height: 100%; min-height: {minHeight};">
|
|
114
|
+
<input
|
|
115
|
+
bind:this={fileInput}
|
|
116
|
+
type="file"
|
|
117
|
+
accept={$fileInputStore.uploadType
|
|
118
|
+
.map(t => {
|
|
119
|
+
if (t === 'documents') return Array.from(DOCUMENT_MIME_TYPES).join(',');
|
|
120
|
+
if (t === 'others') return '';
|
|
121
|
+
return `${t}/*`;
|
|
122
|
+
})
|
|
123
|
+
.filter(Boolean)
|
|
124
|
+
.join(',')
|
|
125
|
+
}
|
|
126
|
+
hidden
|
|
127
|
+
multiple
|
|
128
|
+
onchange={handleFileChange}
|
|
129
|
+
/>
|
|
130
|
+
<div
|
|
131
|
+
role="none"
|
|
132
|
+
ondrop={handleDrop}
|
|
133
|
+
ondragover={handleDragOver}
|
|
134
|
+
style="border: 2px dotted var(--text-tertiary);border-radius: 0.5rem; padding: 2rem; text-align: center; cursor: pointer;"
|
|
135
|
+
onclick={() => fileInput.click()}
|
|
136
|
+
>Drag & drop image here or click to choose file
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<Preview />
|
|
140
|
+
|
|
141
|
+
<div style="display: flex; justify-content: flex-end; gap: 2rem; margin-top: 1rem;">
|
|
142
|
+
{#if $fileInputStore.selectedFiles.length > 0}
|
|
143
|
+
<Button
|
|
144
|
+
variant="outlined"
|
|
145
|
+
color="warning"
|
|
146
|
+
onclick={handleClear}
|
|
147
|
+
>Clear All
|
|
148
|
+
</Button>
|
|
149
|
+
{/if}
|
|
150
|
+
<Button
|
|
151
|
+
endIcon="fa-cloud-arrow-up"
|
|
152
|
+
onclick={(e: MouseEvent) => {
|
|
153
|
+
rest.onclick?.(e);
|
|
154
|
+
}}
|
|
155
|
+
isLoading={processing}
|
|
156
|
+
disabled={$fileInputStore.selectedFiles.length === 0}
|
|
157
|
+
>Upload</Button>
|
|
158
|
+
</div>
|
|
159
159
|
</main>
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {fileInputStore, PreviewAudio,PreviewDocument,PreviewImage,PreviewVideo, PreviewGenericFile, DOCUMENT_MIME_TYPES} from '../../../../../index.js';
|
|
3
|
-
|
|
4
|
-
function getMediaCategory(file: File):
|
|
5
|
-
'Audio' | 'Documents' | 'Images' | 'Videos' | 'Others' {
|
|
6
|
-
|
|
7
|
-
if (file.type.startsWith('audio/')) return 'Audio';
|
|
8
|
-
if (file.type.startsWith('image/')) return 'Images';
|
|
9
|
-
if (file.type.startsWith('video/')) return 'Videos';
|
|
10
|
-
if (DOCUMENT_MIME_TYPES.has(file.type)) return 'Documents';
|
|
11
|
-
|
|
12
|
-
return 'Others';
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
$: media = $fileInputStore.selectedFiles.reduce(
|
|
16
|
-
(acc, file) => {
|
|
17
|
-
acc[getMediaCategory(file)].push(file);
|
|
18
|
-
return acc;
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
Audio: [] as File[],
|
|
22
|
-
Documents: [] as File[],
|
|
23
|
-
Images: [] as File[],
|
|
24
|
-
Videos: [] as File[],
|
|
25
|
-
Others: [] as File[],
|
|
26
|
-
}
|
|
27
|
-
);
|
|
28
|
-
</script>
|
|
29
|
-
|
|
30
|
-
<div style="max-height: 300px; overflow-y: auto; padding: 0.5rem;">
|
|
31
|
-
{#if media.Audio.length > 0}
|
|
32
|
-
<h3 style="margin: 1rem 0rem;">Audio</h3>
|
|
33
|
-
<PreviewAudio buttonTimes urlsOnly={false} {media}/>
|
|
34
|
-
{/if}
|
|
35
|
-
{#if media.Documents.length > 0}
|
|
36
|
-
<h3 style="margin: 1rem 0rem;">Documents</h3>
|
|
37
|
-
<PreviewDocument buttonTimes urlsOnly={false} {media}/>
|
|
38
|
-
{/if}
|
|
39
|
-
{#if media.Images.length > 0}
|
|
40
|
-
<h3 style="margin: 1rem 0rem;">Images</h3>
|
|
41
|
-
<PreviewImage buttonTimes urlsOnly={false} {media}/>
|
|
42
|
-
{/if}
|
|
43
|
-
{#if media.Videos.length > 0}
|
|
44
|
-
<h3 style="margin: 1rem 0rem;">Videos</h3>
|
|
45
|
-
<PreviewVideo buttonTimes urlsOnly={false} {media}/>
|
|
46
|
-
{/if}
|
|
47
|
-
{#if media.Others.length > 0}
|
|
48
|
-
<h3 style="margin: 1rem 0rem;">Other Files</h3>
|
|
49
|
-
<PreviewGenericFile buttonTimes urlsOnly={false} {media}/>
|
|
50
|
-
{/if}
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {fileInputStore, PreviewAudio,PreviewDocument,PreviewImage,PreviewVideo, PreviewGenericFile, DOCUMENT_MIME_TYPES} from '../../../../../index.js';
|
|
3
|
+
|
|
4
|
+
function getMediaCategory(file: File):
|
|
5
|
+
'Audio' | 'Documents' | 'Images' | 'Videos' | 'Others' {
|
|
6
|
+
|
|
7
|
+
if (file.type.startsWith('audio/')) return 'Audio';
|
|
8
|
+
if (file.type.startsWith('image/')) return 'Images';
|
|
9
|
+
if (file.type.startsWith('video/')) return 'Videos';
|
|
10
|
+
if (DOCUMENT_MIME_TYPES.has(file.type)) return 'Documents';
|
|
11
|
+
|
|
12
|
+
return 'Others';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
$: media = $fileInputStore.selectedFiles.reduce(
|
|
16
|
+
(acc, file) => {
|
|
17
|
+
acc[getMediaCategory(file)].push(file);
|
|
18
|
+
return acc;
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
Audio: [] as File[],
|
|
22
|
+
Documents: [] as File[],
|
|
23
|
+
Images: [] as File[],
|
|
24
|
+
Videos: [] as File[],
|
|
25
|
+
Others: [] as File[],
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<div style="max-height: 300px; overflow-y: auto; padding: 0.5rem;">
|
|
31
|
+
{#if media.Audio.length > 0}
|
|
32
|
+
<h3 style="margin: 1rem 0rem;">Audio</h3>
|
|
33
|
+
<PreviewAudio buttonTimes urlsOnly={false} {media}/>
|
|
34
|
+
{/if}
|
|
35
|
+
{#if media.Documents.length > 0}
|
|
36
|
+
<h3 style="margin: 1rem 0rem;">Documents</h3>
|
|
37
|
+
<PreviewDocument buttonTimes urlsOnly={false} {media}/>
|
|
38
|
+
{/if}
|
|
39
|
+
{#if media.Images.length > 0}
|
|
40
|
+
<h3 style="margin: 1rem 0rem;">Images</h3>
|
|
41
|
+
<PreviewImage buttonTimes urlsOnly={false} {media}/>
|
|
42
|
+
{/if}
|
|
43
|
+
{#if media.Videos.length > 0}
|
|
44
|
+
<h3 style="margin: 1rem 0rem;">Videos</h3>
|
|
45
|
+
<PreviewVideo buttonTimes urlsOnly={false} {media}/>
|
|
46
|
+
{/if}
|
|
47
|
+
{#if media.Others.length > 0}
|
|
48
|
+
<h3 style="margin: 1rem 0rem;">Other Files</h3>
|
|
49
|
+
<PreviewGenericFile buttonTimes urlsOnly={false} {media}/>
|
|
50
|
+
{/if}
|
|
51
51
|
</div>
|
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {isMobile} from '../../../../../index.js';
|
|
3
|
-
let {
|
|
4
|
-
width = '250px',
|
|
5
|
-
height = '30px',
|
|
6
|
-
value = $bindable(''),
|
|
7
|
-
placeholder = 'Search',
|
|
8
|
-
isVisible = $bindable(!$isMobile),
|
|
9
|
-
...rest
|
|
10
|
-
} = $props();
|
|
11
|
-
|
|
12
|
-
$effect(() => {
|
|
13
|
-
isVisible = $isMobile ? false : true;
|
|
14
|
-
});
|
|
15
|
-
</script>
|
|
16
|
-
<style>
|
|
17
|
-
#sierra-search-bar #sierra-search-input{
|
|
18
|
-
width: 100%;
|
|
19
|
-
height: 100%;
|
|
20
|
-
border-top-left-radius: 25px;
|
|
21
|
-
border-bottom-left-radius: 25px;
|
|
22
|
-
background: transparent;
|
|
23
|
-
border: 1px solid var(--input-border);
|
|
24
|
-
border-right: none;
|
|
25
|
-
}
|
|
26
|
-
#sierra-search-bar div{
|
|
27
|
-
display: flex;
|
|
28
|
-
align-items: center;
|
|
29
|
-
gap: 10px;
|
|
30
|
-
padding: 0px 10px 0px 0px; /*top right bottom left */
|
|
31
|
-
height: 100%;
|
|
32
|
-
border: 1px solid var(--input-border);
|
|
33
|
-
border-left: none;
|
|
34
|
-
border-top-right-radius: 25px;
|
|
35
|
-
border-bottom-right-radius: 25px;
|
|
36
|
-
}
|
|
37
|
-
</style>
|
|
38
|
-
<main id="sierra-search-bar"
|
|
39
|
-
style="
|
|
40
|
-
height: {height};
|
|
41
|
-
width: {width}; {isVisible? 'display:flex;' : 'display:none;'}
|
|
42
|
-
transform: translateX({isVisible && isMobile ? '0' : '100%'});
|
|
43
|
-
opacity: {isVisible && isMobile ? 1 : 0};
|
|
44
|
-
transition: transform 0.3s ease, opacity 0.3s ease;
|
|
45
|
-
">
|
|
46
|
-
<input
|
|
47
|
-
id="sierra-search-input"
|
|
48
|
-
type="text"
|
|
49
|
-
bind:value={value}
|
|
50
|
-
placeholder={placeholder}
|
|
51
|
-
/>
|
|
52
|
-
<div>
|
|
53
|
-
{#if value}
|
|
54
|
-
<button aria-label="Clear search" onclick={() => value = ''} style="color: var(--primary-bg);">
|
|
55
|
-
<i class="fa fa-times-circle"></i>
|
|
56
|
-
</button>
|
|
57
|
-
{/if}
|
|
58
|
-
<button
|
|
59
|
-
aria-label="Search"
|
|
60
|
-
onclick={(e: MouseEvent) => {
|
|
61
|
-
rest.onclick?.(e);
|
|
62
|
-
}}
|
|
63
|
-
><i class="fa fa-search"></i>
|
|
64
|
-
</button>
|
|
65
|
-
</div>
|
|
66
|
-
</main>
|
|
67
|
-
<button aria-label="Show search bar" onclick={() => isVisible = true} style="{isVisible? 'display:none;' : ''}">
|
|
68
|
-
<i class="fa fa-search"></i>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {isMobile} from '../../../../../index.js';
|
|
3
|
+
let {
|
|
4
|
+
width = '250px',
|
|
5
|
+
height = '30px',
|
|
6
|
+
value = $bindable(''),
|
|
7
|
+
placeholder = 'Search',
|
|
8
|
+
isVisible = $bindable(!$isMobile),
|
|
9
|
+
...rest
|
|
10
|
+
} = $props();
|
|
11
|
+
|
|
12
|
+
$effect(() => {
|
|
13
|
+
isVisible = $isMobile ? false : true;
|
|
14
|
+
});
|
|
15
|
+
</script>
|
|
16
|
+
<style>
|
|
17
|
+
#sierra-search-bar #sierra-search-input{
|
|
18
|
+
width: 100%;
|
|
19
|
+
height: 100%;
|
|
20
|
+
border-top-left-radius: 25px;
|
|
21
|
+
border-bottom-left-radius: 25px;
|
|
22
|
+
background: transparent;
|
|
23
|
+
border: 1px solid var(--input-border);
|
|
24
|
+
border-right: none;
|
|
25
|
+
}
|
|
26
|
+
#sierra-search-bar div{
|
|
27
|
+
display: flex;
|
|
28
|
+
align-items: center;
|
|
29
|
+
gap: 10px;
|
|
30
|
+
padding: 0px 10px 0px 0px; /*top right bottom left */
|
|
31
|
+
height: 100%;
|
|
32
|
+
border: 1px solid var(--input-border);
|
|
33
|
+
border-left: none;
|
|
34
|
+
border-top-right-radius: 25px;
|
|
35
|
+
border-bottom-right-radius: 25px;
|
|
36
|
+
}
|
|
37
|
+
</style>
|
|
38
|
+
<main id="sierra-search-bar"
|
|
39
|
+
style="
|
|
40
|
+
height: {height};
|
|
41
|
+
width: {width}; {isVisible? 'display:flex;' : 'display:none;'}
|
|
42
|
+
transform: translateX({isVisible && isMobile ? '0' : '100%'});
|
|
43
|
+
opacity: {isVisible && isMobile ? 1 : 0};
|
|
44
|
+
transition: transform 0.3s ease, opacity 0.3s ease;
|
|
45
|
+
">
|
|
46
|
+
<input
|
|
47
|
+
id="sierra-search-input"
|
|
48
|
+
type="text"
|
|
49
|
+
bind:value={value}
|
|
50
|
+
placeholder={placeholder}
|
|
51
|
+
/>
|
|
52
|
+
<div>
|
|
53
|
+
{#if value}
|
|
54
|
+
<button aria-label="Clear search" onclick={() => value = ''} style="color: var(--primary-bg);">
|
|
55
|
+
<i class="fa fa-times-circle"></i>
|
|
56
|
+
</button>
|
|
57
|
+
{/if}
|
|
58
|
+
<button
|
|
59
|
+
aria-label="Search"
|
|
60
|
+
onclick={(e: MouseEvent) => {
|
|
61
|
+
rest.onclick?.(e);
|
|
62
|
+
}}
|
|
63
|
+
><i class="fa fa-search"></i>
|
|
64
|
+
</button>
|
|
65
|
+
</div>
|
|
66
|
+
</main>
|
|
67
|
+
<button aria-label="Show search bar" onclick={() => isVisible = true} style="{isVisible? 'display:none;' : ''}">
|
|
68
|
+
<i class="fa fa-search"></i>
|
|
69
69
|
</button>
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
export let id: string = '';
|
|
3
|
-
export let label: string = '';
|
|
4
|
-
export let value: string | number = '';
|
|
5
|
-
export let type: string = 'text';
|
|
6
|
-
export let placeholder: string = '';
|
|
7
|
-
</script>
|
|
8
|
-
|
|
9
|
-
<label class="sierra-input" for={id}>{label}
|
|
10
|
-
<input
|
|
11
|
-
id={id}
|
|
12
|
-
name={id}
|
|
13
|
-
type={type}
|
|
14
|
-
bind:value={value}
|
|
15
|
-
placeholder={placeholder}
|
|
16
|
-
/>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export let id: string = '';
|
|
3
|
+
export let label: string = '';
|
|
4
|
+
export let value: string | number = '';
|
|
5
|
+
export let type: string = 'text';
|
|
6
|
+
export let placeholder: string = '';
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<label class="sierra-input" for={id}>{label}
|
|
10
|
+
<input
|
|
11
|
+
id={id}
|
|
12
|
+
name={id}
|
|
13
|
+
type={type}
|
|
14
|
+
bind:value={value}
|
|
15
|
+
placeholder={placeholder}
|
|
16
|
+
/>
|
|
17
17
|
</label>
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
export let id: string = '';
|
|
3
|
-
export let label: string = '';
|
|
4
|
-
export let value: string = '';
|
|
5
|
-
export let placeholder: string = '';
|
|
6
|
-
let show: boolean = false;
|
|
7
|
-
</script>
|
|
8
|
-
|
|
9
|
-
<label class="sierra-input" for={id}>{label}
|
|
10
|
-
<div style="position: relative; background-color: transparent;">
|
|
11
|
-
<input
|
|
12
|
-
style="width: 100%;"
|
|
13
|
-
type={show ? "text" : "password"}
|
|
14
|
-
id={id}
|
|
15
|
-
name={id}
|
|
16
|
-
bind:value={value}
|
|
17
|
-
placeholder={placeholder}
|
|
18
|
-
/>
|
|
19
|
-
<button on:click|preventDefault={() => show = !show}>
|
|
20
|
-
{#if show}
|
|
21
|
-
<i class="fa fa-eye"></i>
|
|
22
|
-
{:else}
|
|
23
|
-
<i class="fa fa-eye-slash"></i>
|
|
24
|
-
{/if}
|
|
25
|
-
</button>
|
|
26
|
-
</div>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export let id: string = '';
|
|
3
|
+
export let label: string = '';
|
|
4
|
+
export let value: string = '';
|
|
5
|
+
export let placeholder: string = '';
|
|
6
|
+
let show: boolean = false;
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<label class="sierra-input" for={id}>{label}
|
|
10
|
+
<div style="position: relative; background-color: transparent;">
|
|
11
|
+
<input
|
|
12
|
+
style="width: 100%;"
|
|
13
|
+
type={show ? "text" : "password"}
|
|
14
|
+
id={id}
|
|
15
|
+
name={id}
|
|
16
|
+
bind:value={value}
|
|
17
|
+
placeholder={placeholder}
|
|
18
|
+
/>
|
|
19
|
+
<button on:click|preventDefault={() => show = !show}>
|
|
20
|
+
{#if show}
|
|
21
|
+
<i class="fa fa-eye"></i>
|
|
22
|
+
{:else}
|
|
23
|
+
<i class="fa fa-eye-slash"></i>
|
|
24
|
+
{/if}
|
|
25
|
+
</button>
|
|
26
|
+
</div>
|
|
27
27
|
</label>
|