quasar-ui-danx 0.4.92 → 0.4.94
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/dist/danx.es.js +7149 -6414
- package/dist/danx.es.js.map +1 -1
- package/dist/danx.umd.js +90 -90
- package/dist/danx.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/ActionTable/Form/Fields/NumberField.vue +36 -8
- package/src/components/Utility/Dialogs/FullscreenCarouselDialog.vue +123 -136
- package/src/components/Utility/Files/CarouselHeader.vue +80 -0
- package/src/components/Utility/Files/FilePreview.vue +76 -21
- package/src/components/Utility/Files/FileRenderer.vue +111 -0
- package/src/components/Utility/Files/ThumbnailStrip.vue +64 -0
- package/src/components/Utility/Files/TranscodeNavigator.vue +175 -0
- package/src/components/Utility/Files/VirtualCarousel.vue +237 -0
- package/src/components/Utility/Files/index.ts +5 -0
- package/src/components/Utility/Widgets/LabelPillWidget.vue +10 -0
- package/src/composables/index.ts +4 -0
- package/src/composables/useFileNavigation.ts +129 -0
- package/src/composables/useKeyboardNavigation.ts +58 -0
- package/src/composables/useThumbnailScroll.ts +43 -0
- package/src/composables/useVirtualCarousel.ts +93 -0
- package/src/helpers/filePreviewHelpers.ts +107 -0
- package/src/helpers/formats/parsers.ts +5 -2
- package/src/helpers/index.ts +1 -0
- package/src/types/files.d.ts +38 -0
- package/src/types/widgets.d.ts +1 -1
- package/src/vue-plugin.ts +1 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { computed, ref, Ref } from "vue";
|
|
2
|
+
import { FileNavigationParent, FileNavigationState, UploadedFile } from "../types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Composable for managing file navigation state with parent stack support
|
|
6
|
+
* Enables diving into related files (like transcodes) and navigating back to parent
|
|
7
|
+
*/
|
|
8
|
+
export function useFileNavigation(initialFile: Ref<UploadedFile | null>, initialRelatedFiles: Ref<UploadedFile[]> = ref([])) {
|
|
9
|
+
// Current navigation state
|
|
10
|
+
const currentFile = ref<UploadedFile | null>(initialFile.value);
|
|
11
|
+
const relatedFiles = ref<UploadedFile[]>(initialRelatedFiles.value);
|
|
12
|
+
const parentStack = ref<FileNavigationParent[]>([]);
|
|
13
|
+
const currentIndex = ref(0);
|
|
14
|
+
|
|
15
|
+
// Computed properties
|
|
16
|
+
const hasParent = computed(() => parentStack.value.length > 0);
|
|
17
|
+
const canNavigatePrevious = computed(() => currentIndex.value > 0);
|
|
18
|
+
const canNavigateNext = computed(() => currentIndex.value < relatedFiles.value.length - 1);
|
|
19
|
+
const totalFiles = computed(() => relatedFiles.value.length);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Navigate to a specific file by index
|
|
23
|
+
*/
|
|
24
|
+
function navigateTo(index: number) {
|
|
25
|
+
if (index >= 0 && index < relatedFiles.value.length) {
|
|
26
|
+
currentIndex.value = index;
|
|
27
|
+
currentFile.value = relatedFiles.value[index];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Navigate to the next file
|
|
33
|
+
*/
|
|
34
|
+
function navigateNext() {
|
|
35
|
+
if (canNavigateNext.value) {
|
|
36
|
+
navigateTo(currentIndex.value + 1);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Navigate to the previous file
|
|
42
|
+
*/
|
|
43
|
+
function navigatePrevious() {
|
|
44
|
+
if (canNavigatePrevious.value) {
|
|
45
|
+
navigateTo(currentIndex.value - 1);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Dive into a related file (e.g., transcodes)
|
|
51
|
+
* Pushes current state onto parent stack
|
|
52
|
+
*/
|
|
53
|
+
function diveInto(file: UploadedFile, newRelatedFiles: UploadedFile[]) {
|
|
54
|
+
// Push current state onto parent stack
|
|
55
|
+
parentStack.value.push({
|
|
56
|
+
file: currentFile.value!,
|
|
57
|
+
relatedFiles: relatedFiles.value,
|
|
58
|
+
index: currentIndex.value
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Update to new state
|
|
62
|
+
currentFile.value = file;
|
|
63
|
+
relatedFiles.value = newRelatedFiles;
|
|
64
|
+
currentIndex.value = newRelatedFiles.findIndex(f => f.id === file.id);
|
|
65
|
+
|
|
66
|
+
// Fallback to 0 if not found
|
|
67
|
+
if (currentIndex.value === -1) {
|
|
68
|
+
currentIndex.value = 0;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Navigate back to parent file
|
|
74
|
+
* Pops state from parent stack
|
|
75
|
+
*/
|
|
76
|
+
function navigateToParent() {
|
|
77
|
+
if (hasParent.value) {
|
|
78
|
+
const parent = parentStack.value.pop()!;
|
|
79
|
+
currentFile.value = parent.file;
|
|
80
|
+
relatedFiles.value = parent.relatedFiles;
|
|
81
|
+
currentIndex.value = parent.index;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Reset navigation state
|
|
87
|
+
*/
|
|
88
|
+
function reset(file: UploadedFile | null = null, files: UploadedFile[] = []) {
|
|
89
|
+
currentFile.value = file;
|
|
90
|
+
relatedFiles.value = files;
|
|
91
|
+
parentStack.value = [];
|
|
92
|
+
currentIndex.value = 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Get navigation state snapshot
|
|
97
|
+
*/
|
|
98
|
+
function getState(): FileNavigationState {
|
|
99
|
+
return {
|
|
100
|
+
currentFile: currentFile.value,
|
|
101
|
+
relatedFiles: relatedFiles.value,
|
|
102
|
+
parentStack: [...parentStack.value],
|
|
103
|
+
currentIndex: currentIndex.value
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
// State
|
|
109
|
+
currentFile,
|
|
110
|
+
relatedFiles,
|
|
111
|
+
parentStack,
|
|
112
|
+
currentIndex,
|
|
113
|
+
|
|
114
|
+
// Computed
|
|
115
|
+
hasParent,
|
|
116
|
+
canNavigatePrevious,
|
|
117
|
+
canNavigateNext,
|
|
118
|
+
totalFiles,
|
|
119
|
+
|
|
120
|
+
// Methods
|
|
121
|
+
navigateTo,
|
|
122
|
+
navigateNext,
|
|
123
|
+
navigatePrevious,
|
|
124
|
+
diveInto,
|
|
125
|
+
navigateToParent,
|
|
126
|
+
reset,
|
|
127
|
+
getState
|
|
128
|
+
};
|
|
129
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { onMounted, onUnmounted } from "vue";
|
|
2
|
+
|
|
3
|
+
export interface KeyboardNavigationCallbacks {
|
|
4
|
+
onPrevious: () => void;
|
|
5
|
+
onNext: () => void;
|
|
6
|
+
onEscape?: () => void;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface UseKeyboardNavigationOptions {
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Composable for keyboard navigation (arrow keys + escape)
|
|
15
|
+
* Handles left/right arrow keys for navigation and optional escape key
|
|
16
|
+
*/
|
|
17
|
+
export function useKeyboardNavigation(
|
|
18
|
+
callbacks: KeyboardNavigationCallbacks,
|
|
19
|
+
options: UseKeyboardNavigationOptions = {}
|
|
20
|
+
) {
|
|
21
|
+
const { enabled = true } = options;
|
|
22
|
+
|
|
23
|
+
function onKeydown(e: KeyboardEvent) {
|
|
24
|
+
if (!enabled) return;
|
|
25
|
+
|
|
26
|
+
switch (e.key) {
|
|
27
|
+
case "ArrowLeft":
|
|
28
|
+
e.preventDefault();
|
|
29
|
+
callbacks.onPrevious();
|
|
30
|
+
break;
|
|
31
|
+
case "ArrowRight":
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
callbacks.onNext();
|
|
34
|
+
break;
|
|
35
|
+
case "Escape":
|
|
36
|
+
if (callbacks.onEscape) {
|
|
37
|
+
callbacks.onEscape();
|
|
38
|
+
}
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
onMounted(() => {
|
|
44
|
+
if (enabled) {
|
|
45
|
+
window.addEventListener("keydown", onKeydown);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
onUnmounted(() => {
|
|
50
|
+
if (enabled) {
|
|
51
|
+
window.removeEventListener("keydown", onKeydown);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
onKeydown
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { nextTick, Ref, watch } from "vue";
|
|
2
|
+
|
|
3
|
+
export interface UseThumbnailScrollOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Container element that holds the thumbnails
|
|
6
|
+
*/
|
|
7
|
+
containerRef: Ref<HTMLElement | null>;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Current active index
|
|
11
|
+
*/
|
|
12
|
+
currentIndex: Ref<number>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Optional CSS selector for thumbnail elements (defaults to '.thumbnail')
|
|
16
|
+
*/
|
|
17
|
+
thumbnailSelector?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Composable for auto-scrolling thumbnails into view
|
|
22
|
+
* Watches the current index and scrolls the active thumbnail into the visible area
|
|
23
|
+
*/
|
|
24
|
+
export function useThumbnailScroll(options: UseThumbnailScrollOptions) {
|
|
25
|
+
const { containerRef, currentIndex, thumbnailSelector = ".thumbnail" } = options;
|
|
26
|
+
|
|
27
|
+
watch(currentIndex, (newIndex) => {
|
|
28
|
+
nextTick(() => {
|
|
29
|
+
const thumbnails = containerRef.value?.querySelectorAll(thumbnailSelector);
|
|
30
|
+
const activeThumbnail = thumbnails?.[newIndex] as HTMLElement;
|
|
31
|
+
|
|
32
|
+
if (activeThumbnail && containerRef.value) {
|
|
33
|
+
activeThumbnail.scrollIntoView({
|
|
34
|
+
behavior: "smooth",
|
|
35
|
+
block: "nearest",
|
|
36
|
+
inline: "center"
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return {};
|
|
43
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { computed, Ref, shallowRef, watch } from "vue";
|
|
2
|
+
import { UploadedFile, VirtualCarouselSlide } from "../types";
|
|
3
|
+
|
|
4
|
+
const BUFFER_SIZE = 2; // Render current slide ± 2 slides
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Composable for managing virtual carousel rendering
|
|
8
|
+
* Only renders slides within buffer window for performance with large file sets
|
|
9
|
+
*/
|
|
10
|
+
export function useVirtualCarousel(
|
|
11
|
+
files: Ref<UploadedFile[]>,
|
|
12
|
+
currentIndex: Ref<number>
|
|
13
|
+
) {
|
|
14
|
+
// Shallow ref to avoid deep reactivity for performance
|
|
15
|
+
const visibleSlides = shallowRef<VirtualCarouselSlide[]>([]);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Calculate which slides should be visible based on current index
|
|
19
|
+
*/
|
|
20
|
+
const visibleIndices = computed(() => {
|
|
21
|
+
const start = Math.max(0, currentIndex.value - BUFFER_SIZE);
|
|
22
|
+
const end = Math.min(files.value.length - 1, currentIndex.value + BUFFER_SIZE);
|
|
23
|
+
const indices: number[] = [];
|
|
24
|
+
|
|
25
|
+
for (let i = start; i <= end; i++) {
|
|
26
|
+
indices.push(i);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return indices;
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Update visible slides based on current index
|
|
34
|
+
*/
|
|
35
|
+
function updateVisibleSlides() {
|
|
36
|
+
const indices = visibleIndices.value;
|
|
37
|
+
const newSlides: VirtualCarouselSlide[] = [];
|
|
38
|
+
|
|
39
|
+
for (const index of indices) {
|
|
40
|
+
if (index >= 0 && index < files.value.length) {
|
|
41
|
+
newSlides.push({
|
|
42
|
+
file: files.value[index],
|
|
43
|
+
index,
|
|
44
|
+
isActive: index === currentIndex.value,
|
|
45
|
+
isVisible: true
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
visibleSlides.value = newSlides;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Check if a slide at given index is visible
|
|
55
|
+
*/
|
|
56
|
+
function isSlideVisible(index: number): boolean {
|
|
57
|
+
return visibleIndices.value.includes(index);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get slide by index (returns null if not visible)
|
|
62
|
+
*/
|
|
63
|
+
function getSlide(index: number): VirtualCarouselSlide | null {
|
|
64
|
+
return visibleSlides.value.find(s => s.index === index) || null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get slides that should be preloaded (visible + buffer)
|
|
69
|
+
*/
|
|
70
|
+
const preloadIndices = computed(() => {
|
|
71
|
+
const start = Math.max(0, currentIndex.value - BUFFER_SIZE - 1);
|
|
72
|
+
const end = Math.min(files.value.length - 1, currentIndex.value + BUFFER_SIZE + 1);
|
|
73
|
+
const indices: number[] = [];
|
|
74
|
+
|
|
75
|
+
for (let i = start; i <= end; i++) {
|
|
76
|
+
indices.push(i);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return indices;
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Watch for changes to update visible slides
|
|
83
|
+
watch([currentIndex, files], updateVisibleSlides, { immediate: true });
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
visibleSlides,
|
|
87
|
+
visibleIndices,
|
|
88
|
+
preloadIndices,
|
|
89
|
+
isSlideVisible,
|
|
90
|
+
getSlide,
|
|
91
|
+
updateVisibleSlides
|
|
92
|
+
};
|
|
93
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { UploadedFile } from "../types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Placeholder constants for file preview
|
|
5
|
+
*/
|
|
6
|
+
export const FILE_PLACEHOLDERS = {
|
|
7
|
+
IMAGE: "https://placehold.co/64x64?text=?",
|
|
8
|
+
VIDEO_SVG: `data:image/svg+xml;base64,${btoa(
|
|
9
|
+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white"><path d="M8 5v14l11-7z"/></svg>'
|
|
10
|
+
)}`
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* MIME type regex patterns for file type detection
|
|
15
|
+
*/
|
|
16
|
+
export const MIME_TYPES = {
|
|
17
|
+
IMAGE: /^image\//,
|
|
18
|
+
VIDEO: /^video\//,
|
|
19
|
+
TEXT: /^text\//,
|
|
20
|
+
PDF: /^application\/pdf/
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Check if file is an image
|
|
25
|
+
*/
|
|
26
|
+
export function isImage(file: UploadedFile): boolean {
|
|
27
|
+
const mimeType = getMimeType(file);
|
|
28
|
+
return MIME_TYPES.IMAGE.test(mimeType);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Check if file is a video
|
|
33
|
+
*/
|
|
34
|
+
export function isVideo(file: UploadedFile): boolean {
|
|
35
|
+
const mimeType = getMimeType(file);
|
|
36
|
+
return MIME_TYPES.VIDEO.test(mimeType);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Check if file is a text file
|
|
41
|
+
*/
|
|
42
|
+
export function isText(file: UploadedFile): boolean {
|
|
43
|
+
const mimeType = getMimeType(file);
|
|
44
|
+
return MIME_TYPES.TEXT.test(mimeType);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Check if file is a PDF
|
|
49
|
+
*/
|
|
50
|
+
export function isPdf(file: UploadedFile): boolean {
|
|
51
|
+
const mimeType = getMimeType(file);
|
|
52
|
+
return MIME_TYPES.PDF.test(mimeType);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get the MIME type from a file
|
|
57
|
+
*/
|
|
58
|
+
export function getMimeType(file: UploadedFile): string {
|
|
59
|
+
return file.mime || file.type || "";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get the file extension from a filename
|
|
64
|
+
*/
|
|
65
|
+
export function getFileExtension(filename: string): string {
|
|
66
|
+
return filename.split(".").pop()?.toLowerCase() || "";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get the preview URL for a file
|
|
71
|
+
* Priority: optimized > blobUrl > url > thumb > empty string
|
|
72
|
+
*/
|
|
73
|
+
export function getPreviewUrl(file: UploadedFile): string {
|
|
74
|
+
if (file.optimized?.url) {
|
|
75
|
+
return file.optimized.url;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (isImage(file)) {
|
|
79
|
+
return file.blobUrl || file.url || "";
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return file.thumb?.url || "";
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Get the thumbnail URL for a file
|
|
87
|
+
* For videos without thumbs, returns a play icon SVG
|
|
88
|
+
*/
|
|
89
|
+
export function getThumbUrl(file: UploadedFile): string {
|
|
90
|
+
if (file.thumb?.url) {
|
|
91
|
+
return file.thumb.url;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (isVideo(file)) {
|
|
95
|
+
return FILE_PLACEHOLDERS.VIDEO_SVG;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return getPreviewUrl(file) || FILE_PLACEHOLDERS.IMAGE;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Get the optimized URL for a file (used for preview)
|
|
103
|
+
* Priority: optimized > blobUrl > url
|
|
104
|
+
*/
|
|
105
|
+
export function getOptimizedUrl(file: UploadedFile): string {
|
|
106
|
+
return file.optimized?.url || file.blobUrl || file.url || "";
|
|
107
|
+
}
|
|
@@ -63,9 +63,12 @@ export function fMarkdownCode(type: string, string: string | object): string {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
const regex = new RegExp(`\`\`\`${type}`, "g");
|
|
67
66
|
string = (string || "") as string;
|
|
68
|
-
if
|
|
67
|
+
// Check if string STARTS with the code fence (not just contains it anywhere)
|
|
68
|
+
// This fixes a bug where JSON containing embedded code fences in the data
|
|
69
|
+
// would incorrectly be detected as already wrapped
|
|
70
|
+
const startsWithCodeFence = new RegExp(`^\\s*\`\`\`${type}\\s`).test(string);
|
|
71
|
+
if (!startsWithCodeFence) {
|
|
69
72
|
string = parseMarkdownCode(string as string);
|
|
70
73
|
return `\`\`\`${type}\n${string}\n\`\`\``;
|
|
71
74
|
}
|
package/src/helpers/index.ts
CHANGED
package/src/types/files.d.ts
CHANGED
|
@@ -34,6 +34,23 @@ export interface UploadedFile extends TypedObject {
|
|
|
34
34
|
meta?: AnyObject;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
export interface StoredFile extends TypedObject {
|
|
38
|
+
filename: string;
|
|
39
|
+
url: string;
|
|
40
|
+
mime: string;
|
|
41
|
+
size?: number;
|
|
42
|
+
location?: {
|
|
43
|
+
x: number;
|
|
44
|
+
y: number;
|
|
45
|
+
};
|
|
46
|
+
meta?: AnyObject;
|
|
47
|
+
page_number?: number;
|
|
48
|
+
is_transcoding?: boolean;
|
|
49
|
+
thumb?: StoredFile;
|
|
50
|
+
optimized?: StoredFile;
|
|
51
|
+
transcodes?: StoredFile[];
|
|
52
|
+
}
|
|
53
|
+
|
|
37
54
|
export interface FileUploadCompleteCallbackParams {
|
|
38
55
|
file?: UploadedFile | null;
|
|
39
56
|
uploadedFile?: UploadedFile | null;
|
|
@@ -60,3 +77,24 @@ export type FileUploadProgressCallback = (params: FileUploadProgressCallbackPara
|
|
|
60
77
|
export type FileUploadErrorCallback = (params: FileUploadErrorCallbackParams) => void
|
|
61
78
|
export type OnFilesChangeCallback = (files: UploadedFile[]) => void;
|
|
62
79
|
export type VoidCallback = () => void;
|
|
80
|
+
|
|
81
|
+
// File Navigation Types
|
|
82
|
+
export interface FileNavigationState {
|
|
83
|
+
currentFile: UploadedFile | null;
|
|
84
|
+
relatedFiles: UploadedFile[];
|
|
85
|
+
parentStack: FileNavigationParent[];
|
|
86
|
+
currentIndex: number;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface FileNavigationParent {
|
|
90
|
+
file: UploadedFile;
|
|
91
|
+
relatedFiles: UploadedFile[];
|
|
92
|
+
index: number;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface VirtualCarouselSlide {
|
|
96
|
+
file: UploadedFile;
|
|
97
|
+
index: number;
|
|
98
|
+
isActive: boolean;
|
|
99
|
+
isVisible: boolean;
|
|
100
|
+
}
|
package/src/types/widgets.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export interface LabelPillWidgetProps {
|
|
2
2
|
label?: string | number;
|
|
3
3
|
size?: "xs" | "sm" | "md" | "lg";
|
|
4
|
-
color?: "sky" | "green" | "red" | "amber" | "yellow" | "blue" | "slate" | "slate-mid" | "gray" | "none";
|
|
4
|
+
color?: "sky" | "green" | "red" | "amber" | "yellow" | "blue" | "purple" | "slate" | "slate-mid" | "gray" | "emerald" | "orange" | "lime" | "teal" | "cyan" | "rose" | "indigo" | "violet" | "fuchsia" | "none";
|
|
5
5
|
}
|