@brftech/filex-core 0.1.56 → 0.1.61
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/LICENSE +21 -21
- package/README.md +108 -108
- package/dist/{ArchiveViewer-CJdaw5x3.js → ArchiveViewer-CbUUEREI.js} +20 -20
- package/dist/ArchiveViewer-CbUUEREI.js.map +1 -0
- package/dist/{CsvViewer-QYx_tePQ.js → CsvViewer-72rDsQJX.js} +3 -3
- package/dist/CsvViewer-72rDsQJX.js.map +1 -0
- package/dist/{DrawioViewer-GWt0TyB7.js → DrawioViewer-DSyMwGvg.js} +7 -7
- package/dist/DrawioViewer-DSyMwGvg.js.map +1 -0
- package/dist/{EpubViewer-Je0ywklQ.js → EpubViewer-DvDa17d7.js} +3 -3
- package/dist/EpubViewer-DvDa17d7.js.map +1 -0
- package/dist/{IpynbViewer-TsB4gqP-.js → IpynbViewer-DibIkdsz.js} +3 -3
- package/dist/IpynbViewer-DibIkdsz.js.map +1 -0
- package/dist/{MermaidViewer-CXfeDS-7.js → MermaidViewer-BoFLtGvl.js} +3 -3
- package/dist/MermaidViewer-BoFLtGvl.js.map +1 -0
- package/dist/{PsdViewer-VtPpxKVe.js → PsdViewer-K2iZkwax.js} +3 -3
- package/dist/PsdViewer-K2iZkwax.js.map +1 -0
- package/dist/{TiffViewer-OINn9bbb.js → TiffViewer-JzDzbqpO.js} +3 -3
- package/dist/TiffViewer-JzDzbqpO.js.map +1 -0
- package/dist/{Viewer3D-xvvyiWHd.js → Viewer3D-WEMYCP8l.js} +7 -7
- package/dist/Viewer3D-WEMYCP8l.js.map +1 -0
- package/dist/filex-core.js +1 -1
- package/dist/filex-core.umd.cjs +4 -4
- package/dist/filex-core.umd.cjs.map +1 -1
- package/dist/{index-CmSYzt6L.js → index-B5YT-m5Q.js} +209 -209
- package/dist/index-B5YT-m5Q.js.map +1 -0
- package/dist/style.css +1 -1
- package/dist/useViewerFetch-czqbd2Lj.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Breadcrumb.vue +282 -282
- package/src/components/ContextMenu.vue +152 -152
- package/src/components/GridView.vue +166 -166
- package/src/components/ListView.vue +212 -212
- package/src/components/PendingOpsTray.vue +91 -91
- package/src/components/RecentlyOpened.vue +155 -155
- package/src/components/StarButton.vue +101 -101
- package/src/components/TagPicker.vue +184 -184
- package/src/components/Toolbar.vue +220 -220
- package/src/components/UploadProgress.vue +78 -78
- package/src/composables/useFileApi.ts +692 -692
- package/src/composables/useKeyboardShortcuts.ts +144 -144
- package/src/composables/useLocale.ts +60 -60
- package/src/composables/useMonacoLoader.ts +98 -98
- package/src/composables/usePendingOps.ts +200 -200
- package/src/composables/useSelection.ts +81 -81
- package/src/composables/useUploadChunked.ts +250 -250
- package/src/composables/useViewerFetch.ts +58 -58
- package/src/index.ts +80 -80
- package/src/locales/en.ts +122 -122
- package/src/locales/index.ts +12 -12
- package/src/locales/tr.ts +122 -122
- package/src/modals/DeleteConfirmModal.vue +32 -32
- package/src/modals/Modal.vue +104 -104
- package/src/modals/NewFolderModal.vue +64 -64
- package/src/modals/PermissionsModal.vue +815 -815
- package/src/modals/PreviewModal.vue +1070 -1070
- package/src/modals/RenameModal.vue +58 -58
- package/src/modals/ShareModal.vue +135 -135
- package/src/styles/base.css +1224 -1224
- package/src/styles/variables.css +90 -90
- package/src/types/FileNode.ts +136 -136
- package/src/types/index.ts +27 -27
- package/src/types/peers.d.ts +45 -45
- package/src/viewers/ArchiveViewer.vue +186 -186
- package/src/viewers/CsvViewer.vue +319 -319
- package/src/viewers/DrawioViewer.vue +243 -243
- package/src/viewers/EpubViewer.vue +307 -307
- package/src/viewers/IpynbViewer.vue +365 -365
- package/src/viewers/MermaidViewer.vue +259 -259
- package/src/viewers/PdfViewer.vue +562 -562
- package/src/viewers/PsdViewer.vue +264 -264
- package/src/viewers/TiffViewer.vue +273 -273
- package/src/viewers/Viewer3D.vue +120 -120
- package/dist/ArchiveViewer-CJdaw5x3.js.map +0 -1
- package/dist/CsvViewer-QYx_tePQ.js.map +0 -1
- package/dist/DrawioViewer-GWt0TyB7.js.map +0 -1
- package/dist/EpubViewer-Je0ywklQ.js.map +0 -1
- package/dist/IpynbViewer-TsB4gqP-.js.map +0 -1
- package/dist/MermaidViewer-CXfeDS-7.js.map +0 -1
- package/dist/PsdViewer-VtPpxKVe.js.map +0 -1
- package/dist/TiffViewer-OINn9bbb.js.map +0 -1
- package/dist/Viewer3D-xvvyiWHd.js.map +0 -1
- package/dist/index-CmSYzt6L.js.map +0 -1
package/src/locales/tr.ts
CHANGED
|
@@ -1,122 +1,122 @@
|
|
|
1
|
-
/** Turkish UI strings. */
|
|
2
|
-
export const tr: Record<string, string> = {
|
|
3
|
-
'toolbar.new_folder': 'Yeni Klasör',
|
|
4
|
-
'toolbar.upload': 'Yükle',
|
|
5
|
-
'toolbar.search': 'Ara',
|
|
6
|
-
'toolbar.search.placeholder': 'Dosya adı…',
|
|
7
|
-
'toolbar.view.list': 'Liste',
|
|
8
|
-
'toolbar.view.grid': 'Izgara',
|
|
9
|
-
'toolbar.refresh': 'Yenile',
|
|
10
|
-
'toolbar.go_up': 'Üst Klasör',
|
|
11
|
-
|
|
12
|
-
'ctx.open': 'Aç',
|
|
13
|
-
'ctx.preview': 'Önizle',
|
|
14
|
-
'ctx.download': 'İndir',
|
|
15
|
-
'ctx.convert': 'Dönüştür',
|
|
16
|
-
'ctx.rename': 'Yeniden Adlandır',
|
|
17
|
-
'ctx.delete': 'Sil',
|
|
18
|
-
'ctx.delete_perm': 'Kalıcı Olarak Sil',
|
|
19
|
-
'ctx.restore': 'Geri Getir',
|
|
20
|
-
'ctx.share': 'Paylaş',
|
|
21
|
-
'ctx.move': 'Taşı',
|
|
22
|
-
'ctx.copy': 'Kopyala',
|
|
23
|
-
'ctx.cut': 'Kes',
|
|
24
|
-
'ctx.paste': 'Yapıştır',
|
|
25
|
-
'ctx.info': 'Bilgi',
|
|
26
|
-
'ctx.duplicate': 'Kopyasını Oluştur',
|
|
27
|
-
'ctx.new_file': 'Yeni Dosya',
|
|
28
|
-
|
|
29
|
-
'modal.delete.title': 'Silinsin mi?',
|
|
30
|
-
'modal.delete.message': '{count} öğe çöpe atılacak.',
|
|
31
|
-
'modal.delete.confirm': 'Çöpe At',
|
|
32
|
-
'modal.delete.cancel': 'Vazgeç',
|
|
33
|
-
|
|
34
|
-
'modal.rename.title': 'Yeniden Adlandır',
|
|
35
|
-
'modal.rename.save': 'Kaydet',
|
|
36
|
-
'modal.rename.cancel': 'Vazgeç',
|
|
37
|
-
|
|
38
|
-
'modal.newfolder.title': 'Yeni Klasör',
|
|
39
|
-
'modal.newfolder.placeholder': 'Klasör adı',
|
|
40
|
-
'modal.newfolder.create': 'Oluştur',
|
|
41
|
-
'modal.newfolder.cancel': 'Vazgeç',
|
|
42
|
-
|
|
43
|
-
'modal.share.title': 'Paylaşım Linki',
|
|
44
|
-
'modal.share.pin': 'PIN koruması',
|
|
45
|
-
'modal.share.expires': 'Son kullanma',
|
|
46
|
-
'modal.share.max_downloads': 'İndirme limiti',
|
|
47
|
-
'modal.share.create': 'Paylaş',
|
|
48
|
-
'modal.share.cancel': 'Vazgeç',
|
|
49
|
-
'modal.share.copy': 'Kopyala',
|
|
50
|
-
'modal.share.url_copied': 'Link kopyalandı',
|
|
51
|
-
'modal.share.pin_copied': 'PIN kopyalandı',
|
|
52
|
-
'modal.share.cli_copied': 'CLI komutu kopyalandı',
|
|
53
|
-
|
|
54
|
-
'upload.progress': 'Yükleniyor',
|
|
55
|
-
'upload.done': 'Tamamlandı',
|
|
56
|
-
'upload.error': 'Hata',
|
|
57
|
-
'upload.aborted': 'İptal edildi',
|
|
58
|
-
'upload.cancel': 'İptal',
|
|
59
|
-
|
|
60
|
-
'empty.folder': 'Bu klasör boş',
|
|
61
|
-
'empty.search': 'Sonuç bulunamadı',
|
|
62
|
-
'loading': 'Yükleniyor…',
|
|
63
|
-
|
|
64
|
-
'col.name': 'Ad',
|
|
65
|
-
'col.size': 'Boyut',
|
|
66
|
-
'col.modified': 'Tarih',
|
|
67
|
-
'col.type': 'Tür',
|
|
68
|
-
|
|
69
|
-
'unit.bytes': 'B',
|
|
70
|
-
'unit.kb': 'KB',
|
|
71
|
-
'unit.mb': 'MB',
|
|
72
|
-
'unit.gb': 'GB',
|
|
73
|
-
'unit.tb': 'TB',
|
|
74
|
-
|
|
75
|
-
'breadcrumb.root': 'Kök',
|
|
76
|
-
'breadcrumb.copy_path': 'Yolu Kopyala',
|
|
77
|
-
'breadcrumb.go_to_path': 'Yola Git',
|
|
78
|
-
'breadcrumb.path_placeholder': 'fileman/foo/bar',
|
|
79
|
-
|
|
80
|
-
'ops.copy': 'Kopyalanıyor',
|
|
81
|
-
'ops.move': 'Taşınıyor',
|
|
82
|
-
'ops.delete': 'Siliniyor',
|
|
83
|
-
'ops.queued': 'sırada',
|
|
84
|
-
'ops.done': 'tamamlandı',
|
|
85
|
-
'ops.error': 'hata',
|
|
86
|
-
|
|
87
|
-
'node.trash': 'Çöp Kutusu',
|
|
88
|
-
|
|
89
|
-
// ——— Zengin önizleyici chrome ———
|
|
90
|
-
'viewer.open_in_new_tab': 'Yeni Sekmede Aç',
|
|
91
|
-
'viewer.loading': 'Yükleniyor…',
|
|
92
|
-
'viewer.failed_to_load': 'Dosya yüklenemedi',
|
|
93
|
-
'viewer.peer_not_installed': 'Bu dosya tipi için opsiyonel kütüphane kurulu değil. Peer dependency yükle veya İndir düğmesini kullan.',
|
|
94
|
-
'viewer.format_unsupported_3d': 'Bu 3B format tarayıcı önizlemesinde desteklenmiyor (model-viewer yalnızca .glb / .gltf / .usdz okur). Lütfen indirip yerel bir araçta açın.',
|
|
95
|
-
'viewer.zoom_in': 'Yakınlaştır',
|
|
96
|
-
'viewer.zoom_out': 'Uzaklaştır',
|
|
97
|
-
'viewer.fit_width': 'Sayfa genişliğine sığdır',
|
|
98
|
-
'viewer.next_page': 'Sonraki sayfa',
|
|
99
|
-
'viewer.prev_page': 'Önceki sayfa',
|
|
100
|
-
'viewer.page_n_of_m': 'Sayfa {n} / {m}',
|
|
101
|
-
'viewer.tags': 'Etiketler',
|
|
102
|
-
'viewer.layers': 'Katmanlar',
|
|
103
|
-
'viewer.toc': 'İçindekiler',
|
|
104
|
-
'viewer.font_smaller': 'Yazıyı küçült',
|
|
105
|
-
'viewer.font_larger': 'Yazıyı büyüt',
|
|
106
|
-
'viewer.search': 'Ara',
|
|
107
|
-
'viewer.download': 'İndir',
|
|
108
|
-
'viewer.save_annotations': 'Açıklamaları kaydet',
|
|
109
|
-
'viewer.annotations_on': 'Açıklamalar: açık',
|
|
110
|
-
'viewer.annotations_off': 'Açıklamalar: kapalı',
|
|
111
|
-
'viewer.read_only': 'Salt okunur',
|
|
112
|
-
'viewer.csv_first_row_header': 'İlk satır başlık olsun',
|
|
113
|
-
'viewer.csv_filter': 'Satır filtrele…',
|
|
114
|
-
'viewer.epub_prev': 'Önceki',
|
|
115
|
-
'viewer.epub_next': 'Sonraki',
|
|
116
|
-
'viewer.drawio.disabled': 'diagrams.net editörü bu filex kurulumunda yapılandırılmamış — yönetici FILEX_DRAWIO_URL\'yi ayarlamalı.',
|
|
117
|
-
'viewer.archive.entries': '{n} dosya',
|
|
118
|
-
'viewer.archive.empty': 'Arşiv boş.',
|
|
119
|
-
'viewer.archive.error': 'Arşiv okunamadı.',
|
|
120
|
-
'viewer.name': 'Ad',
|
|
121
|
-
'viewer.size': 'Boyut',
|
|
122
|
-
};
|
|
1
|
+
/** Turkish UI strings. */
|
|
2
|
+
export const tr: Record<string, string> = {
|
|
3
|
+
'toolbar.new_folder': 'Yeni Klasör',
|
|
4
|
+
'toolbar.upload': 'Yükle',
|
|
5
|
+
'toolbar.search': 'Ara',
|
|
6
|
+
'toolbar.search.placeholder': 'Dosya adı…',
|
|
7
|
+
'toolbar.view.list': 'Liste',
|
|
8
|
+
'toolbar.view.grid': 'Izgara',
|
|
9
|
+
'toolbar.refresh': 'Yenile',
|
|
10
|
+
'toolbar.go_up': 'Üst Klasör',
|
|
11
|
+
|
|
12
|
+
'ctx.open': 'Aç',
|
|
13
|
+
'ctx.preview': 'Önizle',
|
|
14
|
+
'ctx.download': 'İndir',
|
|
15
|
+
'ctx.convert': 'Dönüştür',
|
|
16
|
+
'ctx.rename': 'Yeniden Adlandır',
|
|
17
|
+
'ctx.delete': 'Sil',
|
|
18
|
+
'ctx.delete_perm': 'Kalıcı Olarak Sil',
|
|
19
|
+
'ctx.restore': 'Geri Getir',
|
|
20
|
+
'ctx.share': 'Paylaş',
|
|
21
|
+
'ctx.move': 'Taşı',
|
|
22
|
+
'ctx.copy': 'Kopyala',
|
|
23
|
+
'ctx.cut': 'Kes',
|
|
24
|
+
'ctx.paste': 'Yapıştır',
|
|
25
|
+
'ctx.info': 'Bilgi',
|
|
26
|
+
'ctx.duplicate': 'Kopyasını Oluştur',
|
|
27
|
+
'ctx.new_file': 'Yeni Dosya',
|
|
28
|
+
|
|
29
|
+
'modal.delete.title': 'Silinsin mi?',
|
|
30
|
+
'modal.delete.message': '{count} öğe çöpe atılacak.',
|
|
31
|
+
'modal.delete.confirm': 'Çöpe At',
|
|
32
|
+
'modal.delete.cancel': 'Vazgeç',
|
|
33
|
+
|
|
34
|
+
'modal.rename.title': 'Yeniden Adlandır',
|
|
35
|
+
'modal.rename.save': 'Kaydet',
|
|
36
|
+
'modal.rename.cancel': 'Vazgeç',
|
|
37
|
+
|
|
38
|
+
'modal.newfolder.title': 'Yeni Klasör',
|
|
39
|
+
'modal.newfolder.placeholder': 'Klasör adı',
|
|
40
|
+
'modal.newfolder.create': 'Oluştur',
|
|
41
|
+
'modal.newfolder.cancel': 'Vazgeç',
|
|
42
|
+
|
|
43
|
+
'modal.share.title': 'Paylaşım Linki',
|
|
44
|
+
'modal.share.pin': 'PIN koruması',
|
|
45
|
+
'modal.share.expires': 'Son kullanma',
|
|
46
|
+
'modal.share.max_downloads': 'İndirme limiti',
|
|
47
|
+
'modal.share.create': 'Paylaş',
|
|
48
|
+
'modal.share.cancel': 'Vazgeç',
|
|
49
|
+
'modal.share.copy': 'Kopyala',
|
|
50
|
+
'modal.share.url_copied': 'Link kopyalandı',
|
|
51
|
+
'modal.share.pin_copied': 'PIN kopyalandı',
|
|
52
|
+
'modal.share.cli_copied': 'CLI komutu kopyalandı',
|
|
53
|
+
|
|
54
|
+
'upload.progress': 'Yükleniyor',
|
|
55
|
+
'upload.done': 'Tamamlandı',
|
|
56
|
+
'upload.error': 'Hata',
|
|
57
|
+
'upload.aborted': 'İptal edildi',
|
|
58
|
+
'upload.cancel': 'İptal',
|
|
59
|
+
|
|
60
|
+
'empty.folder': 'Bu klasör boş',
|
|
61
|
+
'empty.search': 'Sonuç bulunamadı',
|
|
62
|
+
'loading': 'Yükleniyor…',
|
|
63
|
+
|
|
64
|
+
'col.name': 'Ad',
|
|
65
|
+
'col.size': 'Boyut',
|
|
66
|
+
'col.modified': 'Tarih',
|
|
67
|
+
'col.type': 'Tür',
|
|
68
|
+
|
|
69
|
+
'unit.bytes': 'B',
|
|
70
|
+
'unit.kb': 'KB',
|
|
71
|
+
'unit.mb': 'MB',
|
|
72
|
+
'unit.gb': 'GB',
|
|
73
|
+
'unit.tb': 'TB',
|
|
74
|
+
|
|
75
|
+
'breadcrumb.root': 'Kök',
|
|
76
|
+
'breadcrumb.copy_path': 'Yolu Kopyala',
|
|
77
|
+
'breadcrumb.go_to_path': 'Yola Git',
|
|
78
|
+
'breadcrumb.path_placeholder': 'fileman/foo/bar',
|
|
79
|
+
|
|
80
|
+
'ops.copy': 'Kopyalanıyor',
|
|
81
|
+
'ops.move': 'Taşınıyor',
|
|
82
|
+
'ops.delete': 'Siliniyor',
|
|
83
|
+
'ops.queued': 'sırada',
|
|
84
|
+
'ops.done': 'tamamlandı',
|
|
85
|
+
'ops.error': 'hata',
|
|
86
|
+
|
|
87
|
+
'node.trash': 'Çöp Kutusu',
|
|
88
|
+
|
|
89
|
+
// ——— Zengin önizleyici chrome ———
|
|
90
|
+
'viewer.open_in_new_tab': 'Yeni Sekmede Aç',
|
|
91
|
+
'viewer.loading': 'Yükleniyor…',
|
|
92
|
+
'viewer.failed_to_load': 'Dosya yüklenemedi',
|
|
93
|
+
'viewer.peer_not_installed': 'Bu dosya tipi için opsiyonel kütüphane kurulu değil. Peer dependency yükle veya İndir düğmesini kullan.',
|
|
94
|
+
'viewer.format_unsupported_3d': 'Bu 3B format tarayıcı önizlemesinde desteklenmiyor (model-viewer yalnızca .glb / .gltf / .usdz okur). Lütfen indirip yerel bir araçta açın.',
|
|
95
|
+
'viewer.zoom_in': 'Yakınlaştır',
|
|
96
|
+
'viewer.zoom_out': 'Uzaklaştır',
|
|
97
|
+
'viewer.fit_width': 'Sayfa genişliğine sığdır',
|
|
98
|
+
'viewer.next_page': 'Sonraki sayfa',
|
|
99
|
+
'viewer.prev_page': 'Önceki sayfa',
|
|
100
|
+
'viewer.page_n_of_m': 'Sayfa {n} / {m}',
|
|
101
|
+
'viewer.tags': 'Etiketler',
|
|
102
|
+
'viewer.layers': 'Katmanlar',
|
|
103
|
+
'viewer.toc': 'İçindekiler',
|
|
104
|
+
'viewer.font_smaller': 'Yazıyı küçült',
|
|
105
|
+
'viewer.font_larger': 'Yazıyı büyüt',
|
|
106
|
+
'viewer.search': 'Ara',
|
|
107
|
+
'viewer.download': 'İndir',
|
|
108
|
+
'viewer.save_annotations': 'Açıklamaları kaydet',
|
|
109
|
+
'viewer.annotations_on': 'Açıklamalar: açık',
|
|
110
|
+
'viewer.annotations_off': 'Açıklamalar: kapalı',
|
|
111
|
+
'viewer.read_only': 'Salt okunur',
|
|
112
|
+
'viewer.csv_first_row_header': 'İlk satır başlık olsun',
|
|
113
|
+
'viewer.csv_filter': 'Satır filtrele…',
|
|
114
|
+
'viewer.epub_prev': 'Önceki',
|
|
115
|
+
'viewer.epub_next': 'Sonraki',
|
|
116
|
+
'viewer.drawio.disabled': 'diagrams.net editörü bu filex kurulumunda yapılandırılmamış — yönetici FILEX_DRAWIO_URL\'yi ayarlamalı.',
|
|
117
|
+
'viewer.archive.entries': '{n} dosya',
|
|
118
|
+
'viewer.archive.empty': 'Arşiv boş.',
|
|
119
|
+
'viewer.archive.error': 'Arşiv okunamadı.',
|
|
120
|
+
'viewer.name': 'Ad',
|
|
121
|
+
'viewer.size': 'Boyut',
|
|
122
|
+
};
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import type { LocaleCode } from '../types/ExplorerConfig';
|
|
3
|
-
import { useLocale } from '../composables/useLocale';
|
|
4
|
-
import Modal from './Modal.vue';
|
|
5
|
-
|
|
6
|
-
const props = defineProps<{
|
|
7
|
-
open: boolean;
|
|
8
|
-
locale: LocaleCode;
|
|
9
|
-
count: number;
|
|
10
|
-
}>();
|
|
11
|
-
|
|
12
|
-
const emit = defineEmits<{
|
|
13
|
-
(e: 'close'): void;
|
|
14
|
-
(e: 'confirm'): void;
|
|
15
|
-
}>();
|
|
16
|
-
|
|
17
|
-
const { t } = useLocale(() => props.locale);
|
|
18
|
-
</script>
|
|
19
|
-
|
|
20
|
-
<template>
|
|
21
|
-
<Modal :open="open" :title="t('modal.delete.title')" size="sm" @close="emit('close')">
|
|
22
|
-
<p>{{ t('modal.delete.message', { count }) }}</p>
|
|
23
|
-
<template #actions>
|
|
24
|
-
<button type="button" class="fe-btn" @click="emit('close')">
|
|
25
|
-
{{ t('modal.delete.cancel') }}
|
|
26
|
-
</button>
|
|
27
|
-
<button type="button" class="fe-btn fe-btn--danger" @click="emit('confirm')">
|
|
28
|
-
{{ t('modal.delete.confirm') }}
|
|
29
|
-
</button>
|
|
30
|
-
</template>
|
|
31
|
-
</Modal>
|
|
32
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { LocaleCode } from '../types/ExplorerConfig';
|
|
3
|
+
import { useLocale } from '../composables/useLocale';
|
|
4
|
+
import Modal from './Modal.vue';
|
|
5
|
+
|
|
6
|
+
const props = defineProps<{
|
|
7
|
+
open: boolean;
|
|
8
|
+
locale: LocaleCode;
|
|
9
|
+
count: number;
|
|
10
|
+
}>();
|
|
11
|
+
|
|
12
|
+
const emit = defineEmits<{
|
|
13
|
+
(e: 'close'): void;
|
|
14
|
+
(e: 'confirm'): void;
|
|
15
|
+
}>();
|
|
16
|
+
|
|
17
|
+
const { t } = useLocale(() => props.locale);
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<Modal :open="open" :title="t('modal.delete.title')" size="sm" @close="emit('close')">
|
|
22
|
+
<p>{{ t('modal.delete.message', { count }) }}</p>
|
|
23
|
+
<template #actions>
|
|
24
|
+
<button type="button" class="fe-btn" @click="emit('close')">
|
|
25
|
+
{{ t('modal.delete.cancel') }}
|
|
26
|
+
</button>
|
|
27
|
+
<button type="button" class="fe-btn fe-btn--danger" @click="emit('confirm')">
|
|
28
|
+
{{ t('modal.delete.confirm') }}
|
|
29
|
+
</button>
|
|
30
|
+
</template>
|
|
31
|
+
</Modal>
|
|
32
|
+
</template>
|
package/src/modals/Modal.vue
CHANGED
|
@@ -1,104 +1,104 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* Modal — tiny headless wrapper. Backdrop + centered card + ESC + autofocus.
|
|
4
|
-
*/
|
|
5
|
-
import { watch, onBeforeUnmount, ref } from 'vue';
|
|
6
|
-
|
|
7
|
-
const props = defineProps<{
|
|
8
|
-
open: boolean;
|
|
9
|
-
title?: string;
|
|
10
|
-
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
11
|
-
closeOnBackdrop?: boolean;
|
|
12
|
-
/** When true, drop the dialog chrome (backdrop tint, header, footer,
|
|
13
|
-
* centered card with border-radius) and render the slot full-bleed.
|
|
14
|
-
* Used by the standalone /files/edit route where the browser tab IS
|
|
15
|
-
* the container — a modal frame on top of it just steals real estate
|
|
16
|
-
* from the editor. ESC + emit('close') still wire through so the
|
|
17
|
-
* parent route can window.close() the tab. */
|
|
18
|
-
chromeless?: boolean;
|
|
19
|
-
/** Explicit theme. When set the modal stamps the appropriate
|
|
20
|
-
* `.fe--theme-{light,dark}` class on its `.fe` backdrop so the CSS
|
|
21
|
-
* variable cascade matches the host shell regardless of OS
|
|
22
|
-
* preference (Modal is a portal-shaped descendant of `<body>`
|
|
23
|
-
* rather than a child of the parent component, so plain DOM
|
|
24
|
-
* inheritance isn't always enough). */
|
|
25
|
-
theme?: 'light' | 'dark' | 'auto';
|
|
26
|
-
}>();
|
|
27
|
-
|
|
28
|
-
const emit = defineEmits<{
|
|
29
|
-
(e: 'close'): void;
|
|
30
|
-
}>();
|
|
31
|
-
|
|
32
|
-
const cardEl = ref<HTMLElement | null>(null);
|
|
33
|
-
|
|
34
|
-
watch(
|
|
35
|
-
() => props.open,
|
|
36
|
-
(v) => {
|
|
37
|
-
if (v) {
|
|
38
|
-
document.addEventListener('keydown', onKey);
|
|
39
|
-
setTimeout(() => {
|
|
40
|
-
const focusable = cardEl.value?.querySelector<HTMLElement>(
|
|
41
|
-
'input,select,textarea,button,[tabindex]:not([tabindex="-1"])',
|
|
42
|
-
);
|
|
43
|
-
focusable?.focus();
|
|
44
|
-
}, 30);
|
|
45
|
-
} else {
|
|
46
|
-
document.removeEventListener('keydown', onKey);
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
onBeforeUnmount(() => document.removeEventListener('keydown', onKey));
|
|
52
|
-
|
|
53
|
-
function onKey(e: KeyboardEvent) {
|
|
54
|
-
if (e.key === 'Escape') emit('close');
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function onBackdrop() {
|
|
58
|
-
if (props.closeOnBackdrop !== false) emit('close');
|
|
59
|
-
}
|
|
60
|
-
</script>
|
|
61
|
-
|
|
62
|
-
<template>
|
|
63
|
-
<transition name="fe-modal">
|
|
64
|
-
<div
|
|
65
|
-
v-if="open"
|
|
66
|
-
class="fe fe-modal__backdrop"
|
|
67
|
-
:class="[
|
|
68
|
-
{ 'fe-modal__backdrop--chromeless': chromeless },
|
|
69
|
-
theme === 'light' ? 'fe--theme-light' : '',
|
|
70
|
-
theme === 'dark' ? 'fe--theme-dark' : '',
|
|
71
|
-
]"
|
|
72
|
-
role="presentation"
|
|
73
|
-
@click="onBackdrop"
|
|
74
|
-
>
|
|
75
|
-
<div
|
|
76
|
-
ref="cardEl"
|
|
77
|
-
class="fe-modal__card"
|
|
78
|
-
:class="[
|
|
79
|
-
`fe-modal__card--${size || 'md'}`,
|
|
80
|
-
chromeless && 'fe-modal__card--chromeless',
|
|
81
|
-
]"
|
|
82
|
-
role="dialog"
|
|
83
|
-
aria-modal="true"
|
|
84
|
-
@click.stop
|
|
85
|
-
>
|
|
86
|
-
<header v-if="title && !chromeless" class="fe-modal__head">
|
|
87
|
-
<h2 class="fe-modal__title">{{ title }}</h2>
|
|
88
|
-
<button
|
|
89
|
-
type="button"
|
|
90
|
-
class="fe-modal__close"
|
|
91
|
-
aria-label="Close"
|
|
92
|
-
@click="emit('close')"
|
|
93
|
-
>×</button>
|
|
94
|
-
</header>
|
|
95
|
-
<div class="fe-modal__body">
|
|
96
|
-
<slot />
|
|
97
|
-
</div>
|
|
98
|
-
<footer v-if="$slots.actions && !chromeless" class="fe-modal__actions">
|
|
99
|
-
<slot name="actions" />
|
|
100
|
-
</footer>
|
|
101
|
-
</div>
|
|
102
|
-
</div>
|
|
103
|
-
</transition>
|
|
104
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Modal — tiny headless wrapper. Backdrop + centered card + ESC + autofocus.
|
|
4
|
+
*/
|
|
5
|
+
import { watch, onBeforeUnmount, ref } from 'vue';
|
|
6
|
+
|
|
7
|
+
const props = defineProps<{
|
|
8
|
+
open: boolean;
|
|
9
|
+
title?: string;
|
|
10
|
+
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
11
|
+
closeOnBackdrop?: boolean;
|
|
12
|
+
/** When true, drop the dialog chrome (backdrop tint, header, footer,
|
|
13
|
+
* centered card with border-radius) and render the slot full-bleed.
|
|
14
|
+
* Used by the standalone /files/edit route where the browser tab IS
|
|
15
|
+
* the container — a modal frame on top of it just steals real estate
|
|
16
|
+
* from the editor. ESC + emit('close') still wire through so the
|
|
17
|
+
* parent route can window.close() the tab. */
|
|
18
|
+
chromeless?: boolean;
|
|
19
|
+
/** Explicit theme. When set the modal stamps the appropriate
|
|
20
|
+
* `.fe--theme-{light,dark}` class on its `.fe` backdrop so the CSS
|
|
21
|
+
* variable cascade matches the host shell regardless of OS
|
|
22
|
+
* preference (Modal is a portal-shaped descendant of `<body>`
|
|
23
|
+
* rather than a child of the parent component, so plain DOM
|
|
24
|
+
* inheritance isn't always enough). */
|
|
25
|
+
theme?: 'light' | 'dark' | 'auto';
|
|
26
|
+
}>();
|
|
27
|
+
|
|
28
|
+
const emit = defineEmits<{
|
|
29
|
+
(e: 'close'): void;
|
|
30
|
+
}>();
|
|
31
|
+
|
|
32
|
+
const cardEl = ref<HTMLElement | null>(null);
|
|
33
|
+
|
|
34
|
+
watch(
|
|
35
|
+
() => props.open,
|
|
36
|
+
(v) => {
|
|
37
|
+
if (v) {
|
|
38
|
+
document.addEventListener('keydown', onKey);
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
const focusable = cardEl.value?.querySelector<HTMLElement>(
|
|
41
|
+
'input,select,textarea,button,[tabindex]:not([tabindex="-1"])',
|
|
42
|
+
);
|
|
43
|
+
focusable?.focus();
|
|
44
|
+
}, 30);
|
|
45
|
+
} else {
|
|
46
|
+
document.removeEventListener('keydown', onKey);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
onBeforeUnmount(() => document.removeEventListener('keydown', onKey));
|
|
52
|
+
|
|
53
|
+
function onKey(e: KeyboardEvent) {
|
|
54
|
+
if (e.key === 'Escape') emit('close');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function onBackdrop() {
|
|
58
|
+
if (props.closeOnBackdrop !== false) emit('close');
|
|
59
|
+
}
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<template>
|
|
63
|
+
<transition name="fe-modal">
|
|
64
|
+
<div
|
|
65
|
+
v-if="open"
|
|
66
|
+
class="fe fe-modal__backdrop"
|
|
67
|
+
:class="[
|
|
68
|
+
{ 'fe-modal__backdrop--chromeless': chromeless },
|
|
69
|
+
theme === 'light' ? 'fe--theme-light' : '',
|
|
70
|
+
theme === 'dark' ? 'fe--theme-dark' : '',
|
|
71
|
+
]"
|
|
72
|
+
role="presentation"
|
|
73
|
+
@click="onBackdrop"
|
|
74
|
+
>
|
|
75
|
+
<div
|
|
76
|
+
ref="cardEl"
|
|
77
|
+
class="fe-modal__card"
|
|
78
|
+
:class="[
|
|
79
|
+
`fe-modal__card--${size || 'md'}`,
|
|
80
|
+
chromeless && 'fe-modal__card--chromeless',
|
|
81
|
+
]"
|
|
82
|
+
role="dialog"
|
|
83
|
+
aria-modal="true"
|
|
84
|
+
@click.stop
|
|
85
|
+
>
|
|
86
|
+
<header v-if="title && !chromeless" class="fe-modal__head">
|
|
87
|
+
<h2 class="fe-modal__title">{{ title }}</h2>
|
|
88
|
+
<button
|
|
89
|
+
type="button"
|
|
90
|
+
class="fe-modal__close"
|
|
91
|
+
aria-label="Close"
|
|
92
|
+
@click="emit('close')"
|
|
93
|
+
>×</button>
|
|
94
|
+
</header>
|
|
95
|
+
<div class="fe-modal__body">
|
|
96
|
+
<slot />
|
|
97
|
+
</div>
|
|
98
|
+
<footer v-if="$slots.actions && !chromeless" class="fe-modal__actions">
|
|
99
|
+
<slot name="actions" />
|
|
100
|
+
</footer>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
</transition>
|
|
104
|
+
</template>
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { ref, watch } from 'vue';
|
|
3
|
-
import type { LocaleCode } from '../types/ExplorerConfig';
|
|
4
|
-
import { useLocale } from '../composables/useLocale';
|
|
5
|
-
import Modal from './Modal.vue';
|
|
6
|
-
|
|
7
|
-
const props = defineProps<{
|
|
8
|
-
open: boolean;
|
|
9
|
-
locale: LocaleCode;
|
|
10
|
-
}>();
|
|
11
|
-
|
|
12
|
-
const emit = defineEmits<{
|
|
13
|
-
(e: 'close'): void;
|
|
14
|
-
(e: 'submit', name: string): void;
|
|
15
|
-
}>();
|
|
16
|
-
|
|
17
|
-
const { t } = useLocale(() => props.locale);
|
|
18
|
-
const name = ref('');
|
|
19
|
-
const err = ref<string | null>(null);
|
|
20
|
-
|
|
21
|
-
watch(() => props.open, (v) => {
|
|
22
|
-
if (v) {
|
|
23
|
-
name.value = '';
|
|
24
|
-
err.value = null;
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
function submit() {
|
|
29
|
-
const clean = name.value.trim();
|
|
30
|
-
if (!clean) {
|
|
31
|
-
err.value = t('modal.newfolder.placeholder');
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
if (/[\\/]/.test(clean) || clean === '.' || clean === '..') {
|
|
35
|
-
err.value = 'Geçersiz karakter';
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
emit('submit', clean);
|
|
39
|
-
}
|
|
40
|
-
</script>
|
|
41
|
-
|
|
42
|
-
<template>
|
|
43
|
-
<Modal :open="open" :title="t('modal.newfolder.title')" size="sm" @close="emit('close')">
|
|
44
|
-
<form @submit.prevent="submit">
|
|
45
|
-
<input
|
|
46
|
-
v-model="name"
|
|
47
|
-
type="text"
|
|
48
|
-
class="fe-input"
|
|
49
|
-
:placeholder="t('modal.newfolder.placeholder')"
|
|
50
|
-
autocomplete="off"
|
|
51
|
-
@keydown.enter.prevent="submit"
|
|
52
|
-
/>
|
|
53
|
-
<p v-if="err" class="fe-form__error">{{ err }}</p>
|
|
54
|
-
</form>
|
|
55
|
-
<template #actions>
|
|
56
|
-
<button type="button" class="fe-btn" @click="emit('close')">
|
|
57
|
-
{{ t('modal.newfolder.cancel') }}
|
|
58
|
-
</button>
|
|
59
|
-
<button type="button" class="fe-btn fe-btn--primary" @click="submit">
|
|
60
|
-
{{ t('modal.newfolder.create') }}
|
|
61
|
-
</button>
|
|
62
|
-
</template>
|
|
63
|
-
</Modal>
|
|
64
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, watch } from 'vue';
|
|
3
|
+
import type { LocaleCode } from '../types/ExplorerConfig';
|
|
4
|
+
import { useLocale } from '../composables/useLocale';
|
|
5
|
+
import Modal from './Modal.vue';
|
|
6
|
+
|
|
7
|
+
const props = defineProps<{
|
|
8
|
+
open: boolean;
|
|
9
|
+
locale: LocaleCode;
|
|
10
|
+
}>();
|
|
11
|
+
|
|
12
|
+
const emit = defineEmits<{
|
|
13
|
+
(e: 'close'): void;
|
|
14
|
+
(e: 'submit', name: string): void;
|
|
15
|
+
}>();
|
|
16
|
+
|
|
17
|
+
const { t } = useLocale(() => props.locale);
|
|
18
|
+
const name = ref('');
|
|
19
|
+
const err = ref<string | null>(null);
|
|
20
|
+
|
|
21
|
+
watch(() => props.open, (v) => {
|
|
22
|
+
if (v) {
|
|
23
|
+
name.value = '';
|
|
24
|
+
err.value = null;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
function submit() {
|
|
29
|
+
const clean = name.value.trim();
|
|
30
|
+
if (!clean) {
|
|
31
|
+
err.value = t('modal.newfolder.placeholder');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (/[\\/]/.test(clean) || clean === '.' || clean === '..') {
|
|
35
|
+
err.value = 'Geçersiz karakter';
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
emit('submit', clean);
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<template>
|
|
43
|
+
<Modal :open="open" :title="t('modal.newfolder.title')" size="sm" @close="emit('close')">
|
|
44
|
+
<form @submit.prevent="submit">
|
|
45
|
+
<input
|
|
46
|
+
v-model="name"
|
|
47
|
+
type="text"
|
|
48
|
+
class="fe-input"
|
|
49
|
+
:placeholder="t('modal.newfolder.placeholder')"
|
|
50
|
+
autocomplete="off"
|
|
51
|
+
@keydown.enter.prevent="submit"
|
|
52
|
+
/>
|
|
53
|
+
<p v-if="err" class="fe-form__error">{{ err }}</p>
|
|
54
|
+
</form>
|
|
55
|
+
<template #actions>
|
|
56
|
+
<button type="button" class="fe-btn" @click="emit('close')">
|
|
57
|
+
{{ t('modal.newfolder.cancel') }}
|
|
58
|
+
</button>
|
|
59
|
+
<button type="button" class="fe-btn fe-btn--primary" @click="submit">
|
|
60
|
+
{{ t('modal.newfolder.create') }}
|
|
61
|
+
</button>
|
|
62
|
+
</template>
|
|
63
|
+
</Modal>
|
|
64
|
+
</template>
|